找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16082|回复: 14
收起左侧

51单片机的时钟与秒表程序带仿真 3个按键 定时器实现数码管显示

  [复制链接]
ID:207636 发表于 2017-6-4 12:48 | 显示全部楼层 |阅读模式
一个51单片机的时钟_秒表小制作,使用数码管来作为时钟显示,可以作为秒表使用,时间可调。带模式选择 ,开始(暂停) ,切换/清零3个按键

单片机时钟和秒表仿真原理图如下(proteus仿真工程文件可到本帖附件中下载):
0.png

0.png 0.png

单片机源程序如下:
  1. #include<reg52.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. uchar code Tab0[]=                //定义数码管数组,没有小数点
  5. {
  6.         0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
  7. };
  8. uchar code Tab1[]=                //定义数码管数组,有小数点
  9. {        
  10.         0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef
  11. };

  12. sbit K1=P3^2;                        //模式选择键,本程序三种模式,分别是时间显示、秒表、时间设置
  13. sbit K2=P3^3;                        //设置时间时加一/开始(暂停)秒表按键
  14. sbit K3=P3^4;                        //切换设置位/清零秒表按键

  15. void Delay(uchar x);                //延时函数
  16. void Display0();                 //时间显示函数
  17. void Display1();                 //秒表显示函数
  18. void Display2();                //时间设置显示函数
  19. void Init();                         //中断初始化函数
  20. void Mode_K1();                        //模式切换函数
  21. void KEY_MiaoBiao();        //检测秒表操作按键
  22. void KEY_Time_Set();         //检测时间设置按键


  23. uchar Hours=23,Minutes=56,seconds=55;                //分别定义三个变量表示时、分、秒
  24. uchar Time0_bit=0;                        //用于定时器0的溢出标志
  25. bit Set_Time=0;                                //设置时 闪烁时长的标志位
  26. bit Set0=0;                                        //设置时间标志,确定是设置‘分’还设置‘时’
  27. uchar K1_bit=0;                                  //用于模式切换的标志
  28. uchar Miao_Biao0,Miao_Biao1,Miao_Biao2,Miao_Biao3,Miao_Biao4;                //用于秒表的变量

  29. void main()
  30. {
  31.         Init();                                                                                //中断初始化
  32.         while(1)                                                                        //死循环
  33.                 {
  34.                         Mode_K1();                                                        //模式扫描
  35.                         switch(K1_bit)                                                 //模式选择
  36.                                 {
  37.                                         case 0:
  38.                                                 {
  39.                                                         Display0();                        //显示时间                                                               
  40.                                                         break;
  41.                                                 }
  42.                                         case 1:
  43.                                                 {
  44.                                                         Display1();                         //显示秒表
  45.                                                         KEY_MiaoBiao();                //扫描秒表操作
  46.                                                         break;
  47.                                                 }
  48.                                         case 2:
  49.                                                         {
  50.                                                                 Display2();                //设置时间时的显示程序,可闪烁定位
  51.                                                                 KEY_Time_Set();        //扫描按键
  52.                                                                 break;
  53.                                                         }
  54.                                 }
  55.                 }
  56. }

  57. void KEY_Time_Set()                                                                   //设置时间时的按键扫描函数
  58. {
  59.         if(K1_bit==2)                                                                  //判断是否为时间设置模式
  60.                 {
  61.                         if(K2==0)                                                         //K2有按下(下同)
  62.                                 {
  63.                                         Delay(10);                                           //延时消抖(下同)
  64.                                         if(K2==0)                                         //再次检测是否为误按
  65.                                                 {
  66.                                                         if(Set0==0)                        //检测是设置‘时’还是分,Set0为0时设置‘分’,Set0为1时设置‘时’
  67.                                                                 {
  68.                                                                         Minutes++;         //‘分’加1
  69.                                                                         if(Minutes==60)        //当'分'加到60时,重新赋值0
  70.                                                                                 Minutes=0;
  71.                                                                 }
  72.                                                         else
  73.                                                                 {
  74.                                                                         Hours++;          //‘时’加1
  75.                                                                         if(Hours==24)        //当'时'加到24时,重新赋值0
  76.                                                                                 Hours=0;
  77.                                                                 }
  78.                                                         while(!K2);                        //按键松开检测,消除松开按键时的抖动干扰
  79.                                                 }
  80.                                 }
  81.                         if(K3==0)
  82.                                 {
  83.                                         Delay(10);
  84.                                         if(K3==0)
  85.                                                 {
  86.                                                         Set0=~Set0;                        //K3每按一次Set0取反,以确定是设置‘时’还是设置‘分’,Set0为0时设置‘分’,Set0为1时设置‘时’
  87.                                                         while(!K3);
  88.                                                 }        
  89.                                 }
  90.                 }
  91. }

  92. void KEY_MiaoBiao()                                                                //检测秒表按键操作
  93. {
  94.         if(K1_bit==1)                                                                //判断是否为秒表模式
  95.                 {
  96.                         if(K2==0)
  97.                                 {
  98.                                         Delay(10);
  99.                                         if(K2==0)
  100.                                                 {
  101.                                                         TR1=~TR1;                        //K2每按一次TR1取反,暂停或开始定时器1,达到暂停或开始秒表的目的
  102.                                                         while(!K2);
  103.                                                 }
  104.                                 }
  105.                         if(K3==0)
  106.                                 {
  107.                                         Delay(10);
  108.                                         if(K3==0)                                         //当K3按下时秒表所有数据清零,并停止定时器1
  109.                                                 {
  110.                                                         TR1=0;                                 //停止定时器1
  111.                                                         Miao_Biao0=0;                 //清零数据
  112.                                                         Miao_Biao1=0;
  113.                                                         Miao_Biao2=0;
  114.                                                         Miao_Biao3=0;
  115.                                                         Miao_Biao4=0;
  116.                                                         while(!K3);
  117.                                                 }
  118.                                 }
  119.                 }
  120. }

  121. void Mode_K1()                                                                        //模式选择键,本程序三种模式,分别是时间显示、秒表、时间设置
  122. {
  123.         if(K1==0)
  124.                 {
  125.                         Delay(10);
  126.                         if(K1==0)
  127.                                 {
  128.                                         K1_bit++;
  129.                                         if(K1_bit==3)
  130.                                                 {
  131.                                                         K1_bit=0;
  132.                                                 }
  133.                                         while(!K1);
  134. /***********************************************************************
  135. *************当K1_bit为0时显示时钟,为1时进入秒表,*********************
  136. *******************为2时进入时间设置模式********************************
  137. ***********************************************************************/
  138.                                 }
  139.                 }
  140. }
  141.         

  142. void Time1() interrupt 3                          //定时器1函数
  143. {
  144.         TH1=(65536-50000)/256;                        //重装初值
  145.         TL1=(65536-50000)%256;

  146.         Miao_Biao0++;
  147.         if(Miao_Biao0==2)                                //以下为秒表数据处理
  148.                 {
  149.                         Miao_Biao0=0;
  150.                         Miao_Biao1++;                         //Miao_Biao1每加1次为100ms,
  151.                         if(Miao_Biao1==10)
  152.                                 {
  153.                                         Miao_Biao1=0;
  154.                                         Miao_Biao2++;
  155.                                         if(Miao_Biao2==60)
  156.                                                 {
  157.                                                         Miao_Biao2=0;
  158.                                                         Miao_Biao3++;
  159.                                                         if(Miao_Biao3==60)
  160.                                                                 {
  161.                                                                         Miao_Biao3=0;
  162.                                                                         Miao_Biao4++;
  163.                                                                         if(Miao_Biao4==10)
  164.                                                                                 Miao_Biao4=0;
  165.                                                                 }
  166.                                                 }
  167.                                 }
  168.                 }
  169. }


  170. void Time0() interrupt 1                                         //定时器0函数
  171. {
  172.         TH0=(65536-50000)/256;                                           //重装初值
  173.         TL0=(65536-50000)%256;
  174.         Time0_bit++;
  175.         if((Time0_bit%10)==0)                                        //每溢出10次Time0_bit取反一次
  176.                 Set_Time=~Set_Time;                                          //0.5秒闪烁一次

  177.         if(Time0_bit==20)                                                //以下为时间数据处理
  178.                 {
  179.                         Time0_bit=0;
  180.                         seconds++;
  181.                         if(seconds==60)
  182.                                 {
  183.                                         seconds=0;
  184.                                         Minutes++;
  185.                                         if(Minutes==60)
  186.                                                 {
  187.                                                         Minutes=0;
  188.                                                         Hours++;
  189.                                                         if(Hours==24)
  190.                                                                 {
  191.                                                                         Hours=0;
  192.                                                                 }
  193.                                                 }
  194.                                 }

  195.                 }
  196. }

  197. void Init()                                                         //中断初始化函数
  198. {
  199.         EA=1;                                                         //开总中断
  200.         TMOD=0X11;                                                  //定时器工作方式选择,定时器0和定时器1都选择第1种工作方式
  201.         TH0=(65536-50000)/256;                        //定时器0装初值,定时50ms
  202.         TL0=(65536-50000)%256;
  203.         ET0=1;                                                        //开定时器0开关
  204.         TR0=1;                                                           //开定时器0小开关

  205.         TH1=(65536-50000)/256;                        //定时器1装初值,定时50ms
  206.         TL1=(65536-50000)%256;
  207.         ET1=1;                                                          //开定时器1开关
  208.         TR1=0;                                                        //关定时器1小开关
  209. }

  210. void Display2()                                                        //时间设置时的显示函数        
  211. {
  212.         if(Set0==0)                                                        //判断是否为设置‘时’还是‘分’
  213.                 {
  214.                         P0=Tab0[seconds%10];                //显示秒的个位
  215.                         P1=0xdf;                                        //段选
  216.                         Delay(10);                                        //延时
  217.                         P0=0X00;                                        //消隐
  218.                
  219.                         P0=Tab0[seconds/10];                //显示秒的十位
  220.                         P1=0xef;                                        //段选
  221.                         Delay(10);                                        //延时
  222.                         P0=0X00;                                        //消隐
  223.                         
  224.                         if(Set_Time)                                //这个if语句实现分钟以0.5秒的频率闪烁
  225.                                 {
  226.                                         P0=Tab1[Minutes%10];                //显示分的个位,需要加上小数点做分隔符
  227.                                         P1=0xf7;                                        //段选
  228.                                         Delay(10);                                        //延时
  229.                                         P0=0X00;                                        //消隐

  230.                                         P0=Tab0[Minutes/10];                //显示分的十位
  231.                                         P1=0xfb;                                        //段选
  232.                                         Delay(10);                                        //延时
  233.                                         P0=0X00;                                        //消隐
  234.                                 }
  235.                         else
  236.                                 {
  237.                                         P0=0x00;                //显示分的个位,需要加上小数点做分隔符
  238.                                         P1=0xf7;                                        //段选
  239.                                         Delay(10);                                        //延时
  240.                                         P0=0X00;                                        //消隐
  241.                
  242.                                         P0=0x00;                //显示分的十位
  243.                                         P1=0xfb;                                        //段选
  244.                                         Delay(10);                                        //延时
  245.                                         P0=0X00;                                        //消隐
  246.                                 }
  247.                         
  248.                         P0=Tab1[Hours%10];                        //显示时的个位,需要加上小数点做分隔符
  249.                         P1=0xfd;                                        //段选
  250.                         Delay(10);                                        //延时
  251.                         P0=0X00;                                        //消隐
  252.                
  253.                         P0=Tab0[Hours/10];                        //显示时的十位
  254.                         P1=0xfe;                                        //段选
  255.                         Delay(10);                                        //延时
  256.                         P0=0X00;                                        //消隐
  257.                 }


  258.         else                        //‘时’钟闪烁
  259.                 {
  260.                         P0=Tab0[seconds%10];                //显示秒的个位
  261.                         P1=0xdf;                                        //段选
  262.                         Delay(10);                                        //延时
  263.                         P0=0X00;                                        //消隐
  264.                
  265.                         P0=Tab0[seconds/10];                //显示秒的十位
  266.                         P1=0xef;                                        //段选
  267.                         Delay(10);                                        //延时
  268.                         P0=0X00;                                        //消隐
  269.                         
  270.                         P0=Tab1[Minutes%10];                //显示分的个位,需要加上小数点做分隔符
  271.                         P1=0xf7;                                        //段选
  272.                         Delay(10);                                        //延时
  273.                         P0=0X00;                                        //消隐

  274.                         P0=Tab0[Minutes/10];                //显示分的十位
  275.                         P1=0xfb;                                        //段选
  276.                         Delay(10);                                        //延时
  277.                         P0=0X00;                                        //消隐
  278.                         
  279.                         if(Set_Time)                                //这个if语句实现‘时’钟以0.5秒的频率闪烁
  280.                                 {
  281.                                         P0=Tab1[Hours%10];                        //显示时的个位,需要加上小数点做分隔符
  282.                                         P1=0xfd;                                        //段选
  283.                                         Delay(10);                                        //延时
  284.                                         P0=0X00;                                        //消隐
  285.                                 
  286.                                         P0=Tab0[Hours/10];                        //显示时的十位
  287.                                         P1=0xfe;                                        //段选
  288.                                         Delay(10);                                        //延时
  289.                                         P0=0X00;                                        //消隐
  290.                                 }
  291.                         else
  292.                                 {
  293.                                         P0=0x00;                        //显示时的个位,需要加上小数点做分隔符
  294.                                         P1=0xFF;                                        //段选
  295.                                         Delay(10);                                        //延时
  296.                                         P0=0X00;                                        //消隐
  297.                                 
  298.                                         P0=0X00;                        //显示时的十位
  299.                                         P1=0xFF;                                        //段选
  300.                                         Delay(10);                                        //延时
  301.                                         P0=0X00;                                        //消隐                                
  302.                                 }               
  303.                 }
  304. }

  305. void Display1()                        //显示秒表
  306. {
  307.         P0=Tab0[Miao_Biao1%10];                //显示1/10秒的个位
  308.         P1=0xdf;                                        //段选
  309.         Delay(10);                                        //延时
  310.         P0=0X00;                                        //消隐

  311.         P0=Tab1[Miao_Biao2%10];                //显示秒的个位,需要加上小数点做分隔符
  312.         P1=0xef;                                        //段选
  313.         Delay(10);                                        //延时
  314.         P0=0X00;                                        //消隐

  315.         P0=Tab0[Miao_Biao2/10];                //显示秒的十位
  316.         P1=0xf7;                                        //段选
  317.         Delay(10);                                        //延时
  318.         P0=0X00;                                        //消隐

  319.         P0=Tab1[Miao_Biao3%10];                //显示分的个位,需要加上小数点做分隔符
  320.         P1=0xfb;                                        //段选
  321.         Delay(10);                                        //延时
  322.         P0=0X00;                                        //消隐

  323.         P0=Tab0[Miao_Biao3/10];                //显示分的十位
  324.         P1=0xfd;                                        //段选
  325.         Delay(10);                                        //延时
  326.         P0=0X00;                                        //消隐

  327.         P0=Tab1[Miao_Biao4%10];                //显示时的个位,需要加上小数点做分隔符
  328.         P1=0xfe;                                        //段选
  329.         Delay(10);                                        //延时
  330.         P0=0X00;                                        //消隐
  331. }
  332. ……………………

  333. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
51单片机-时钟.zip (103.24 KB, 下载次数: 204)

评分

参与人数 1黑币 +5 收起 理由
wanli2018 + 5 赞一个!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2017-6-4 17:00 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:52922 发表于 2017-10-26 09:58 | 显示全部楼层
想学习一下,钱不够。
回复

使用道具 举报

ID:52922 发表于 2017-10-26 09:59 | 显示全部楼层
学习一下。
回复

使用道具 举报

ID:350899 发表于 2018-6-13 10:28 | 显示全部楼层
感谢楼主楼主好人
回复

使用道具 举报

ID:361073 发表于 2018-6-28 15:14 | 显示全部楼层
想看后面的
回复

使用道具 举报

ID:450150 发表于 2018-12-20 08:44 | 显示全部楼层
学习一下,很有启发
回复

使用道具 举报

ID:445043 发表于 2018-12-20 20:20 | 显示全部楼层
学习学习~~
回复

使用道具 举报

ID:450056 发表于 2018-12-20 23:56 来自手机 | 显示全部楼层
楼主厉害,给力
回复

使用道具 举报

ID:632561 发表于 2019-10-30 11:55 | 显示全部楼层
想看后面
回复

使用道具 举报

ID:5300 发表于 2019-12-4 21:51 | 显示全部楼层
仿真文件哪个可以打开
回复

使用道具 举报

ID:535853 发表于 2019-12-8 10:06 | 显示全部楼层
哪个是proteus仿真文件啊
回复

使用道具 举报

ID:685407 发表于 2020-2-22 22:11 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:777601 发表于 2020-6-14 21:41 | 显示全部楼层
为什么我的跑不出来呢  报错位置在key.c里的if(k1==0)
回复

使用道具 举报

ID:495613 发表于 2020-6-15 08:38 | 显示全部楼层
好方法
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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