• 售前

  • 售后

热门帖子
入门百科

51单片机入门——数字时钟

[复制链接]
一箫凝月黄 显示全部楼层 发表于 2022-1-16 12:44:51 |阅读模式 打印 上一主题 下一主题
文章目次



1. 前言

在此之前我们已经学习了单片机的定时器、停止、数码管。这篇文章重要陈诉怎样用上述的知识自己制作一个基于51单片机的数字时钟。
1.1. 计划要求

(1)主电路由秒信号发生器、“时、分、秒”计数器、译码器及表现器、校准电路等构成。
(2)秒信号发生器一样寻常用石英晶体振荡器加分频器实现。
(3)译码电路将时、分、秒计数器的输出状态送七段译码器译码,颠末六八位LED七段共阴表现器表现出来。
(4)校时电路用来对时、分、秒表现数字举行校对。
2. 硬件原理

2.1. 时钟信号(晶振)


单片机晶振部位电路,详情请参考《51单片机入门——单片机最小体系》,在此项目中我们选择 11.0592 MHz的晶振。
2.2. 按键开关


按键部分我们选择利用单片机的P3.0、P3.1、P3.2 三个 I/O 口 利用。
初版原理:按下开关K2“时”加一,按下开关K3“分”加一,按下开关K4“秒”加一。
终版原理:按下开关K3加一,按下开关K2控制按钮2的位移(比方:刚开始按K3无反应,按一下K2后秒加、再按分加),按下开关K4控制“时分秒”与“年代日”的切换。
2.3. 数码管表现

在仿真软件中我们选择利用两个4位共阴极数码管(赤色),现实电路中选择两个4位0.36英寸的赤色共阴极数码管。


3. 原理图

3.1. 仿真原理图


3.2. AD原理图


3.3. PCB图


4. 软件计划

4.1. 初版代码(无年代日)

  1. //该程序使用两个四位共阴数码管,10.0592Mhz晶振,STC89C52RC单片机,三个轻触开关
  2. #include<reg51.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. //单独控制某个引脚的电平不能直接写P3^0=1,必须先定义引脚
  6. sbit key0 = P3^0 ;                 
  7. sbit key1 = P3^2 ;
  8. sbit key2 = P3^3 ;
  9. uchar s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};           //共阴数码管0~9
  10. uchar a = 0 ,hour = 0 , min = 0 , sec = 0 ;                                          
  11. uchar b = 0 , c = 0 , d = 0;
  12. void time0_server_() interrupt 1      // interrupt  0表示外部中断0 , 1表示定时器中断0 , 2表示外部中断1 , 3表示定时器中断1 , 4表示串口中断
  13. {
  14.         TH0 = 0x4c ;
  15.         TL0 = 0x00 ;
  16.         a++;
  17.         if(a == 20)                                                //20 * 50 = 1000ms = 1s 即每隔1s“秒”加1
  18.         {
  19.                 a = 0 ;
  20.                 sec = sec + 1 ;
  21.         }
  22.         if(sec == 60)                                   //sec=60时清空,“分”加1
  23.         {
  24.                 min = min + 1 ;
  25.                 sec = 0 ;
  26.         }
  27.         if(min == 60)                                  //min=60时清空,“时”加1
  28.         {
  29.                 hour = hour + 1 ;
  30.                 min = 0 ;
  31.         }
  32.         if(hour == 24)                                 //hour=24时清空
  33.         {
  34.                 hour = 0 ;
  35.         }
  36. }
  37. void init_t0()
  38. {
  39.         TMOD = 0x01 ;           //采用16位定时器
  40.         TH0 = 0x4C ;           //50ms (65536-50000)/256
  41.         TL0 = 0x00 ;           //       (65536-50000)%256   
  42.         EA = 1 ;                   //开启定时器0的中断
  43.         ET0 = 1 ;          //开启总中断                  
  44.         TR0 = 1 ;                   //启动定时器0                  
  45. }
  46. void delay(uint n)                           //延时函数(运行空项目以达到延迟时间的效果)
  47. {
  48.         uint i,j;
  49.         for(i = 0 ; i < n ; i ++)
  50.         {
  51.                 for(j = 0 ; j < 120 ; j ++);
  52.         }       
  53. }
  54. void display1()                                                   //在数码管上显示
  55. {
  56.         uchar t0 = 0 ,t1 = 0 , t2 = 0 , t3 = 0 , t4 = 0 , t5 = 0 ;
  57.         t0 = hour / 10 ;                  //t0表示时针的十位
  58.         t1 = hour % 10 ;                  //t1表示时针的个位
  59.         t2 = min / 10 ;                          //t2表示分针的十位
  60.         t3 = min % 10 ;                          //t3表示分针的个位
  61.         t4 = sec / 10 ;                          //t4表示秒针的十位
  62.         t5 = sec % 10 ;                          //t5表示秒针的个位
  63.         P2 = 0x7f ;                                  //P2^7低电平         0111 1111         控制第一个数码管
  64.         P0 = s[t0] ;                          //用来显示“时”的十位
  65.         delay(1) ;                                  //延时大约1ms
  66.         P2 = 0xbf ;                                  //P2^6低电平         1011 1111         控制第二个数码管
  67.         P0 = s[t1] ;                          //用来显示“时”的个位
  68.         delay(1) ;
  69.         P2 = 0xdf ;                                  //P2^5低电平         1101 1111         控制第三个数码管
  70.         P0 = 0x40 ;                                  //显示“—”来分割“时”与“分”
  71.         delay(1) ;
  72.         P2 = 0xef ;                                  //P2^4低电平         1110 1111         控制第四个数码管
  73.         P0 = s[t2] ;                          //用来显示“分”的十位
  74.         delay(1) ;
  75.         P2 = 0xf7 ;                                  //P2^3低电平         1111 0111         控制第五个数码管
  76.         P0 = s[t3] ;                          //用来显示“分”的个位
  77.         delay(1) ;
  78.         P2 = 0xfb ;                                  //P2^2低电平         1111 1011         控制第六个数码管
  79.         P0 = 0x40 ;                                  //显示“—”来分割“分”与“秒”
  80.         delay(1) ;
  81.         P2 = 0xfd ;                                  //P2^1低电平         1111 1101         控制第七个数码管
  82.         P0 = s[t4] ;                          //用来显示“秒”的十位
  83.         delay(1) ;
  84.         P2 = 0xfe ;                                  //P2^0低电平         1111 1110         控制第八个数码管
  85.         P0 = s[t5] ;                          //用来显示“秒”的个位
  86.         delay(1) ;       
  87. }
  88. //开关控制(不是用的外部中断!!!!!)
  89. void KEY0()                                                        //开关0控制“时”加1
  90. {
  91.         if(key0 == 0 && c == 0)
  92.         {
  93.                 c = 1 ;
  94.         }
  95.         if(key0 == 1 && c == 1)
  96.         {
  97.                 c = 0 ;
  98.                 hour = hour + 1 ;
  99.         }
  100. }
  101. void KEY1()                                                 //开关1控制“分”加1
  102. {
  103.         if(key1 == 0 && d == 0)
  104.         {
  105.                 d = 1 ;
  106.         }
  107.         if(key1 == 1 && d == 1)
  108.         {
  109.                 d = 0 ;
  110.                 min = min + 1 ;
  111.         }
  112. }
  113. void KEY2()                                                 //开关2控制“秒”加1
  114. {
  115.         if(key2 == 0 && b == 0)
  116.         {
  117.                 b = 1 ;
  118.         }
  119.         if(key2 == 1 && b == 1)
  120.         {
  121.                 b = 0 ;
  122.                 sec = sec + 1 ;
  123.         }
  124. }
  125. void main()                                          //主函数
  126. {
  127.         init_t0();
  128.         while(1)
  129.         {
  130.                 KEY0();
  131.                 KEY1();
  132.                 KEY2();
  133.                 display1();
  134.         }       
  135. }
复制代码
4.2. 终版代码

[code]#include#define uchar unsigned char#define uint unsigned intsbit key1 = P3^0 ;sbit key0 = P3^1 ;                 sbit key2 = P3^2 ;sbit key3 = P3^3 ;uchar s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};           //共阴数码管0~9uchar hour = 10 , min = 10 , sec = 0 ,day = 25 , month = 1 , year = 20 ;                                           uchar a = 0 ,b = 0 , c = 0 , d = 0 , e = 0 ,f = 0 ;uchar b_1 = 0 ,c_1 = 0 ;                   void time0_server_() interrupt 1      {        TH0 = 0x4c ;        TL0 = 0x00 ;        a++;        e = 2000 + year ;        if(a == 20)                                                {                a = 0 ;                sec = sec + 1 ;        }        if(sec == 60)                                           {                min = min + 1 ;                sec = 0 ;        }         if(min == 60)                                         {                hour = hour + 1 ;                min = 0 ;        }        if(hour == 24)                                         {                day = day + 1 ;                hour = 0 ;                }        switch(month)                        //根据月份来控制天数        {                case 1:                 case 3:                case 5:                case 7:                case 8:                case 10:                case 12:if(day == 32)                                {                                        month = month + 1 ;                                        day = 1 ;                                }                                break ;                case 4:                case 6:                case 9:                case 11:if(day == 31)                                {                                        month =month + 1;                                        day = 1 ;                                }                                break ;                case 2:if(e%400==0||e%4==0&&e%100!=0)                            {                                         if(day == 30)                                        {                                                month = month + 1 ;                                                day = 1 ;                                                }                                }                                else if(day == 29)                                         {                                                 month = month + 1 ;                                                day = 1 ;                                                 }                                break ;        }        if(month == 13)        {                year = year + 1 ;                month = 1 ;        } }void init_t0(){        TMOD = 0x01 ;                   TH0 = 0x4C ;                   TL0 = 0x00 ;                     EA = 1 ;                           ET0 = 1 ;                                    TR0 = 1 ;                                     }void delay(uint n)         //延时函数        约莫1ms           {        uint i,j;        for(i = 0 ; i < n ; i ++)        {                for(j = 0 ; j < 120 ; j ++);        }        }void display1()                //表现 “时、分、秒”                                 {        uchar t0 = 0 ,t1 = 0 , t2 = 0 , t3 = 0 , t4 = 0 , t5 = 0 ;        t0 = hour / 10 ;                          t1 = hour % 10 ;                          t2 = min / 10 ;                        t3 = min % 10 ;                                  t4 = sec / 10 ;                                 t5 = sec % 10 ;/************* 74HC138译码器 辅助控制数码管 ******/                                  P2 = 0x1c ;        P0 = s[t0] ;        delay(2) ;        P2 = 0x18 ;        P0 = s[t1] ;        delay(2) ;        P2 = 0x14 ;        P0 = 0x40 ;        delay(2) ;        P2 = 0x10 ;        P0 = s[t2] ;        delay(2) ;        P2 = 0x0c ;        P0 = s[t3] ;        delay(2) ;        P2 = 0x08 ;        P0 = 0x40 ;        delay(2) ;        P2 = 0x04 ;        P0 = s[t4] ;        delay(2) ;        P2 = 0x00 ;        P0 = s[t5] ;        delay(2) ;/*********** P2直接控制数码管 *********///        P2 = 0x7f ;                                  //        P0 = s[t0] ;                //        delay(1) ;                        //        P2 = 0xbf ;                                  //        P0 = s[t1] ;                //        delay(1) ;//        P2 = 0xdf ;                        //        P0 = 0x40 ;                        //        delay(1) ;//        P2 = 0xef ;                        //        P0 = s[t2] ;                          //        delay(1) ;//        P2 = 0xf7 ;                                 //        P0 = s[t3] ;                        //        delay(1) ;//        P2 = 0xfb ;                                 //        P0 = 0x40 ;                                //        delay(1) ;//        P2 = 0xfd ;                                //        P0 = s[t4] ;                         //        delay(1) ;//        P2 = 0xfe ;                        //        P0 = s[t5] ;                //        delay(1) ;        }void display2()           //表现 “年、月、日”{        uchar t0 = 0 ,t1 = 0 , t2 = 0 , t3 = 0 , t4 = 0 , t5 = 0 ;        t0 = year / 10 ;                          t1 = year % 10 ;                          t2 = month / 10 ;                        t3 = month % 10 ;                                  t4 = day / 10 ;                                 t5 = day % 10 ;                P2 = 0x1c ;        P0 = s[t0] ;        delay(2) ;        P2 = 0x18 ;        P0 = s[t1] ;        delay(2) ;        P2 = 0x14 ;        P0 = 0x40 ;        delay(2) ;        P2 = 0x10 ;        P0 = s[t2] ;        delay(2) ;        P2 = 0x0c ;        P0 = s[t3] ;        delay(5) ;        P2 = 0x08 ;        P0 = 0x40 ;        delay(2) ;        P2 = 0x04 ;        P0 = s[t4] ;        delay(2) ;        P2 = 0x00 ;        P0 = s[t5] ;        delay(2) ;//        P2 = 0x7f ;                                  //        P0 = s[t0] ;                //        delay(1) ;                        //        P2 = 0xbf ;                                  //        P0 = s[t1] ;                //        delay(1) ;//        P2 = 0xdf ;                        //        P0 = 0x40 ;                        //        delay(1) ;//        P2 = 0xef ;                        //        P0 = s[t2] ;                          //        delay(1) ;//        P2 = 0xf7 ;                                 //        P0 = s[t3] ;                        //        delay(1) ;//        P2 = 0xfb ;                                 //        P0 = 0x40 ;                                //        delay(1) ;//        P2 = 0xfd ;                                //        P0 = s[t4] ;                         //        delay(1) ;//        P2 = 0xfe ;                        //        P0 = s[t5] ;                //        delay(1) ;                                }void KEY0()                //控制按钮2的位移{        if(key0 == 0 && c == 0)        {                c = 1 ;        }        if(key0 == 1 && c == 1)        {                c = 0 ;                c_1 = c_1 + 1 ;        }        if(c_1 == 4)        {                c_1 = 0 ;        }}void KEY1()                  //控制 "秒"、“分”、“时”、“天”、“月”、“年”        的加1{        switch(c_1)        {                case 1: if(b_1 == 0)                                {                                         if(key1 == 0 && d == 0)                                        {                                                d = 1 ;                                        }                                        if(key1 == 1 && d == 1)                                        {                                                d = 0 ;                                                sec = sec + 1 ;                                        }                                }                                else if(b_1 == 1)                                {                                        if(key1 == 0 && d == 0)                                        {                                                d = 1 ;                                        }                                        if(key1 == 1 && d == 1)                                        {                                                d = 0 ;                                                day = day + 1 ;                                        }                                        }                                break ;                case 2: if(b_1 == 0)                                {                                        if(key1 == 0 && d == 0)                                        {                                                d = 1 ;                                        }                                        if(key1 == 1 && d == 1)                                        {                                                d = 0 ;                                                min = min + 1 ;                                        }                                }                                else if(b_1 == 1)                                {                                        if(key1 == 0 && d == 0)                                        {                                                d = 1 ;                                        }                                        if(key1 == 1 && d == 1)                                        {                                                d = 0 ;                                                month = month + 1 ;                                        }                                }                                break ;                case 3: if(b_1 == 0)                                {                                        if(key1 == 0 && d == 0)                                        {                                                d = 1 ;                                        }                                        if(key1 == 1 && d == 1)                                        {                                                d = 0 ;                                                hour = hour + 1 ;                                        }                                }                                else if(b_1 == 1)                                {                                        if(key1 == 0 && d == 0)                                        {                                                d = 1 ;                                        }                                        if(key1 == 1 && d == 1)                                        {                                                d = 0 ;                                                year = year + 1 ;                                        }                                }                                break ;        }}void KEY2()                  //控制 "秒"、“分”、“时”、“天”、“月”、“年”        的减1{        switch(c_1)        {                case 1: if(b_1 == 0)                                {                                         if(key2 == 0 && f == 0)                                        {                                                f = 1 ;                                        }                                        if(key2 == 1 && f == 1)                                        {                                                f = 0 ;                                                sec = sec - 1 ;                                                        if(sec == 255)                                                {                                                        sec = 59 ;                                                }                                        }                                }                                else if(b_1 == 1)                                {                                        if(key2 == 0 && f == 0)                                        {                                                f = 1 ;                                        }                                        if(key2 == 1 && f == 1)                                        {                                                f = 0 ;                                                day = day - 1 ;                                                if(day

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作