找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 5042|回复: 7
收起左侧

简单易懂,功能丰富的数字钟设计(含仿真)

  [复制链接]
ID:186556 发表于 2017-5-24 21:58 | 显示全部楼层 |阅读模式
        数拓做了一个数字钟,功能有年月日,时分秒,星期,闹钟,秒表,整点报时。通过按键切换不同功能。
材料简单,适合单片机新手

电路图

电路图
0.png
单片机源程序如下:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. /*****************************************
  5.                                 定义变量和数码表
  6. *******************************************/         
  7. sbit s1=P0^0;                  //数码管位选控制端
  8. sbit s2=P0^1;
  9. sbit s3=P0^2;
  10. sbit s4=P0^3;
  11. sbit s5=P0^4;
  12. sbit s6=P0^5;

  13. sbit s7=P0^6;                        //LED闹钟
  14.                   
  15. sbit k1=P2^7;          /*k1设置时间,k2定时。k1,k2使用不自动弹起按键。 k3时分秒选择,k4加数字,k5减数字。*/
  16. sbit k2=P2^6;            
  17. sbit k3=P2^5;
  18. sbit k4=P2^4;

  19. uchar count=0,a=0,b=0,c=0,d=0,e=0,f=0,
  20. djss=0,djsm=0,djsh=0,st,mt,ht,sec,min,hour,w=0,ss=0,
  21. thousand,hundred,ten,ge,liang1,liang2;s=60,m=60,h=24;
  22. uint year=2017,month=5,day=12,week;
  23. uchar code mum[]={0xc0,0xf9,0xa4,0xb0,0x99,
  24. 0x92,0x82,0xf8,0x80,0x90};                         //共阳数码管0-9编码
  25. void display(uchar zs,uchar zm, uchar zh);
  26. void WeekDay(uint y,uint M, uint d);
  27. unsigned mon(uchar mo);
  28. /*******************************************
  29.                          延时程序
  30.                 供动态扫描和按键去抖用
  31. *******************************************/
  32. void delayms(uint k)                                                           //延时函数
  33. {
  34. uint i,j;
  35. for(i=k;i>0;i--)
  36. for(j=110;j>0;j--);        
  37. }                                          
  38. /*******************************************
  39.                                 时间控制函数0
  40. *******************************************/
  41. void timecontrol()      /*通过count获得hour,min,sec变量值 */
  42. {
  43. sec++;
  44.     if(sec==60)
  45.     {
  46.             sec=0;
  47.         min++;
  48.         if(min==60)
  49.         {
  50.                 min=0;
  51.             hour++;
  52.             if(hour==24)
  53.             hour=0;
  54. }
  55. }
  56. }
  57. /*******************************************
  58.                                 时间控制函数1
  59. *******************************************/
  60. void timecontrol1()      
  61. {
  62. djss++;
  63.     if(djss==60)
  64.     {
  65. djss=0;
  66. djsm++;
  67.         if(djsm==60)
  68.         {
  69. djsm=0;
  70.             djsh++;
  71.             if(djsh==24)
  72.             djsh=0;
  73.         }
  74.     }
  75. }
  76. /*******************************************
  77.                                 整点报时程序
  78. *******************************************/
  79. void baoshi()
  80. {
  81.         if((min=59)&(sec==59))/*整点报时功能*/
  82.         {
  83.                 uchar bs;
  84.                 bs=sec;
  85.                 bs++;
  86.                 while(bs>0)/*报时次数等于小时数*/
  87.                 {
  88.                         bs--;
  89.                         s7=0;
  90.                         delayms(100);
  91.                         s7=1;
  92.                         delayms(100);
  93.                 }
  94.         }
  95. }
  96. /*******************************************
  97.                                 数码管显示程序
  98. *******************************************/
  99. void display(uchar zs,uchar zm, uchar zh)                 
  100. {         
  101. s1=1;
  102.           P1=mum[zh/10];
  103.           delayms(1);
  104.           s1=0;

  105. s2=1;
  106.           P1=mum[zh%10]&0x7f;                                   // 时的个位加上小数点
  107.           delayms(1);
  108.           s2=0;
  109.    
  110.           s3=1;
  111.           P1=mum[zm/10];      
  112.           delayms(1);
  113.           s3=0;
  114.   
  115.           s4=1;
  116.           P1=mum[zm%10]&0x7f;                                //分的个位加上小数点
  117.           delayms(1);
  118.           s4=0;
  119.    
  120.           s5=1;
  121.           P1=mum[zs/10];
  122.           delayms(1);
  123.           s5=0;
  124.    
  125.           s6=1;      
  126.           P1=mum[zs%10];
  127.           delayms(1);
  128.           s6=0;
  129. }
  130. /*******************************************
  131.                                 按键选择程序
  132. *******************************************/
  133. void choose()
  134. {          
  135. if(k2==0)
  136. {
  137. delayms(10);
  138.         if(k2==0)         
  139.         {
  140.                 while(!k2);
  141.             ss++;
  142.             if(ss==3)        
  143. ss=0;
  144.         }
  145.     }  
  146. }
  147. void dm()
  148. {          
  149. djss=0;
  150. djsm=0;
  151. djsh=0;
  152. TR1=0;
  153.         while((w==5)&(k1==1))               
  154.         {               
  155.                 display(djss,djsm,djsh);                       
  156. if(k2==0)
  157.         {
  158.                 delayms(10);
  159.             if(k2==0)         
  160.             {
  161.                     while(!k2);
  162.                 {         
  163. TR1=1;display(djss,djsm,djsh);       
  164. }
  165. }
  166. }
  167.                         if(k3==0)
  168.                 {
  169.                     delayms(10);
  170.                 if(k3==0)         
  171.                 {
  172.                 while(!k3);
  173.                                 TR1=0;
  174.                 }
  175. }
  176.                                 if(k4==0)
  177.                 {
  178.                         delayms(10);
  179.                     if(k4==0)         
  180.                     {
  181.                             while(!k4);
  182.                                                 {
  183. TR1=0;djss=0;djsm=0;djsh=0;
  184. }
  185. }
  186. }
  187. }
  188. }
  189. /*******************************************
  190.                            时间设置函数
  191. *******************************************/
  192. void keyscan_settime()              
  193. {
  194. display(sec,min,hour);
  195.     if(k1==0)
  196.     {
  197.             delayms(10);
  198.         if(k1==0)                     //关闭定时器
  199. {
  200. while(k1==0);         //等待用户按键
  201.                         w++;
  202. }
  203.         }                 
  204.                        
  205. }          
  206. void tshi()
  207. {
  208. st=sec,mt=min,ht=hour;
  209.     TR0=0; ss=0;      
  210.         while((w==1)&(k1==1))               
  211.         {               
  212.                 display(st,mt,ht);                       
  213.         choose();        /*通过ss选择时分秒设置*/
  214. if(k3==0)                //加数
  215.         {
  216.                 delayms(10);
  217.             if(k3==0)
  218.           {
  219.                while(!k3);
  220.                switch(ss)
  221.                {
  222.                                case 0:st++;if(st==60)st=0;break;
  223.                     case 1:mt++;if(mt==60)mt=0;break;
  224.                     case 2:ht++;if(ht==24)ht=0;break;      
  225.                     default : ;                                          
  226.                 }
  227.            }      
  228.     }
  229. if(k4==0)                //减数
  230.     {
  231.             delayms(10);
  232.         if(k4==0)
  233.         {
  234.                 while(!k4);
  235.             switch(ss)
  236.             {
  237.                     case 0:if(st>0)st--;
  238.                 else  st=59;break;
  239.                 case 1:if(mt>0)mt--;
  240.                 else  mt=59;break;
  241.                 case 2:if(ht>0)ht--;
  242.                 else  ht=23;break;      
  243.                 default : ;
  244.             }                                                                                                                                       
  245.         }      
  246.         }
  247. }
  248. }
  249. /*******************************************
  250.                             定时函数
  251. *******************************************/
  252. void dshi()
  253. {       
  254. TR0=1;
  255.     sec=st,min=mt,hour=ht;                 
  256. s=sec;m=min;h=hour;ss=0;
  257. while((w==2)&(k1==1))
  258.         {
  259.                 display(s,m,h);
  260.         if(k2==0)
  261.         {
  262.                 delayms(10);
  263.             if(k2==0)         
  264.             {
  265. while(!k2);
  266.                 ss++;
  267.                 if(ss==3)      
  268. ss=0;
  269.                 }
  270.             }                    /*通过ss选择时分秒设置*/
  271. if(k3==0)                //加数
  272.             {
  273.                     delayms(10);
  274.                 if(k3==0)
  275.                 {
  276.                         while(!k3);
  277.                     switch(ss)
  278.                     {
  279.                             case 0:s++;if(s==60)s=0;break;
  280.                         case 1:m++;if(m==60)m=0;break;
  281.                         case 2:h++;if(h==24)h=0;break;      
  282.                         default :;                                               
  283.                     }
  284.                 }      
  285.             }
  286.             if(k4==0)                //减数
  287.             {
  288.                     delayms(10);
  289.                 if(k4==0)
  290.                 {
  291.                         while(!k4);
  292.                     switch(ss)
  293.                     {
  294.                             case 0:if(s>0)s--;
  295.                         else   s=59;break;
  296.                         case 1:if(m>0)m--;
  297.                         else   m=59;break;
  298.                         case 2:if(h>0)h--;
  299.                         else   h=23;break;      
  300.                         default : ;
  301.                     }                                                                                                                                            
  302.                 }      
  303.            }
  304. }
  305. }
  306. /*******************************************
  307.                                 年调整程序
  308. *******************************************/       
  309. void year_change()
  310. {       
  311.         ss=1;
  312.         while((w==3)&(k1==1))
  313.         {
  314.                 display(0,liang1,liang2);
  315.         if(k2==0)
  316.         {
  317.                 delayms(10);
  318.             if(k2==0)         
  319.             {
  320.                     while(!k2);
  321.                 ss++;
  322.                 if(ss==3)        
  323. ss=1;
  324.             }
  325.         }               /*通过ss选择时分秒设置*/
  326. if(k3==0)                //加数
  327.             {
  328.                       delayms(10);
  329.                 if(k3==0)
  330.                 {
  331.                         while(!k3);
  332.                     switch(ss)
  333.                     {
  334.                             case 1:liang1++;if(liang1==100)liang1=0;break;
  335.                         case 2:liang2++;if(liang2==21)liang2=0;break;      
  336.                         default :;                                               
  337.                     }
  338.                }      
  339.           }
  340.           if(k4==0)                //减数
  341.           {
  342.                           delayms(10);
  343.                 if(k4==0)
  344.                 {
  345.                         while(!k4);
  346.                     switch(ss)
  347.                     {
  348.                             case 1:if(liang1>0)liang1--;
  349.                         else   liang1=99;break;
  350.                         case 2:if(liang2>0)liang2--;
  351.                         else   liang2=20;break;      
  352.                         default : ;
  353.                     }   
  354.                         }
  355.                 }
  356.         }
  357. }
  358. /*******************************************
  359.                                 月日调整程序
  360. *******************************************/
  361. void md_change()
  362. {       
  363. ge=liang1%10;
  364.         ten=liang1%100/10;
  365.         hundred=liang2%10;
  366.         thousand=liang2%100/10;
  367.         year=thousand*1000+hundred*100+ten*10+ge;
  368.         ss=1;
  369.         while((w==4)&(k1==1))
  370.         {         
  371. WeekDay(year,month,day);
  372.                 display(week,day,month);
  373.         if(k2==0)
  374.         {
  375.                 delayms(10);
  376.             if(k2==0)         
  377.             {
  378.                     while(!k2);
  379.                 ss++;
  380.                 if(ss==3)        
  381. ss=1;
  382.             }
  383.        }                  /*通过ss选择时分秒设置*/
  384. if(k3==0)                //加数
  385.             {
  386.                     delayms(10);
  387.                 if(k3==0)
  388.                 {
  389.                         while(!k3);
  390.                     switch(ss)
  391.                     {
  392.                                               case 1:day++;
  393. if(day==(mon(month)+1))day=1;
  394. break;
  395.                         case 2:month++;if(month==13)month=1;
  396. break;      
  397.                         default :;                                               
  398.                     }
  399.                }      
  400.           }
  401.            if(k4==0)                //减数
  402.            {
  403.                            delayms(10);
  404.                 if(k4==0)
  405.                 {
  406.                         while(!k4);
  407.                     switch(ss)
  408.                     {
  409.                             case 1:if(day>1)day--;
  410.                         else   day=mon(month);break;
  411.                         case 2:if(month>1)month--;
  412.                         else   month=12;break;      
  413.                         default : ;
  414.                     }
  415.                                 }
  416.                         }
  417.                 }
  418.         }
  419. /*******************************************
  420.                         时分秒调整程序
  421. *******************************************/                                                                                                 
  422. void buz()
  423. {           
  424. if((hour==h)&&(min==m)&&(sec==s))
  425. {  
  426. TR1=1;b=0;
  427.                 while(1)   
  428.                 {
  429. if(b%2==0)
  430.                         {
  431.                                 s7=0;
  432.                                 display(sec,min,hour);       
  433. }
  434.                         else{ s7=1;
  435.                         display(sec,min,hour);}
  436. if(b==11)
  437.                         {
  438. s7=1;b=0;TR1=0;break;
  439. }
  440.                                 if(k4==0)                //减数
  441.                     {
  442.                         delayms(10);
  443.                     if(k4==0)
  444.                     {
  445.                             while(!k4);
  446.                                                 {s7=1;break;
  447. }
  448. }  
  449. }
  450. }
  451. }
  452. }
  453. /*******************************************
  454.                 闰年判断程序
  455. *******************************************/
  456. unsigned leap(uchar y)                                     //判断是否闰年并返回二月份的天数
  457. {                                   //闰年返回29,平年返回28
  458.         y+=2000;
  459.     if(y%4==0)
  460.     {
  461.                 if(y%100==0)
  462.                 {
  463.                         if(y%400==0)
  464.                                 return 29;
  465.                         else
  466.                                 return 28;
  467.                 }
  468.                 else
  469.                         return 29;
  470.         }
  471.         else
  472.                 return 28;
  473. }
  474. /*******************************************
  475.                                 月返回函数
  476. *******************************************/
  477. unsigned mon(uchar mo)                           //计算并返回每个月的天数
  478. {
  479.         switch(mo)
  480.     {
  481.                 case 1:
  482.                 case 3:
  483.                 case 5:
  484.                 case 7:
  485.                 case 8:
  486.                 case 10:
  487.                 case 12:        return 31;
  488.                 break;                                              //1,3,5,7,8,10,12月每月31天
  489.                 case 4:
  490.                 case 6:
  491.                 case 9:
  492.                 case 11:        return 30;
  493.                 break;                                           //4,6,9,11月每月30天
  494.                 case 2:         return leap(year);
  495.                 break;                                                //返回二月份的天数
  496.                 default:        break;
  497.         }
  498. }
  499. /*******************************************
  500.                                 星期显示程序
  501. *******************************************/
  502. void WeekDay(uint y,uint M, uint d)
  503. {
  504. if(M==1||M==2)
  505. {
  506. M+=12;
  507. y--;
  508. }
  509.         week=(d+2*M+3*(M+1)/5+y+y/4-y/100+y/400+1)%7;
  510.         if(week==0)
  511. week=7;
  512. }
  513. void ymd()
  514. {       
  515. if(w==0)
  516.         {
  517.                 if(k3==0)               
  518.          {
  519.            delayms(10);
  520.             if(k3==0)
  521.             {       
  522. while(!k3);
  523.                                  c++;
  524. }
  525. }
  526. }
  527. }
  528. void ymd1()
  529. {       
  530.         display(0,liang1,liang2);
  531. }
  532. void ymd2()
  533. {       
  534. WeekDay(year,month,day);
  535.         display(week,day,month);
  536. }
  537. /*******************************************
  538.                                 主函数程序
  539. *******************************************/       
  540. void main()
  541. {               
  542.         TMOD=0x11;                          //定时器0工作在方式1
  543.         TH0=(65536-45872)/256;                          //装初值,50ms
  544.         TL0=(65536-45872)%256;
  545.         EA=1;                                          //总中断允许
  546. ……………………

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

所有资料51hei提供下载:
数拓---数字钟设计.rar (137.66 KB, 下载次数: 112)


评分

参与人数 3黑币 +76 收起 理由
15838831911 + 18
waitc + 8 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

举报

ID:353947 发表于 2018-6-18 22:54 | 显示全部楼层
大神有没有时间帮我做一个简单的题目  我们的课设  真心不会
回复

举报

ID:350863 发表于 2018-6-19 10:23 来自触屏版 | 显示全部楼层
加个温度测量就更完美了!
回复

举报

ID:232619 发表于 2018-10-7 15:27 | 显示全部楼层
谢谢分享
回复

举报

ID:284846 发表于 2018-10-7 16:24 | 显示全部楼层
学习中,谢谢!
回复

举报

ID:765587 发表于 2020-6-1 01:37 来自触屏版 | 显示全部楼层
月日函数设置,k 2显示未定义
回复

举报

ID:762487 发表于 2020-6-9 12:54 | 显示全部楼层
很棒!
回复

举报

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

本版积分规则

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

Powered by 单片机教程网

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