找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机数码管时钟 软件框图仿真程序 可以显示时分秒 注释详细

[复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


原理: 共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。led数码管由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。LED数码管以发光二极管作为发光单元,颜色有单红, 黄,蓝,绿,白,黄绿等效果。单色,分段全彩管可用大楼,道路,河堤轮廓亮化,LED数码管可均匀排布形成大面积显示区域,可显示图案及文字,并可播放不同格式的视频文件。
(仅写所用到的主要原理,不要介绍单片机本身的特点)
(4)    电路原理图


(5)    所用主要元器件清单
序号    名称    规格型号    数量    备注
1    MCU    STC89C51    1   
2    晶振    11.0592MHz    1   
3    数码管    2位共阴数码管    3   
4    芯片    74HC595    2   
5    按键    6*6*5    4   
6    上拉电阻    10k    1   
7    复位电路    10uf    1   
8    电阻    5.1k    1   
9    电阻    100    1   
10    蜂鸣器    Buz    1   

(6)    软件框图


单片机源程序如下:
  1. #include<reg51.h>  //包含51单片机头文件
  2. #define uchar unsigned char//把unsigned char 定义为uchar
  3. #define uint unsigned int//把unsigned int定义为uint
  4. /*定义外部按键接口*/
  5. sbit K1=P3^3;   //调整
  6. sbit K2=P3^0;   //确定
  7. sbit K3=P3^2;   //加
  8. sbit K4=P3^1;   //减

  9. sbit BUZZ=P1^7;   //蜂鸣器
  10. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xf7,0XAF,0XFF};        //共阳数码管编码
  11. uchar Show_table[6];//定义显示数组
  12. uchar temp_time=0,time_1s=0,time_1m=0,time_1h=0;//定义中间时间变量
  13. int hour_shi=0,hour_ge=0,mine_shi=0,mine_ge=0;//定义时间变量
  14. uchar w  = 0;
  15. uchar mode=0;
  16. uchar zhengdian_flag=0; //整点报时标志
  17. uchar flash_time=0;
  18. bit flash_flag=0;
  19. uchar key_num=0;  

  20. /*定时器0初始化*/                                                          
  21. void Time0_init()
  22. {
  23.   TMOD |= 0x01;                        //使用模式1,16位定时器
  24.   TH0   = (65536-50000)/256;        //定时器装入初始值50ms
  25.   TL0   = (65536-50000)%256;//装入定时器低八位计数值
  26.   EA    = 1;  //总中断
  27.   ET0   = 1;//定时器0初始化
  28.   TR0   = 1;//打开定时器
  29.   
  30. }

  31. void Delay_ms(uint i)//1ms延时               
  32. {
  33.   uchar x,j;//定义两个无符号字符型变量
  34.   for(j=0;j<i;j++)//循环j=0,只要j<i,j就加一直到j大于i
  35.     for(x=0;x<=148;x++);//循环x=0,只x<=0,x就减一直到x大于148
  36. }
  37. /*独立按键程序*/
  38. void KeyRead()
  39. {         
  40.   static uchar key_up=1;//按键松开标志          
  41.   if(key_up&&(K1==0||K2==0||K3==0||K4==0))
  42.   {
  43.     Delay_ms(2);//去除抖动
  44.     key_up=0;
  45.     if(K1==0)key_num=1;
  46.     else if(K2==0)key_num=2;
  47.     else if(K3==0)key_num= 3;       
  48.     else if(K4==0)key_num= 4;
  49.    
  50.   }else if(K1==1&&K2==1&&K3==1&&K4==1)// 无按键按下
  51.   {
  52.     key_up=1;             
  53.     key_num= 0;
  54.   }
  55.   else
  56.   {key_num= 0;}

  57. }
  58. void display(void)//数码管显示程序
  59. {
  60.   static uchar step=0;
  61.   P0 = 0xff;                 //关闭数码管显示
  62.   switch(step++)        //依次传送数据
  63.   {
  64.     case 0:P2=0x01;P0 = table[Show_table[0]];
  65.     break;
  66.     case 1:P2=0x02;P0 = table[Show_table[1]];
  67.     break;
  68.     case 2:P2=0x04;P0 = table[Show_table[2]];
  69.     break;
  70.     case 3:P2=0x08;P0 = table[Show_table[3]];
  71.     break;
  72.     case 4:P2=0x10;P0 = table[Show_table[4]];
  73.     break;
  74.     case 5:P2=0x20;P0 = table[Show_table[5]];
  75.     break;
  76.   }
  77.   if(step>5)step=0;           //一共6位数码管 ,超过了就从0 开始

  78. }

  79. //*************************************
  80. //主函数
  81. ///***********************************                                                          
  82. void main(void)
  83. {
  84.   Time0_init();        //初始化定时器
  85.   while(1)
  86.   {
  87.     KeyRead();//读取按键值
  88.     switch(key_num)
  89.     {
  90.     case 1:     //调整按键
  91.       mode++;
  92.       if(mode>4)mode=1;
  93.       break;
  94.     case 2:     //确定按键
  95.       mode=0;
  96.       break;
  97.     case 3:     //增加按键
  98.       if(mode==1)
  99.       {
  100.         hour_shi++;
  101.         if(hour_shi>2)hour_shi=0;
  102.       }
  103.       else if(mode==2)
  104.       {
  105.         hour_ge++;
  106.         if(hour_shi<2)
  107.         {
  108.           if(hour_ge>9)hour_ge=0;
  109.         }
  110.         else
  111.         {
  112.           if(hour_ge>3)hour_ge=0;
  113.         }
  114.       }
  115.       else if(mode==3)
  116.       {
  117.         mine_shi++;
  118.         if(mine_shi>5)mine_shi=0;
  119.       }
  120.       else if(mode==4)
  121.       {
  122.         mine_ge++;
  123.         if(mine_ge>9)mine_ge=0;
  124.       }
  125.       break;
  126.     case 4:     //减少按键
  127.       if(mode==1)
  128.       {
  129.         hour_shi--;
  130.         if(hour_shi<0)hour_shi=2;
  131.       }
  132.       else if(mode==2)
  133.       {
  134.         hour_ge--;
  135.         if(hour_shi<2)
  136.         {
  137.           if(hour_ge<0)hour_ge=9;
  138.         }
  139.         else
  140.         {
  141.           if(hour_ge<0)hour_ge=3;
  142.         }
  143.       }
  144.       else if(mode==3)
  145.       {
  146.         mine_shi--;
  147.         if(mine_shi<0)mine_shi=5;
  148.       }
  149.       else if(mode==4)
  150.       {
  151.         mine_ge--;
  152.         if(mine_ge<0)mine_ge=9;
  153.       }
  154.       break;
  155.     }
  156.           if(mode==0)//正常显示模式
  157.   {
  158.     Show_table[0]=hour_shi;
  159.     Show_table[1]=hour_ge;
  160.     Show_table[2]=mine_shi;
  161.     Show_table[3]=mine_ge;
  162.     hour_shi=time_1h/10;
  163.     hour_ge=time_1h%10;
  164.     mine_shi=time_1m/10;
  165.     mine_ge=time_1m%10;
  166.   }
  167.   else//设定模式
  168.   {       
  169.     if(flash_flag)//首先亮,这里其实就是利用程序循环3000次来达到延时的效果
  170.     {
  171.       if(mode==1)
  172.       {
  173.         Show_table[3]=mine_ge;
  174.         Show_table[mode-1]=hour_shi;
  175.       }
  176.       else if(mode==2)
  177.       {
  178.         Show_table[0]=hour_shi;
  179.         Show_table[mode-1]=hour_ge;
  180.       }
  181.       else if(mode==3)
  182.       {
  183.         Show_table[1]=hour_ge;
  184.         Show_table[mode-1]=mine_shi;
  185.       }
  186.       else if(mode==4)
  187.       {
  188.         Show_table[2]=mine_shi;
  189.         Show_table[mode-1]=mine_ge;
  190.       }
  191.     }
  192.     else//然后熄灭,这样就闪烁了, 这里其实就是利用程序循环6000次来达到延时的效果
  193.     {
  194.       Show_table[mode-1]=18;     //查数码管表
  195.     }
  196.     time_1h=hour_shi*10+hour_ge;
  197.     time_1m=mine_shi*10+mine_ge;
  198.   }
  199.   
  200.   Show_table[4]=time_1s/10;
  201.   Show_table[5]=time_1s%10;
  202.   display();//显示时间数据
  203.   }
  204. }

  205. //定时器0中断
  206. void time0(void)interrupt 1
  207. {
  208.   static uchar temp_3s=0;
  209.   if(mode==0)
  210.   {
  211.   flash_time=0;
  212.     temp_time++;
  213.     if(temp_time>=20)//1s=20*50ms
  214.     {
  215.       temp_time=0;
  216.       time_1s++;
  217.       if(time_1s>=60)
  218.       {
  219.         time_1s=0;
  220.         time_1m++;
  221.         if(time_1m>=60)
  222.         {
  223.           time_1m=0;
  224.           time_1h++;
  225.                   BUZZ=0;     //打开蜂鸣器
  226.           zhengdian_flag=1;
  227.           if(time_1h>=23)
  228.           {
  229.             time_1h=0;
  230.           }
  231.         }
  232.       }
  233.     }
  234.   }
  235.   flash_time++;
  236.   if(flash_time>2)
  237.   {
  238.     flash_flag=~flash_flag;
  239.     flash_time=0;
  240.   }


  241.   if(zhengdian_flag)
  242.   {
  243.     temp_3s++;
  244.     if(temp_3s>=60)//3000MS=50*60
  245.     {
  246.       zhengdian_flag=0;
  247.       temp_3s=0;
  248.       BUZZ=1;//3S后蜂鸣器关闭
  249.     }
  250.   }
  251.   else
  252.   {
  253.     temp_3s=0;
  254.   }
  255.   TH0=(65536-50000)/256;//重新装入计数器初值高八位
  256.   TL0=(65536-50000)%256;//重新装入计数器初值低八位
  257. }
复制代码
Keil代码与Proteus仿真下载:
5-数码管时钟.zip (249.22 KB, 下载次数: 61)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:965040 发表于 2023-11-15 15:04 | 只看该作者
非常好用,运行稳定,学习了
回复

使用道具 举报

板凳
ID:275111 发表于 2024-3-30 21:00 | 只看该作者
留言 非常感谢 之前用的是单片机内部模块做定时,这次需要使用mcu自己的定时器做多个时钟控制。之前代码总在开关TR0 总是翻车。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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