單片機論壇

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11630|回復: 14
打印 上一主題 下一主題
收起左側

51單片機的時鐘與秒表程序帶仿真 3個按鍵 定時器實現數碼管顯示

  [復制鏈接]
跳轉到指定樓層
樓主
一個51單片機的時鐘_秒表小制作,使用數碼管來作為時鐘顯示,可以作為秒表使用,時間可調。帶模式選擇 ,開始(暫停) ,切換/清零3個按鍵

單片機時鐘和秒表仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載):




單片機源程序如下:
  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, 下載次數: 173)


評分

參與人數 1黑幣 +5 收起 理由
wanli2018 + 5 贊一個!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 轉播轉播 分享分享 分享淘帖 頂3 踩
回復

使用道具 舉報

沙發
admin 發表于 2017-6-4 17:00 | 只看該作者
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

板凳
cb474265 發表于 2017-10-26 09:58 | 只看該作者
想學習一下,錢不夠。
回復

使用道具 舉報

地板
cb474265 發表于 2017-10-26 09:59 | 只看該作者
學習一下。
回復

使用道具 舉報

5#
zhishichanquan 發表于 2018-6-13 10:28 | 只看該作者
感謝樓主樓主好人
回復

使用道具 舉報

6#
舊時光--jing 發表于 2018-6-28 15:14 | 只看該作者
想看后面的
回復

使用道具 舉報

7#
林子家的貓 發表于 2018-12-20 08:44 | 只看該作者
學習一下,很有啟發
回復

使用道具 舉報

8#
zhoumo1998 發表于 2018-12-20 20:20 | 只看該作者
學習學習~~
回復

使用道具 舉報

9#
公寓3 發表于 2018-12-20 23:56 來自手機 | 只看該作者
樓主厲害,給力
回復

使用道具 舉報

10#
xushil 發表于 2019-10-30 11:55 | 只看該作者
想看后面
回復

使用道具 舉報

11#
qingfeng1215 發表于 2019-12-4 21:51 | 只看該作者
仿真文件哪個可以打開
回復

使用道具 舉報

12#
一日不學習 發表于 2019-12-8 10:06 | 只看該作者
哪個是proteus仿真文件啊
回復

使用道具 舉報

13#
tanglong166 發表于 2020-2-22 22:11 | 只看該作者
學習一下
回復

使用道具 舉報

14#
Xvv 發表于 2020-6-14 21:41 | 只看該作者
為什么我的跑不出來呢  報錯位置在key.c里的if(k1==0)
回復

使用道具 舉報

15#
hu980219 發表于 2020-6-15 08:38 | 只看該作者
好方法
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
重庆百变王牌奖金