找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3803|回复: 0
收起左侧

单片机按键控制数码管秒表视频+源程序

[复制链接]
ID:259017 发表于 2019-1-20 23:22 | 显示全部楼层 |阅读模式
按键控制数码管秒表
从上到下四个按键分别为 启动/继续运行按键 暂停按键  复位清零按键 熄屏睡眠按键

实际效果见视频:
其余内容见附件:
单片机源码:
  1. /* 包含头文件 -------------------------------------------------------------*/
  2. #include "STC8.h"
  3. #include "intrins.h"
  4. #include "bsp_key.h"
  5. #include "bsp_led.h"
  6. #include "bsp_smg.h"
  7. /*常量声明-----------------------------------------------------------------*/
  8. unsigned char KeySta[4]={//按键当前状态
  9.         1,1,1,1
  10. };
  11. /*变量声明 ----------------------------------------------------------------*/
  12. unsigned char sec=0;//秒时间初值
  13. unsigned char flag1s=0;//秒表运行刷新标志
  14. bit RunningFlag=0;//秒表运行标志
  15. bit ResetFlag=1;//秒表复位标志(注:锁死定时器,避免多走,为启动做准备)
  16. bit PauseFlag=0;//秒表暂停标志
  17. /*函数声明 --------------------------------------------------------------  */
  18. void ConfigTimer0(unsigned int ms);                //定时器0配置函数声明
  19. void KeyScan(void);                                //按键扫描函数声明
  20. void KeyDriver(void);                        //按键驱动函数
  21. void StopwatchAction(void);//Stopwatch启动函数声明
  22. void StopwatchReset(void);//Stopwatch复位函数声明
  23. void StopwatchPause(void);//Stopwatch暂停函数声明

  24. void main(void)
  25. {
  26.         
  27.         EA=1;//开总中断
  28.         
  29.         ConfigTimer0(2);//配置T0定时2ms
  30.         while(1)
  31.         {
  32.           KeyDriver();
  33.                                 if(flag1s&&RunningFlag)//运行状态
  34.                 {
  35.                         flag1s=0;
  36.                         if(!PauseFlag)//如果暂停键没有按下(暂停状态)
  37.                         {
  38.                         sec++;
  39.                         }
  40.                         SMGBuff[0]=SMGChar[sec%10];
  41.                         SMGBuff[1]=SMGChar[sec/10%10];
  42.                         if(sec==100)//因为我总共就只有两位数码管,所以满100清0
  43.                         {
  44.                                 sec=0;
  45.                         }
  46.                         }        
  47.                 else if(ResetFlag)//复位状态
  48.                 {
  49.                         SMGBuff[0]=SMGChar[sec%10];
  50.                         SMGBuff[1]=SMGChar[sec/10%10];
  51.                 }
  52.         }
  53. }
  54. /*
  55. 函数名称:Stopwatch启动函数
  56. 功    能:/
  57. */
  58. void StopwatchAction(void)
  59. {
  60.         
  61.         RunningFlag=1;//运行标志置1
  62.         ResetFlag=0;//复位标志置0
  63.         PauseFlag=0;//暂停标志置0
  64. }
  65. /*
  66. 函数名称:Stopwatch复位函数
  67. 功    能:/
  68. */
  69. void StopwatchReset(void)
  70. {
  71.         ResetFlag=1;//复位标志置1
  72.         RunningFlag=0;//运行标志置0
  73.         PauseFlag=0;//暂停标志置0
  74.         sec=0;//清零计数值
  75. }
  76. /*
  77. 函数名称:Stopwatch暂停函数
  78. 功    能:/
  79. */
  80. void StopwatchPause(void)
  81. {
  82.         PauseFlag=1;//暂停标志置0
  83.         ResetFlag=0;//复位标志置1
  84.         RunningFlag=0;//运行标志置0
  85. }
  86. /*
  87. 函数名称:按键驱动程序
  88. 功    能:检测按键动作,调度相应动作函数
  89. */
  90. void KeyDriver(void)
  91. {
  92.         unsigned char i;
  93.         static unsigned char backup[4]={
  94.                 1,1,1,1
  95.         };
  96.         for(i=0;i<4;i++)//循环检测四个按键
  97.         {
  98.                 if(backup[i]!=KeySta[i])//检测按键动作
  99.                 {
  100.                         if(backup[i]!=0)//按键按下时执行动作
  101.                         {
  102.                                 if(i==0)
  103.                                         StopwatchAction();
  104.                                 else if(i==1)
  105.                                         StopwatchPause();
  106.                                 else if(i==2)
  107.                                         StopwatchReset();
  108.                                 else if(i==3)
  109.                                         _nop_();
  110.                                        
  111.                         }
  112.                         backup[i]=KeySta[i];//刷新前一次备份的值
  113.                 }
  114.         }
  115. }
  116. /*
  117. 函数名称:按键扫描程序
  118. 功    能:按键扫描函数,须在定时器中断中调用
  119. */
  120. void KeyScan(void)
  121. {
  122.         unsigned char i;
  123.         static unsigned char keybuf[4]={
  124.                 0xFF,0xFF,0xFF,0xFF
  125.         };
  126.         //按键值移入缓冲区
  127.         keybuf[0]=(keybuf[0]<<1)|KEY2;
  128.         keybuf[1]=(keybuf[1]<<1)|KEY3;
  129.         keybuf[2]=(keybuf[2]<<1)|KEY4;
  130.         keybuf[3]=(keybuf[3]<<1)|KEY5;
  131.         
  132.         for(i=0;i<4;i++)
  133.         {
  134.                 if(keybuf[i]==0x00)
  135.                 {//连续8次扫描值为0,即16ms内都是按下状态时,可认为按键已稳定的按下
  136.                         KeySta[i]=0;
  137.                 }
  138.                 else if(keybuf[i]==0xFF)
  139.                 {//连续8次扫描值为1,即16ms内都是弹起状态,可认为按键已稳定的弹起
  140.                         KeySta[i]=1;
  141.                 }
  142.         }
  143.         
  144. }
  145. /*
  146. 函数名称:定时器0初始化程序
  147. 功    能:定时器0方式1 16位自动重载 12分频
  148. */
  149. void ConfigTimer0(unsigned int ms)                //@24.000MHz
  150. {
  151.         unsigned char T0RH=0;
  152.         unsigned char T0RL=0;
  153.         unsigned long tmp;
  154.         
  155.         tmp=24000000/12;//定时器计数频率
  156.         tmp=(tmp*ms)/1000;//计算所需的计数值
  157.         tmp=65536-tmp;//计算定时器重载值
  158.         T0RH=(unsigned char)(tmp>>8);//定时器重载值拆分为高低字节
  159.         T0RL=(unsigned char)tmp;
  160.         
  161.         TMOD &=0xF0;//清零T0的控制位
  162.         TMOD |=0x00;//配置T0为模式0
  163.         TH0=T0RH;//加载T0重载值
  164.         TL0=T0RL;
  165.         ET0=1;//使能T0中断
  166.         TR0=1;//启动T0
  167. }
  168. /*
  169. 函数名称:定时器0中断服务程序
  170. 功    能:2ms进入中断一次
  171. */
  172. void TM0_Rountine(void) interrupt 1
  173. {
  174.         static unsigned char i=0;//动态扫描的索引
  175.         static unsigned int cnt=0;//记录T0中断次数
  176.         KeyScan();
  177.         if(ResetFlag)//如果暂停键按下,计数清零
  178.                 cnt=0;
  179.         else if(!PauseFlag)//如果暂停键没有按下
  180.                 cnt++;
  181.         if(cnt>=500)
  182.         {
  183.                 cnt=0;
  184.                 flag1s=1;
  185.         }
  186.         switch(i)
  187.         {
  188.                 case 0:SMG1_EN=1;SMG2_EN=0;i++;SMG=SMGBuff[0];break;
  189.                 case 1:SMG1_EN=0;SMG2_EN=1;i=0;SMG=SMGBuff[1];break;
  190.                 default:break;
  191.         }
  192. }
复制代码

全部资料51hei下载地址:
Template.zip (66.23 KB, 下载次数: 24)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表