找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6170|回复: 2
收起左侧

单片机6位数码管时钟

[复制链接]
ID:363597 发表于 2018-7-2 23:41 | 显示全部楼层 |阅读模式

C51单片机六位数码管时钟

用数码管dot分隔时分秒

用三个按键设置时间:

SET键:小时设定->分钟设定->结束设定,小时设定状态时表示小时的两位数码管闪烁,分钟设定时表示分钟的两位数码管闪烁

CHANGE键:在小时设定状态和分钟设定状态改变数值

SET S键:秒置零

20160922120743121 .jpg

C语言代码:

//main.c

  1. #include <REGX52.H>

  2. typedef unsigned int UINT  ;

  3. typedef unsigned char UCHAR        ;

  4. #define KEY P2

  5. #define KEYMASK   0x07  

  6. sbit LE1 = P2^6;  //定义位控口                        

  7. sbit LE2 = P2^7;  //定义段控口

  8. UCHAR KeyPressDown = 0x00;  

  9. UCHAR KeyRelease = 0x00;  

  10. UCHAR LastKey = 0x00;  

  11. UCHAR MODE ;

  12. extern UCHAR HH;

  13. extern UCHAR MM;

  14. extern UCHAR SS;

  15. extern bit T_CYCLE  ;

  16. extern void T0_Init(void);        //初始化定时器,函数定义在Timer.c

  17. UCHAR code NUM[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

  18. void delay(UINT t) //延时t时钟周期

  19. {

  20.         while (t--)        ;

  21. }

  22. void H_Increase(void)        //小时增1

  23. {

  24.         if(HH<23) HH++;

  25.         else

  26.         {

  27.                 HH = 0;

  28.         }

  29. }

  30. void M_Increase(void)  //分钟增1

  31. {

  32.         if(MM<59) MM++;

  33.         else

  34.         {

  35.                 MM = 0;

  36.                 H_Increase();

  37.         }

  38. }

  39. void S_Increase(void)  //秒增1

  40. {

  41.         if(SS<59) SS++;

  42.         else

  43.         {

  44.                 SS = 0;

  45.                 M_Increase();

  46.         }

  47. }

  48. void display(UCHAR SEG,UCHAR Digi) //显示一位数码管,SEG = 0-9数字,Digi = 第0-6位

  49. {

  50.         LE2 = 1;

  51.         P0 = (0x01<<Digi) ;

  52.         LE2 = 0;

  53.         P0 = 0x00;

  54.         LE1 = 1;

  55.         P0 = NUM[SEG];

  56.         if (Digi==1||Digi==3) P0 &= 0x7f        ;  //显示分隔符

  57.         delay(50);

  58.         P0 = 0xff;

  59.         LE1 = 0;

  60. }

  61. void main(void)

  62. {

  63.     P0 = 0xff;

  64.     LE1 = 0;

  65.     LE2 = 0;

  66.         T0_Init();

  67.     while(1)

  68.         {

  69.                 if(MODE != 1 || T_CYCLE)

  70.                 {

  71.                         display(HH/10,0);  //显示小时十位数

  72.                         display(HH%10,1);  //显示小时个位数

  73.                 }

  74.                 if(MODE != 2  || T_CYCLE)

  75.                 {

  76.                         display(MM/10,2);  //显示分钟十位数

  77.                         display(MM%10,3);  //显示分钟个位数

  78.                 }

  79.                 display(SS/10,4);  //显示秒十位数

  80.                 display(SS%10,5);  //显示秒个位数

  81.         }

  82. }

  83. void key_Process(void)                 //按键处理程序

  84. {

  85.     UCHAR CurrKey;  


  86.     KEY |= KEYMASK;  //将按键对应的IO设置为输入状态  

  87.     CurrKey = (~KEY) & KEYMASK;  

  88.   

  89.     KeyPressDown = (~LastKey) & CurrKey;  

  90.     KeyRelease = LastKey & (~CurrKey);  

  91.   

  92.     LastKey = CurrKey;

  93.         switch(KeyRelease)

  94.         {

  95.                 case 1:

  96.                          if(MODE == 2) MODE = 0;

  97.                          else MODE ++;

  98.                          break;

  99.                 case 2:

  100.                          if(MODE == 1) H_Increase() ;

  101.                          if(MODE == 2) M_Increase() ;

  102.                          break;

  103.                 case 4:

  104.                          SS = 0;

  105.                          break;

  106.                 default: break;

  107.         }

  108. }
  109. //Timer#include <reg52.h>
  110. typedef unsigned int UINT  ;
  111. typedef unsigned char UCHAR        ;
  112. UCHAR HH = 14;         //小时初始值
  113. UCHAR MM = 2;         //分钟初始值
  114. UCHAR SS = 55;         //秒初始值
  115. UINT u_10ms  = 0; //10ms计数
  116. bit T_CYCLE = 0;
  117. extern void key_Process(void);
  118. extern void S_Increase(void);

  119. void T0_Init(void)
  120. {
  121.         TMOD &= 0xf0;
  122.         TMOD |= 0x01;
  123.         //定时器赋初始值,定时时间为10ms。
  124.         TH0 = 0xd8;
  125.         TL0 = 0xf0;
  126.         TR0 = 1;
  127.         IE = 0x82;

  128. }

  129. void T0_INTSrv(void) interrupt 1
  130. {
  131.         //定时器重新开始计时。
  132.         TH0 = 0xd8;
  133.         TL0 = 0xf0;
  134.         u_10ms ++;
  135.         if (u_10ms%20==0)        // 200 ms
  136.         {
  137.                 T_CYCLE = !        T_CYCLE; //闪烁循环
  138.         }
  139.         if (u_10ms>99)        // 1000 ms = 1 second
  140.         {
  141.                 u_10ms = 0;
  142.                 S_Increase();
  143.         }
  144.         key_Process();        //SET按键处理
  145. }
复制代码




回复

使用道具 举报

ID:16255 发表于 2018-7-3 08:07 | 显示全部楼层
单片机直接扫描数码管可能出现字符闪烁,亮度不均匀的现象。可以用74HC595让数码管静态显示。
单片机直接中断计时可能出现走时不准,断电时间丢失的现象。可以用DS1302时钟芯片。
回复

使用道具 举报

ID:320226 发表于 2018-7-3 12:04 | 显示全部楼层
一个单片机做一个时钟诸存多得很还加二个74H太浪费了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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