找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机电子时钟,能显示时间,星期,日期 带PCB文件

[复制链接]
跳转到指定楼层
楼主

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


全部资料下载地址:
时钟电路图及PCB工程.zip (6.91 MB, 下载次数: 106)

单片机源代码为
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. sbit lcdrs=P2^4;
  6. sbit lcdrw=P2^5;
  7. sbit lcden=P2^6;
  8. sbit key1=P2^2;
  9. sbit key2=P2^1;
  10. sbit key3=P2^0;
  11. sbit FM=P1^0;


  12. uchar counter,cycle;
  13. uchar key_counter = 0;  //定义光标闪烁以及修改操作数的标记
  14. uchar second0,second1,minute0,minute1,hour0,hour1;
  15. uchar table[][3]={"SUN","MON","TUE","WEN","THU","FRI","SAT"};
  16. uchar year[4],day[2],month[2],date; //日期变量
  17. uchar small_mon,leap_year;
  18. uchar k;


  19. void state() //检查日期状态函数(即判断是否闰年,是否小月的函数)
  20. {
  21.   switch(month[0])     //2,4,6,9,11月是小月
  22.      {
  23.        case 1:
  24.            if(month[1] == 1) //若是11月,则是小月
  25.           small_mon = 1;
  26.        else              //若是1月,则不是小月
  27.        small_mon = 0; break;
  28.            case 2:
  29.        case 4:
  30.        case 6:
  31.        case 9: small_mon = 1; break;
  32.        default:small_mon = 0;break;
  33.      }
  34.          
  35.          k=year[3]*1000+year[2]*100+year[1]*10+year[0];
  36.          if(k%4==0&&k%100!=0||k%400==0)
  37.          leap_year=1;
  38.          else
  39.          leap_year=0;
  40. }


  41. void Dater() //日期函数
  42. {
  43.   state();        
  44.   day[0]++;
  45.   date=(date+1)%7;

  46.   switch(day[0])    //日变化
  47.     {
  48.       case 10:
  49.        {
  50.          if(day[1] == 2 && month[0] == 2 && month[1] == 0) //20日的个位能到10,说明是闰年,把2月30号转变为3月1号
  51.            {
  52.              day[0] = 1;
  53.              day[1] = 0;
  54.              month[0]++;
  55.             }
  56.          else  //日期个位满10进1
  57.             {
  58.               day[0] = 0;
  59.               day[1]++;
  60.             }
  61.        }  break;
  62.       case 1:
  63.        {
  64.          if(day[1] == 3 && small_mon) //小月31号时把日期置为1号,月份+1
  65.            {
  66.              day[0] = 1;
  67.              day[1] = 0;
  68.              month[0]++;
  69.            }
  70.        } break;
  71.       case 2:
  72.        {
  73.          if(day[1] == 3)
  74.            {
  75.              day[0] = 1;
  76.              day[1] = 0;
  77.              month[0]++;
  78.            }
  79.         }break;
  80.        case 9:
  81.         {
  82.          if(day[1] == 2 && !leap_year && month[0] == 2 && month[1] == 0)  //平年时,把2月29号变为3月1号
  83.            {
  84.              day[0] = 1;
  85.              day[1] = 0;
  86.              month[0]++;
  87.            }
  88.         } break;
  89.        default: break;
  90.      }


  91.   switch(month[0])   //月变化
  92.     {
  93.       case 10:           //个位逢10进1
  94.        {
  95.          month[0] = 0;
  96.          month[1]++;
  97.        } break;
  98.       case 3:     //当十位是1,个位逢3则年进1
  99.        {
  100.          if(month[1] == 1)
  101.            {
  102.              month[0] = 1;
  103.              month[1] = 0;
  104.              year[0]++;
  105.            }
  106.        } break;
  107.     }


  108.   if(year[0] > 9)     //相应年变化
  109.     {
  110.       year[0] = 0;
  111.       year[1]++;
  112.       if(year[1] > 9)
  113.         {
  114.           year[1] = 0;
  115.           year[2]++;
  116.           if(year[2] > 9)
  117.             {
  118.               year[2] = 0;
  119.               year[3]++;
  120.               if(year[3] > 9)
  121.               year[3] = 0;
  122.             }
  123.          }
  124.       }
  125. }



  126. void clock() //时钟函数
  127. {
  128.   second0++;
  129.   if(second0 > 9)
  130.     {
  131.       second0 = 0;
  132.       second1++;
  133.       if(second1 > 5)
  134.         {
  135.           second1 = 0;
  136.           minute0++;
  137.           if(minute0 > 9)
  138.             {
  139.               minute0 = 0;
  140.               minute1++;
  141.               if(minute1 > 5)
  142.                 {
  143.                   minute1 = 0;
  144.                   hour0++;
  145.                   if(hour0 == 4 && hour1 == 2)
  146.                     {
  147.                       hour0 = hour1 = 0;
  148.                       Dater();
  149.                      }
  150.                   else if(hour0 > 9)
  151.                          {
  152.                            hour0 = 0;
  153.                            hour1++;
  154.                          }
  155.                  }
  156.              }
  157.         }
  158.      }
  159. }



  160. void delay(uint z) //延时函数ms
  161. {
  162.   uint x,y;
  163.   for(x = z;x > 0;x--)
  164.   for(y = 110;y > 0;y--) ;
  165. }

  166. void write_com(uchar com) //写指令到LCD液晶显示
  167. {
  168.   lcdrs = 0;  //选择指令寄存器
  169.   lcdrw = 0;  //选择写
  170.   P0 = com;   //把命令字送入P0口
  171.   delay(1);   //延时,让1602准备接收数据
  172.   lcden = 1;  //使能线电平变化,命令送入1602的8位数据口

  173.   delay(1);   //等待接收
  174.   lcden = 0;
  175. }

  176. void write_data(uchar data0) //写数据到LCD液晶显示
  177. {
  178.   lcdrs = 1;   //选择数据寄存器
  179.   lcdrw = 0;   //选择写
  180.   P0 = data0;  //把数据送入P0口
  181.   delay(1);    //延时,让1602准备接收数据
  182.   lcden = 1;   //使能线电平变化,数据送入8位数据口

  183.   delay(1);  //等待接收
  184.   lcden = 0;
  185. }

  186. void disp_time() //显示时间
  187. {
  188.   write_com(0xc4);  //设定显示地址为下排第5位

  189.   write_data(hour1 + 0x30);  //小时
  190.   write_data(hour0 + 0x30);
  191.   write_data(0x3a);   //显示冒号

  192.   write_data(minute1 + 0x30);  //分钟
  193.   write_data(minute0 + 0x30);
  194.   write_data(0x3a);   //冒号

  195.   write_data(second1 + 0x30);//秒
  196.   write_data(second0 + 0x30);

  197.   if(key_counter != 0 )   //按功能键key1次数不为0
  198.     {
  199.       switch(key_counter)
  200.         {
  201.           case 1:
  202.            write_com(0x80+0x4b); //定位回光标闪烁位置,第二行第12位
  203.            break;
  204.           case 2:
  205.            write_com(0x80+0x48); //第二行第9位
  206.            break;
  207.           case 3:
  208.            write_com(0x80+0x45); //第二行第6位
  209.            break;
  210.           case 4:
  211.            write_com(0x80+0x0e); //第一行第15位
  212.            break;
  213.           case 5:
  214.            write_com(0x80+0x0b); //第一行第12位
  215.            break;
  216.           case 6:
  217.            write_com(0x80+0x08);  //第一行第9位
  218.            break;
  219.           case 7:
  220.            write_com(0x80+0x03);  //第一行第4位
  221.            break;
  222.          }
  223.        write_com(0x0f);  //关光标
  224.        delay(150);
  225.     }
  226. }

  227. void disp_date() //显示日期
  228. {
  229.   write_com(0x81);   //定义回第一行第2位

  230.   for(cycle = 0; cycle < 3;cycle++)// 显示星期
  231.      write_data(table[date][cycle]);

  232.   write_data(0x20);   //显示空格

  233.   for(cycle = 0;cycle < 4;cycle++)  //显示年
  234.      write_data(year[3 - cycle]+0x30);

  235.   write_data(0x2d); //显示'/'

  236.   write_data(month[1]+0x30); //显示月
  237.   write_data(month[0]+0x30);

  238.   write_data(0x2d);  //显示'/'

  239.   write_data(day[1]+0x30);  //显示日
  240.   write_data(day[0]+0x30);
  241. }
  242. void di()            //蜂鸣器发声函数
  243. {
  244.      FM=0;
  245.          delay(100);
  246.          FM=1;
  247. }

  248. void setting_detect()  //按键扫描函数
  249. {

  250.   if(key1==0)
  251.     {
  252.      delay(5);
  253.      if(key1==0) //消除抖动
  254.        {
  255.         while(!key1); //等待松手
  256.         TR0=0;                            //TRO==0
  257.         di();   //蜂鸣器滴
  258.         key_counter++;  //功能键按下次数加一
  259.         do
  260.          {
  261.           disp_date();   //显示星期+日期
  262.           disp_time();   //显示时间
  263.           if(key1==0) //按键“切换”
  264.             {
  265.              delay(5);
  266.              if(key1==0)
  267.                {
  268.                 while(!key1);
  269.                                 di();
  270.                 key_counter++;
  271.                }
  272.             }

  273.            if(key2==0) //按键“加”
  274.              {
  275.               delay(5);
  276.               if(key2==0)
  277.                 {
  278.                  while(!key2);
  279.                  di();
  280.                  switch(key_counter)  //判断功能键按下次数
  281.                    {
  282.                     case 1:     //一次则秒加一
  283.                       second0++;
  284.                       if(second0 > 9)
  285.                        {
  286.                         second0 = 0;
  287.                         second1++;
  288.                         if(second1 == 6)
  289.                           second1 = 0;
  290.                        } break;

  291.                     case 2:      //两次则分加一
  292.                       minute0++;
  293.                       if(minute0 > 9)
  294.                         {
  295.                          minute0 = 0;
  296.                          minute1++;
  297.                          if(minute1 == 6)
  298.                            minute1 = 0;
  299.                         } break;

  300.                     case 3:   //三次则时加一
  301.                       hour0++;
  302.                       if(hour1 == 2 && hour0 > 3)
  303.                         {
  304.                          hour0 = 0;
  305.                          hour1 = 0;
  306.                         }
  307.                       else if(hour0 > 9)
  308.                              {
  309.                               hour0 = 0;
  310.                               hour1++;
  311.                               }
  312.                       break;

  313.                      case 4:   //四次则日加一
  314.                        day[0]++;
  315.                        if(day[0] == 2 && day[1] == 3)
  316.                          {
  317.                           day[0] = 1;
  318.                           day[1] = 0;
  319.                          }
  320.                        if(day[0] == 10)
  321.                          {
  322.                           day[0] = 0;
  323.                           day[1]++;
  324.                          }
  325.                         break;

  326.                      case 5:    //五次则月加一
  327.                        month[0]++;
  328.                        if(month[0] == 3 && month[1] == 1)
  329.                          {
  330.                           month[0] = 1;
  331.                           month[1] = 0;
  332.                          }
  333.                        if(month[0] == 10)
  334.                          {
  335.                           month[0] = 0;
  336.                           month[1] = 1;
  337.                          }
  338.                          break;

  339.                       case 6:    //六次则年加一
  340.                        year[0]++;
  341.                        if(year[0] > 9)
  342.                          {
  343.                           year[0] = 0;
  344.                           year[1]++;
  345.                           if(year[1] > 9)
  346.                             {
  347.                              year[1] = 0;
  348.                              year[2]++;
  349.                              if(year[2] > 9)
  350.                                {
  351.                                 year[2] = 0;
  352.                                 year[3]++;
  353.                                 if(year[3] > 9)
  354.                                   year[3] = 0;
  355.                                 }
  356.                              }
  357.                            }
  358.                            break;

  359.                        case 7:  //七次则星期加一
  360.                          date=(date+1)%7;
  361.                         break;
  362.           }
  363.       }
  364. }
  365.           if(key3==0) //按键“减”
  366.             {
  367.              delay(5);
  368.              if(key3==0)
  369.                {
  370.                 while(!key3);
  371.                 di();
  372.                 switch(key_counter)
  373.                   {
  374.                     case 1:
  375.                       if(second0 == 0)
  376.                         {
  377.                          second0 = 9;
  378.                          if(second1 == 0)
  379.                             second1 = 5;
  380.                          else
  381.                             second1--;
  382.                          }
  383.                        else
  384.                          second0--;
  385.                        break;

  386.                      case 2:
  387.                        if(minute0 == 0)
  388.                          {
  389.                           minute0 = 9;
  390.                           if(minute1 == 0)
  391.                              minute1 = 5;
  392.                           else
  393.                              minute1--;
  394.                           }
  395.                         else
  396.                           minute0--;
  397.                         break;

  398.                       case 3:
  399.                          if(hour0 == 0)
  400.                            {
  401.                             if(hour1 == 0)
  402.                               {
  403.                                hour0 = 3;
  404.                                hour1 = 2;
  405.                               }
  406.                             else
  407.                               {
  408.                                hour0 = 9;
  409.                                hour1--;
  410.                               }
  411.                             }
  412.                           else
  413.                             hour0--;
  414.                           break;

  415.                        case 4:
  416.                          if(day[0] == 1 && day[1] == 0)
  417.                             day[1] = 3;
  418.                          if(day[0] == 0)
  419.                            {
  420.                             day[0] = 9;
  421.                             day[1]--;
  422.                            }
  423.                           else
  424.                            day[0]--;
  425.                           break;

  426.                        case 5:
  427.                          if(month[0] == 1 && month[1] == 0)
  428.                            {
  429.                              month[0] = 2;
  430.                              month[1] = 1;
  431.                            }
  432.                          else if(month[0] == 0)
  433.                                 {
  434.                                  month[0] = 9;
  435.                                  month[1]--;
  436.                                 }
  437.                               else
  438.                                  month[0]--;
  439.                                 break;

  440.                    case 6:
  441.                      if(year[0] == 0)
  442.                        {
  443.                         year[0] = 9;
  444.                         if(year[1] == 0)
  445.                            {
  446.                              year[1] = 9;
  447.                              if(year[2] == 0)
  448.                                {
  449.                                 year[2] = 9;
  450.                                 if(year[3] == 0)
  451.                                   year[3] = 9;
  452.                                 else
  453.                                  year[3]--;
  454.                                 }
  455.                              else
  456.                                year[2]--;
  457.                            }
  458.                          else
  459.                            year[1]--;
  460.                         }
  461.                       else
  462.                        year[0]--;
  463.                      break;

  464.                  case 7:
  465.                  date=(date+6)%7;
  466.                  break;
  467.              }
  468.            }
  469.          }
  470.         }
  471.     while(key_counter != 8);
  472.          key_counter = 0; //退出设置时关掉光标显示
  473.          TR0=1;
  474.      }
  475.   }
  476. }

  477. void Lcd_init()       //显示屏初始化
  478. {
  479.    lcden = 0;
  480.    write_com(0x01);   //清屏
  481.    write_com(0x02);   //位置复位为左上方
  482.    write_com(0x06); //光标右移
  483.    write_com(0x0e); //显示开,有光标,闪烁
  484.    write_com(0x38);  //两行,每行16字符,5*7点阵
  485. }

  486. void timer0() interrupt 1 //定时器
  487. {
  488.    TH0 = (65536-39970)/256;
  489.    TL0 = (65536-39970)%6;
  490.    counter++;
  491.    if(counter == 25)
  492.      {
  493.       counter = 0;
  494.       clock();
  495.      }
  496. }

  497. void Timer_init() //定时器初始化
  498. {
  499.    TMOD = 0x01;
  500.    TH0 = (65536-29995)/256;
  501.    TL0 = (65536-29995)%6;
  502.    EA = 1;
  503.    ET0 = 1;
  504.    TR0 = 1;
  505. }   

  506. void Date_init() //日期初始化
  507. {
  508.    date = 4;

  509.    day[0] = 0;
  510.    day[1] = 2;

  511.    month[0] = 4;
  512.    month[1] = 0;

  513.    year[0] = 7;
  514.    year[1] = 1;
  515.    year[2] = 0;
  516.    year[3] = 2;
  517. }

  518. void Time_init() //时间初始化
  519. {
  520.         second0 = 0;
  521.         second1 = 3;
  522.         
  523.         minute0 = 0;
  524.         minute1 = 3;
  525.         
  526.         hour0 = 2;
  527.         hour1 = 1;
  528.         
  529.         counter = 0;
  530. }

  531. void main() //主函数
  532. {
  533.         Lcd_init();
  534.         Time_init();
  535.         Date_init();
  536.         Timer_init();
  537.         while(1)
  538.         {
  539.                 disp_date();
  540.                 disp_time();
  541.                 setting_detect();
  542.         }
  543. }
复制代码


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

使用道具 举报

沙发
ID:360045 发表于 2018-6-27 10:34 | 只看该作者
大神,厉害啊
回复

使用道具 举报

板凳
ID:452039 发表于 2018-12-22 12:31 | 只看该作者
xiexiedashen
回复

使用道具 举报

地板
ID:452539 发表于 2018-12-23 12:12 | 只看该作者
学习的好资料,我想下载一个
回复

使用道具 举报

5#
ID:677980 发表于 2019-12-30 22:56 | 只看该作者
可以,不过不知道有没有串口
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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