基于STM32的电子秒表仿真设计及程序详解

基于STM32的简易电子秒表仿真设计(仿真+程序+设计报告+讲解)

  • 视频演示
  • 1.主要功能
  • 2.仿真
  • 3. 程序
  • 4. 设计报告
  • 5.资料清单&下载链接
  • 仿真图proteus 8.9

    程序编译器:keil 5

    编程语言:C语言

    设计编号:C0078

    视频演示

    基于STM32的简易电子秒表proteus仿真设计

    1.主要功能

    结合实际情况,基于STM32F103单片机设计一个电子秒表。该设计应满足的功能要求为:

    1、以STM32为最小系统电路进行连接,用四位数码管显示计时时间。

    2、三个按键作为开始、清零、暂停来控制秒表的计时。

    3、计时精确度为0.1S,最大可以显示999.9s

    主要硬件设备:STM32F103单片机、四位数码管。

    以下为本设计资料展示:

    2.仿真

    整体设计方案

    该系统为电子秒表设计系统,其主要的硬件设计:以stm32为最小系统电路进行连接,用数码管显示秒表计时时间。

    测试如下所示:

    开始仿真后显示000.0,等待开始按键按下后开始计时,0.1秒增加一次计时。

    img

    按下暂停按键后暂停计时,显示当前计时的时间。如下图所示:

    img

    3. 程序

    img

    主函数:

    #include "stm32f10x.h"
    #include "main.h"
    
    //定义数码管的引脚
    #define   SEG_A   PC(12)
    #define   SEG_B   PC(11)
    #define   SEG_C   PC(10)
    #define   SEG_D   PC(9)
    #define   SEG_E   PC(8)
    #define   SEG_F   PC(7)
    #define   SEG_G   PC(6)
    #define   SEG_DP   PC(5)
    
    #define   SEG1   PC(4)
    #define   SEG2   PC(3)
    #define   SEG3   PC(2)
    #define   SEG4   PC(1)
    //定义数按键的引脚
    #define   K1   PBIN(15)
    #define   K2   PBIN(14)
    #define   K3   PBIN(13)
    //共阳数码管段码表0-F
    const char  CAseg_table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
    //共阴数码管段码表0-F
    const char  CCseg_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    
    u8 Time_count=0;//计时时间
    
    //初始化引脚
    void GPIO_Config(void)
    {
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    	GPIO_InitTypeDef GPIO_InitStructure;
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;    
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
      GPIO_Init(GPIOC, &GPIO_InitStructure); 
    	GPIO_SetBits(GPIOC,GPIO_Pin_All);
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;    
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
      GPIO_Init(GPIOB, &GPIO_InitStructure); 
    	GPIO_SetBits(GPIOB,GPIO_Pin_All);
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13;    
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
      GPIO_Init(GPIOB, &GPIO_InitStructure); 
    
    }
    
    //把数值输出到具体的单片机引脚
    void Drv_SEG(u8 num)
    {
    	SEG_A=GETVALBIT(num,0);
    	SEG_B=GETVALBIT(num,1);
    	SEG_C=GETVALBIT(num,2);
    	SEG_D=GETVALBIT(num,3);
    	SEG_E=GETVALBIT(num,4);
    	SEG_F=GETVALBIT(num,5);
    	SEG_G=GETVALBIT(num,6);
    	SEG_DP=GETVALBIT(num,7);
    }
    //驱动数码管的函数
    //mode =0表示共阳,mode=1表示共阴,可以通过这个修改
    //m是要显示的数字,比如1.0就是m=10,放大10倍
    void Show_num(u16 m)
    {
    	u8 num=0,n=0;
    	static u8 temp_flag=0;
    	//数码管消隐
    	SEG1=0;SEG2=0;SEG3=0;SEG4=0;
    	switch(temp_flag)
    	{
    		case 0://左侧第1位数码管		
    			n=m/1000;//取数据
    			num=CAseg_table[n];//查询数码管的断码表
    			Drv_SEG(num);
    			SEG1=1;//打开数码管显示
    			temp_flag++;
    		break;
    		case 1://左侧第2位数码管
    			
    			n=m%1000/100;//取数据
    			num=CAseg_table[n];//查询数码管的断码表
    			Drv_SEG(num);
    			SEG2=1;//打开数码管显示
    			temp_flag++;
    		break;
    		case 2://左侧第3位数码管
    			
    			n=m%100/10;//取数据
    			num=CAseg_table[n]&0x7f;//查询数码管的断码表
    			Drv_SEG(num);
    			SEG3=1;//打开数码管显示
    			temp_flag++;
    		break;
    		case 3://左侧第4位数码管
    			
    		n=m%10;//取数据
    		num=CAseg_table[n];//查询数码管的断码表
    		Drv_SEG(num);
    		SEG4=1;//打开数码管显示
    		temp_flag=0;
    		break;
    	}
    	
    	Delay_ms(10);//延时
    }
    
    //获取独立按键数据
    u8 Get_key_num()
    {
    	u8 temp_key=0;
    	static u8 flag=0;
    	if((flag==0)&&((K1==0)||(K2==0)||(K3==0)))
    	{
    		flag=1;//按键只获取一次按键数值
    		SysTick_Delay_Ms(10);//消除抖动
    		//如果有对应的按键按下就返回对应按键数值
    		if(K1==0)
    		{temp_key=1;}
    		else if(K2==0)
    		{temp_key=2;}
    		else if(K3==0)
    		{temp_key=3;}
    
    	}
    	else if((K1==1)&&(K2==1)&&(K3==1))
    	{
    		flag=0;//所有按键都弹起就清除标志
    	}
    	return temp_key;
    }
    
    //定时器初始化
    void  TimInit(void)
    {
      NVIC_InitTypeDef NVIC_InitStructure;
      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
      
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
      
      TIM_DeInit(TIM2);
      NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    	
      TIM_TimeBaseStructure.TIM_Period = 999; // 10mS
      TIM_TimeBaseStructure.TIM_Prescaler = (80-1); // 10uS,这里配合仿真是8M,所以是80,如果是72M那么就是720,仿真没有备倍频
      TIM_TimeBaseStructure.TIM_ClockDivision = 0;
      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     
      TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
      TIM_PrescalerConfig(TIM2, 80-1, TIM_PSCReloadMode_Immediate); // 10uS,这里配合仿真是8M,所以是80,如果是72M那么就是720,仿真没有备倍频
      TIM_ClearFlag(TIM2, TIM_FLAG_Update);  
      TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);         
      TIM_Cmd(TIM2, ENABLE);
    
    }
    
    //定时器服务函数
    void  TIM2_IRQHandler(void)   
    {
      if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
      { 
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 
        if(++Time_count>250)Time_count=250;//时间计时
      } 
    }
    
    
    int main(void)
    {
      u8 key_num=0;//按键数值
    	u16 dis_num=0;
    	u8 mode=0;
    	GPIO_Config();		//初始化引脚
    	TimInit();		//初始化定时器
    	while(1)
    	{
    		key_num=Get_key_num();//读取按键
    		switch(key_num)
    		{
    			case 1://开始按键
    				TIM_Cmd(TIM2, ENABLE);
    				mode=1;//开始
    			break;
    			case 2://暂停按键
    				TIM_Cmd(TIM2, DISABLE);
    				mode=2;//暂停
    			break;
    			case 3://清除按键
    				TIM_Cmd(TIM2, DISABLE);
    				Time_count=0;
    				dis_num=0;
    			  mode=0;//清除显示
    			break;
    		}
    		if(mode==1)//开始
    		{
    			if(Time_count>=10)//每0.1s增加1
    			{
    				Time_count=0;
    				if(++dis_num>9999)dis_num=9999;//最大999.9s
    			}
    		}
    		Show_num(dis_num);//刷新数码管显示
    		
    	}
    }
    
    

    4. 设计报告

    img

    报告部分内容

    二、主控制器选择

    2.1 stm32f103芯片的概述

    STM32单片机有很多个系列,其中包括基本型、USB基本型、增强型以及互联型几大系列,这写系列的STM32单片机都是具有性能高、功耗低、成本低等特点。其内部结构图如图 2.2所示:

    img

    ​ 图 2.2 STM32内部结构图

    本课题采用的是STM32F103C8T6单片机芯片,这是是一款ARM M3内核的增强型微控制器,这款内核的工作频率是能够达到72MHz的,它拥有着128K字节的闪存和极其丰富的外设,如GPIO口,串口,定时器,中断,数模转换,实时时钟,看门狗,SPI,IIC,CAN总线等部分组成。STM32F103系列单片机的性能在同一个类别的产品中是最高的,它能够在-40°C -85°C温度下正常地进行工作,工作的电压范围为2V-3.6V,具有低功耗的节能工作模式,闪存存储器的容量为64K字节。

    5.资料清单&下载链接

    img

    百度网盘分享下载链接:
    https://docs.qq.com/doc/DS21hQUpNd3JabkZt

    物联沃分享整理
    物联沃-IOTWORD物联网 » 基于STM32的电子秒表仿真设计及程序详解

    发表评论