找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4137|回复: 1
打印 上一主题 下一主题
收起左侧

单片机可调时钟的C程序及proteus仿真图

[复制链接]
跳转到指定楼层
楼主
分享一个基于51单片机的可调时钟小设计

模式键:按一次,进入倒计时设置模式(设置倒计时的时间,比如2min30s,5min40s等)
    按两次,进入倒计时模式(开始倒计时)
    按三次,进入钟表时间调节模式
    按四次,回到正常显示模式(进入计时器/倒计时模式时不影响钟表正常走时)

配置键:按一次调整分
    按两次调整时
    按三次,回到调整分,依次循环
    (配置键选择需要调整的单位,由加/减键进行加减调整)

加法键:数值加
减法键:数值减


红色数码管显示0时,为正常显示模式
红色数码管显示1时,为倒计时设置模式
红色数码管显示3时,为倒计时模式

在正常显示模式下,除模式键外其他按键都不可用
在钟表时间调节模式下,钟表不走时,其他任何模式都不影响钟表的正常走时

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)



单片机源程序如下:
  1.         /*晶振12MHZ*/   
  2. #include<reg52.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar code wela[6] = {0x20,0x10,0x08,0x04,0x02,0x01};           //位选码
  6. uchar code dula[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};         //段选码
  7. uchar buff[6] = {0,0,0,0,0,0};

  8. sbit P33 = P3^3;
  9. sbit P32 = P3^2;
  10. sbit P34 = P3^4;
  11. sbit P35 = P3^5;
  12. uchar hour,second,minute,hour_1,second_1,minute_1,hour_2,second_2,minute_2,t0,mode,reset,i;
  13.         //无下划线的为时分秒辅助变量,下划线1的为时钟时分秒,下划线2的为倒计时时分秒

  14. void init();       //初始化函数
  15. void mode_0(void);                //动态扫描函数       
  16. void mode_1(void);                //闪烁函数       
  17. void time_1(void);                //时钟函数(正计时)
  18. void time_2(void);                //倒计时函数
  19. void oper_add(void);        //加法键函数
  20. void oper_minus(void);         //减法键函数
  21. void delay(uint z);                 //延时函数

  22. void main()
  23. {
  24.         init();
  25.         while(1)
  26.         {
  27.                 if(mode==1)
  28.                 {
  29.                         second = second_2;
  30.                         minute = minute_2;
  31.                         hour = hour_2;
  32.                         oper_add();                          //加法键函数
  33.                         oper_minus();                //减法键函数
  34.                         second_2 = second;
  35.                         minute_2 = minute;
  36.                         hour_2 = hour;
  37.                 }
  38.                 else if(mode==3)
  39.                 {
  40.                         second = second_1;
  41.                         minute = minute_1;
  42.                         hour = hour_1;
  43.                         oper_add();
  44.                         oper_minus();
  45.                         second_1 = second;
  46.                         minute_1 = minute;
  47.                         hour_1 = hour;
  48.                 }
  49.         }
  50. }

  51.         /*初始化函数*/
  52. void init()
  53. {
  54.         TMOD = 0x01;                           //设置T0为方式一
  55.         TH0 = 0x3c;
  56.         TL0 = 0xb0;
  57.         IE = 0x87;
  58.         IT0 = IT1 = 0;
  59.         IP = 0X02;                                        //设置T0为高优先级
  60.         TR0 = 1;
  61.         t0 = 0;
  62.         mode = 0;
  63.         P1 = 0xc0;

  64. }

  65.         /*模式键函数,外部中断0*/
  66. void X0_mode() interrupt 0                                               
  67. {
  68.         delay(10);
  69.         if(P32 == 0)
  70.         {
  71.                 mode++;                                                //mode为模式标志位
  72.                 reset = 0;                                        //reset为时分秒调节标志位
  73.                 switch(mode)
  74.                 {
  75.                         case 0 :        P1 = 0xc0 ; break;
  76.                         case 1 : {  P1 = 0xf9 ; hour_2 = second_2 = minute_2 = 0;} break;
  77.                         case 2 :         P1 = 0xa4 ; break;
  78.                         case 3 :        P1 = 0xb0 ; break;
  79.                         case 4 : {        P1 = 0xc0 ; mode = 0;} break;
  80.                         default : break;
  81.                 }

  82.         }
  83.         while(P32 == 0);
  84.        
  85. }

  86.         /*配置键函数,外部中断1*/
  87. void X1_reset() interrupt 2                                               
  88. {
  89.         delay(10);
  90.         if(P33 == 0)
  91.         {
  92.                 if((mode==1) || (mode==3))
  93.                         {
  94.                                 reset++;                         //时分秒调节标志位
  95.                                 if(reset == 3)
  96.                                         reset = 0;
  97.                         }
  98.         }
  99.         while(P33 == 0);
  100.        
  101. }

  102.         /*计时/动态扫描函数,内部中断0*/
  103. void T0_disp() interrupt 1                                  
  104. {       
  105.         TH0 = 0xb1;
  106.         TL0 = 0xe0;                                                 //b1e0(20ms)
  107.         t0++;
  108.         if(t0==50)                                                 //秒计数部分(正倒计时共用)
  109.         {
  110.                 t0=0;
  111.                 if(mode != 3)
  112.                         time_1();                                 //除了调节钟表时间调节模式外,其他模式下执行正计时函数
  113.                 if(mode==2)
  114.                         time_2();                                 //进入倒计时模式时,执行倒计时函数(正计时不受干扰)
  115.         }
  116.         if((mode==1) || (mode==2))                   //装载部分,将时分秒装载到数组buff,便于动态扫描。
  117.         {
  118.                 buff[0]=second_2%10;
  119.                 buff[1]=second_2/10;
  120.                 buff[2]=minute_2%10;
  121.                 buff[3]=minute_2/10;
  122.                 buff[4]=hour_2%10;
  123.                 buff[5]=hour_2/10;
  124.                        
  125.         }
  126.         else
  127.         {
  128.                 buff[0]=second_1%10;
  129.                 buff[1]=second_1/10;
  130.                 buff[2]=minute_1%10;
  131.                 buff[3]=minute_1/10;
  132.                 buff[4]=hour_1%10;
  133.                 buff[5]=hour_1/10;
  134.         }                       
  135.         switch(mode)                                                //显示部分,包括动态扫描和闪烁函数
  136.         {
  137.                 case 0 : mode_0() ; break;
  138.                 case 1 : mode_1() ; break;
  139.                 case 2 : mode_0() ; break;
  140.                 case 3 : mode_1() ; break;
  141.                 default : break;
  142.         }       
  143.        
  144. }

  145.         /*动态扫描函数*/
  146. void mode_0(void)
  147. {
  148.         for(i=0;i<6;i++)
  149.         {
  150.                 P2=wela[i];
  151.                 P0=dula[buff[i]];
  152.                 delay(1);       
  153.         }
  154.         P2 = 0xe0;
  155.         P0 = 0xbf;
  156.         delay(1);               
  157. }

  158.         /*闪烁函数*/
  159. void mode_1(void)                                                                //实现0.5s亮灭闪烁
  160. {
  161.         P2 = 0xc0;
  162.         P0 = 0xbf;
  163.         delay(1);
  164.                
  165.         if((reset==0) && (t0>24))        P2 = 0;
  166.         else        P2 = wela[0];
  167.         P0 = dula[buff[0]];
  168.         delay(1);

  169.         if((reset==0) && (t0>24))        P2 = 0;
  170.         else        P2 = wela[1];       
  171.         P0 = dula[buff[1]];
  172.         delay(1);

  173.         if((reset==1) && (t0>24))        P2 = 0;
  174.         else        P2 = wela[2];
  175.         P0 = dula[buff[2]];
  176.         delay(1);

  177.         if((reset==1) && (t0>24))        P2 = 0;
  178.         else        P2 = wela[3];
  179.         P0 = dula[buff[3]];
  180.         delay(1);

  181.         if((reset==2) && (t0>24))        P2 = 0;
  182.         else        P2 = wela[4];
  183.         P0 = dula[buff[4]];
  184.         delay(1);

  185.         if((reset==2) && (t0>24))        P2 = 0;
  186.         else        P2 = wela[5];
  187.         P0 = dula[buff[5]];
  188.         delay(1);


  189. }

  190.         /*正计时函数*/
  191. void time_1(void)                                                                 
  192. {
  193.         second_1++;
  194.         if(second_1==60)
  195.         {
  196.                 second_1=0;
  197.                 minute_1++;
  198.                 if(minute_1==60)
  199.                 {
  200.                         minute_1=0;
  201.                         hour_1++;
  202.                         if(hour_1==24)
  203.                                 hour_1=0;
  204.                 }
  205.         }
  206. }

  207.         /*倒计时函数*/
  208. void time_2(void)                                                                 
  209. {
  210.         second_2--;
  211.         if(second_2==255)
  212.         {
  213.                 second_2=59;
  214.                 minute_2--;
  215.                 if(minute_2==255)
  216.                 {
  217.                         minute_2=59;
  218.                         hour_2--;
  219.                         if(hour_2==255)
  220.                                 hour_2=23;
  221.                 }
  222.         }
  223. }

  224.         /*加法键函数*/
  225. void oper_add(void)
  226. {
  227.         if(P35 == 0)
  228.         {
  229.                 delay(10);
  230.                 if(P35 == 0)
  231.                 {
  232.                         switch(reset)
  233.                         {
  234.                                 case 0 :
  235.                                         {
  236.                                                 second++;
  237.                                                 if(second > 59)
  238.                                                         second = 0;                                               
  239.                                         } break;
  240.                                 case 1 :
  241.                                         {
  242.                                                 minute++;
  243.                                                 if(minute > 59)
  244.                                                         minute = 0;                                               
  245.                                         } break;
  246.                                 case 2 :
  247.                                         {
  248.                                                 hour++;
  249.                                                 if(hour > 24)
  250.                                                         hour = 0;                                       
  251.                                         }
  252.                                 default : break;
  253.                         }

  254.                 }
  255.                 while(P35 == 0);
  256.         }       
  257. }

  258.         /*减法键函数*/
  259. void oper_minus(void)
  260. {
  261.         if(P34 == 0)
  262.         {
  263.                 delay(10);
  264.                 if(P34 == 0)
  265.                 {
  266.                         switch(reset)
  267. ……………………

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

所有资料51hei提供下载:
clock.zip (65.56 KB, 下载次数: 67)


评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:411940 发表于 2018-10-18 21:31 | 只看该作者
很厉害的程序,感谢楼主分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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