找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9129|回复: 3
收起左侧

单片机用8位数码管-显示时钟Proteus仿真+代码

[复制链接]
ID:293363 发表于 2019-5-6 21:46 | 显示全部楼层 |阅读模式
程序要求如下:
   1、使用定时器中断
         2、数码管显示:时-分-秒
         3、三个按键控制:MOD键、+键,-键
       在正常计时时,按MOD键一次,时间暂停,如果这时按+键或键-键,秒的数量就加1或减一;再按MOD键(两次),如果这时按+键或键-键,分                 的数量就加1或减一;再按MOD键(三次),如果这时按+键或键-键,时的数量就加1或减一;再按MOD键(四次),启动计时(恢复正常计时)。
    4、12小时制或24小时制。
废话不多说,直接上图
仿真.jpg

单片机源程序如下:
  1. //------------------------------------------------------------------------
  2. //名称:按键调节数码管显示
  3. //------------------------------------------------------------------------
  4. //说明:
  5. //     按MOD键一次,时间暂停,如果这时按+键或键-键,
  6. //     秒的数量就加1或减一;再按MOD键(两次),如果这时按+键或键-键,
  7. //     分的数量就加1或减一;再按MOD键(三次),如果这时按+键或键-键,
  8. //     时的 数量就加1或减一;再按MOD键(四次),启动计时(恢复正常计时)。   
  9. //------------------------------------------------------------------------

  10. #include <reg51.h>                            //调用含有51专用寄存器的头文件
  11. #define uchar unsigned char            //用uchar代替unsigned char
  12. #define uint unsigned int                //用uint代替unsigned int

  13. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};        //共阳极数码管断码表
  14. //uchar code  table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管断码表

  15. sbit mode = P1^0;         //模式调节
  16. sbit s1 = P1^1;             //加
  17. sbit s2 = P1^2;             //减

  18. int sec=20,min=5,hour=12;           //显示初值
  19. uint temp;                                           //临时变量
  20. uchar m,n;


  21. /***********************************
  22.            延时子函数
  23. *************************************/
  24. void delayms(uint xms)
  25. {
  26.    uint i,j;
  27.    for(i=xms;i>0;i--)
  28.          for(j=120;j>0;j--);
  29. }

  30. /*******************************
  31.           显示子函数
  32. ********************************/
  33. void display(void)
  34. {
  35.    P2=0x80;
  36.    P0=table[sec%10];                   //显示秒个位
  37.    delayms(5);

  38.    P2=0x40;
  39.    P0=table[sec/10];                  //显示秒十位
  40.    delayms(5);

  41.    P2=0x20;                                  //显示横线
  42.    P0=0xbf;
  43.    delayms(5);

  44.    P2=0x10;                                          //显示分个位
  45.    P0=table[min%10];
  46.    delayms(5);

  47.    P2=0x08;                                          //显示分十位
  48.    P0=table[min/10];
  49.    delayms(5);

  50.    P2=0x04;                              //显示横线
  51.    P0=0xbf;
  52.    delayms(5);

  53.    P2=0x02;                                           //显示时个位
  54.    P0=table[hour%10];
  55.    delayms(5);

  56.    P2=0x01;                                          //显示时十位
  57.    P0=table[hour/10];
  58.    delayms(5);
  59. }

  60. /*****************************************
  61.                           按键子函数
  62. *******************************************/
  63. void key()                             
  64. {
  65. if(mode==0)                 //第一次判断"模式"按键按下
  66. {
  67.   delayms(5);                //延时消抖
  68.   if(mode==0)                //第二次判断"模式"按键按下
  69.   { TR0=0;n++; }                     //暂停计时,并且记录按键按下的次数
  70.    while(!mode)              //等待按键释放
  71.    {display();}              //调用显示函数消除数码管闪烁
  72. }                                                                 
  73.   if(n>3)                                         //如果第四次按下mode键则继续计时,并且重新记录按下的按键次数
  74. {TR0=1;n=0;}                
  75. /********************************
  76.                调整+
  77. *********************************/
  78.          if (s1==0)                                 //第一次判断"+"按键按下
  79.          {                                                 
  80.          {delayms(10);                         //延时消抖
  81.          if (s1==0)                                 //第二次判断"模式"按键按下
  82.          {
  83.          switch(n)                                 //根据"模式"按键按下的次数,执行对应程序
  84.          {
  85.            case 1:sec++;if(sec>59)sec=0;                 //秒递增,最大显示59,若59继续递增则显示00
  86.            break;
  87.            case 2:min++;if(min>59)min=0;                 //分递增,最大显示59,若59继续递增则显示00
  88.            break;
  89.            case 3:hour++;if(hour>23)hour=0;                 //时递增,最大显示59,若23继续递增则显示00
  90.            break;
  91.          }
  92.          }
  93.         }
  94.          while(!s1)              //等待"+"按键释放
  95.           {display();}           //调用显示函数消除数码管闪烁
  96.          }
  97. /******************************
  98.                 调整-
  99. *******************************/
  100. if (s2==0)                                         //第一次判断"-"按键按下
  101. {
  102. {delayms(10);                                 //延时消抖
  103.   if(s2==0)                                         //第二次判断"模式"按键按下
  104.   {
  105.    switch(n)                                 //根据"模式"按键按下的次数,执行对应程序
  106.          {
  107.            case 1:sec--;if(sec<=0)sec=59;                //秒递减,最小显示00,若00继续递减则显示59
  108.            break;
  109.            case 2:min--;if(min<=0)min=59;                //分递减,最小显示00,若00继续递减则显示59
  110.            break;
  111.            case 3:hour--;if(hour<=-1)hour=23;        //时递减,最小显示00,若00继续递减则显示23
  112.            break;
  113.          }
  114.   }
  115.   }
  116.         while(!s2)//等待按键释放
  117.   {display();}//调用显示函数消除数码管闪烁
  118. }

  119. }

  120. /*************主函数************/
  121. void main(void)   
  122. {         
  123.    TMOD=0x11;                              //设置工作方式
  124.    ET0=1;                                             //使能定时器0
  125.    TH0=(65536-50000)/256;           //定时器的初值
  126.    TL0=(65536-50000)%256;
  127.    TR0=1;                             //停止开启定时器0   
  128.    EA=1;                             //使能中断
  129.     while(1)
  130.         {
  131.          display();                                 //调用显示函数
  132.          key();                                         //调用按键处理函数
  133.         }
  134. }
  135. /************定时器0中断计时**********/         
  136. void  Time0() interrupt 1
  137. {
  138.   TH0=(65536-50000)/256;            //重装初值50ms;
  139.   TL0=(65536-50000)%256;
  140.   m=m+1;
  141.   key();
  142.   if(m>20)                          // m=20说明1秒时间到
  143.   {
  144.     m=0;
  145.         sec++;       
  146.     if(sec>59)                         //判断到达60s
  147.     {
  148.      min++;                                 //分钟加1
  149.          sec=0;
  150.           if(min>59)                     //判断到达60分
  151.          {
  152.           hour=hour+1;                         //小时加1
  153.           min=0;
  154.          }
  155.          if(hour==24)hour=0;         
  156.     }
  157.    }  
  158. }
复制代码
0.png
所有资料51hei提供下载:
可调时钟.zip (59.2 KB, 下载次数: 181)

评分

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

查看全部评分

回复

使用道具 举报

ID:743615 发表于 2020-5-4 10:17 来自手机 | 显示全部楼层
请问如果再加个蜂鸣器整点报时,程序要怎么写呢
回复

使用道具 举报

ID:781711 发表于 2020-6-17 15:25 | 显示全部楼层
您好,能问一下怎么把时钟上最开始的值设为十二点整?
回复

使用道具 举报

ID:293363 发表于 2020-6-26 21:12 | 显示全部楼层
huang452 发表于 2020-6-17 15:25
您好,能问一下怎么把时钟上最开始的值设为十二点整?

修改显示初值 sec min hour 的值
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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