找回密码
 立即注册

QQ登录

只需一步,快速开始

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

我的单片机电子时钟设计 含源码,仿真原理图

[复制链接]
跳转到指定楼层
楼主
这是我上个月所做的单片机电子时钟仿真设计
keil4和proteus8进行模拟仿真
都是自己原创的请大家多多指教,批评指正!

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include <reg52.h>
  2. #include "main.h"

  3. #include "seg.h"
  4. #include "ds1302.h"

  5. sbit KEY0 = P3^4;
  6. sbit KEY1 = P3^5;
  7. sbit KEY2 = P3^6;
  8. sbit KEY3 = P3^7;

  9. //按键是否按下的标志位,按下为1,没按下为0
  10. bit  isKey0 = 0; //修改
  11. bit  isKey1 = 0; //增加---修改显示
  12. bit  isKey2 = 0; //减少
  13. bit  isKey3 = 0; //确认

  14. //0 正常显示状态  1 修改时间状态
  15. bit  changeOrNormalState = 0;
  16. //显示模式 0 显示正常时分秒  1 显示正常年月日  2 显示修改时间下的时分秒  3显示修改时间下的年月日
  17. u8   showMode = 0;
  18. //正在修改的变量 0 秒 1 分 2 时 3 日 4 月 5 年
  19. u8   changeCount = 0;

  20. void Timer0Init(void);
  21. void segBuffChange(void);
  22. void ClockChangeFunction(void);
  23. void dataAdd(void);
  24. void dataSub(void);
  25. void DataTempGet(void);

  26. void main()
  27. {
  28.         ds1302init();
  29.         Timer0Init();
  30.         while(1)
  31.         {
  32.                 ds1302readtime();
  33.                 ClockChangeFunction();
  34.         }
  35. }

  36. /**
  37.   * @name    SegBuffChange
  38.   * @brief   根据显示状态变量,修改现在的显示变量
  39.   * @param   : [输入/出]
  40.   * @retval  返回值
  41.   */
  42. void SegBuffChange()
  43. {
  44.         if(showMode == 0)
  45.         {
  46.                 segBuff[5] = second%10;
  47.                 segBuff[4] = second/10;
  48.                 segBuff[3] = minute%10;
  49.                 segBuff[2] = minute/10;
  50.                 segBuff[1] = hour%10;
  51.                 segBuff[0] = hour/10;
  52.         }else if(showMode == 1)
  53.         {
  54.                 segBuff[5] = day%10;
  55.                 segBuff[4] = day/10;
  56.                 segBuff[3] = month%10;
  57.                 segBuff[2] = month/10;
  58.                 segBuff[1] = year%10;
  59.                 segBuff[0] = year/10;
  60.         }else if(showMode == 2)
  61.         {
  62.                 segBuff[5] = secondTemp%10;
  63.                 segBuff[4] = secondTemp/10;
  64.                 segBuff[3] = minuteTemp%10;
  65.                 segBuff[2] = minuteTemp/10;
  66.                 segBuff[1] = hourTemp%10;
  67.                 segBuff[0] = hourTemp/10;
  68.         }else if(showMode == 3)
  69.         {
  70.                 segBuff[5] = dayTemp%10;
  71.                 segBuff[4] = dayTemp/10;
  72.                 segBuff[3] = monthTemp%10;
  73.                 segBuff[2] = monthTemp/10;
  74.                 segBuff[1] = yearTemp%10;
  75.                 segBuff[0] = yearTemp/10;
  76.         }
  77. }

  78. /**
  79.   * @name    KeyScan
  80.   * @brief   按键按下时,各个状态值变1
  81.   * @param   mode: 1 连续 0 不连续
  82.   * @retval  返回值
  83.   */
  84. void KeyScan(u8 mode)
  85. {
  86.     static int keyCount = 0;
  87.     static int keyState = 0;
  88.     if(mode == 1) keyState=0;
  89.     if (keyState == 0 && (KEY0 == 0||KEY1 == 0||KEY2 == 0||KEY3 == 0))
  90.     {
  91.         keyCount++;
  92.         if(keyCount>2)
  93.         {
  94.             keyState = 1;
  95.             keyCount=0;
  96.             if(KEY0 == 0) isKey0 = 1;
  97.             else if(KEY1 == 0) isKey1 = 1;
  98.                         else if(KEY2 == 0) isKey2 = 1;
  99.                         else if(KEY3 == 0) isKey3 = 1;
  100.         }
  101.     } else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && KEY3 == 1)
  102.     {
  103.         keyState = 0;
  104.     }
  105. }

  106. /**
  107.   * @name    ClockChangeFunction
  108.   * @brief   按键按下后的执行函数
  109.   * @param   : [输入/出]
  110.   * @retval  返回值
  111.   */
  112. void ClockChangeFunction()
  113. {
  114.         if(isKey0 == 1)
  115.         {
  116.                 isKey0 = 0;
  117.                 if(changeCount == 0 && changeOrNormalState == 0)//修改的位选为0,即为秒,同时显示状态为正常显示状态下
  118.                 {
  119.                         changeOrNormalState = 1;//显示状态改为修改时间模式
  120.                         DataTempGet();//获取修改前的时间变量值
  121.                         showMode = 2;//显示模式为显示修改时间下的时分秒
  122.                 }else if(changeOrNormalState == 1)//假如为显示模式
  123.                 {
  124.                         changeCount++;//按键按下位次++
  125.                         if(changeCount > 5)
  126.                                 changeCount = 0;
  127.                         if(changeCount > 2)//时分秒是0、1、2,大于2就要换成年月日显示
  128.                                 showMode = 3;//显示模式为显示修改时间下的年月日
  129.                         else
  130.                                 showMode = 2;
  131.                 }
  132.         }else if(isKey1 == 1)
  133.         {
  134.                 isKey1 = 0;
  135.                 if(changeOrNormalState == 1)//显示状态为修改时间模式
  136.                 {
  137.                         dataAdd();//对应位次时间变量增加
  138.                 }else //正常显示模式
  139.                 {
  140.                         if(showMode == 0)//切换时间和日期的显示
  141.                                 showMode = 1;
  142.                         else if(showMode == 1)
  143.                                 showMode = 0;
  144.                 }
  145.         }else if(isKey2 == 1)
  146.         {
  147.                 isKey2 = 0;
  148.                 if(changeOrNormalState == 1)//和增加一样
  149.                 {
  150.                         dataSub();
  151.                 }
  152.         }else if(isKey3 == 1)
  153.         {
  154.                 isKey3 = 0;
  155.                 if(changeOrNormalState == 1)//在修改模式下按下
  156.                 {
  157.                         changeOrNormalState = 0;//变为正常显示模式
  158.                         ds1302writetime();//写入修改后的时间
  159.                         showMode = 0;//显示模式为时分秒
  160.                         changeCount = 0;//修改位次归零
  161.                 }
  162.         }
  163. }

  164. /**
  165.   * @name    DataTempGet
  166.   * @brief   修改按键按下后,将现在的时间,放入temp中
  167.   * @param   : [输入/出]
  168.   * @retval  返回值
  169.   */
  170. void DataTempGet()
  171. {
  172.         secondTemp = second;
  173.         minuteTemp = minute;
  174.         hourTemp   = hour;
  175.         dayTemp    = day;
  176.         monthTemp  = month;
  177.         weekTemp   = week;
  178.         yearTemp   = year;
  179. }

  180. /**
  181.   * @name    dataAdd
  182.   * @brief   增加按键按下后,时间变量的变化方式,主要是有个平闰年的处理,其他都比较正常
  183.   * @param   : [输入/出]
  184.   * @retval  返回值
  185.   */
  186. void dataAdd()
  187. {
  188.         if(changeCount == 0)
  189.         {
  190.                 secondTemp ++;
  191.                 if(secondTemp > 59)
  192.                         secondTemp = 0;
  193.         }else if(changeCount == 1)
  194.         {
  195.                 minuteTemp ++;
  196.                 if(minuteTemp > 59)
  197.                         minuteTemp = 0;
  198.         }else if(changeCount == 2)
  199.         {
  200.                 hourTemp ++;
  201.                 if(hourTemp > 23)
  202.                         hourTemp = 0;
  203.         }else if(changeCount == 3)
  204.         {
  205.                 dayTemp ++;
  206.                 if(monthTemp == 1 || monthTemp == 3 || monthTemp == 5 || monthTemp == 7 || monthTemp == 8 || monthTemp == 10 || monthTemp == 12)
  207.                 {
  208.                         if(dayTemp > 31)
  209.                                 dayTemp = 1;
  210.                 }else if(monthTemp == 3 || monthTemp == 6 || monthTemp == 9 || monthTemp == 11)
  211.                 {
  212.                         if(dayTemp > 30)
  213.                                 dayTemp = 1;
  214.                 }else if(monthTemp == 2)
  215.                 {
  216.                         if((2000+year)%400==0)
  217.                         {
  218.                                 if(dayTemp > 29)
  219.                                         dayTemp = 1;
  220.                         }
  221.                         else
  222.                         {
  223.                                 if((2000+year)%4==0&&(2000+year)%100!=0)
  224.                                 {
  225.                                         if(dayTemp > 29)
  226.                                                 dayTemp = 1;
  227.                                 }else
  228.                                 {
  229.                                         if(dayTemp > 28)
  230.                                                 dayTemp = 1;
  231.                                 }
  232.                         }
  233.                 }
  234.         }else if(changeCount == 4)
  235.         {
  236.                 monthTemp ++;
  237.                 if(monthTemp > 12)
  238.                         monthTemp = 1;
  239.         }else if(changeCount == 5)
  240.         {
  241.                 yearTemp ++;
  242.                 if(yearTemp > 99)
  243.                         yearTemp = 0;
  244.         }
  245. }

  246. /**
  247.   * @name    dataSub
  248.   * @brief   减少按键按下后,时间变量的变化方式
  249.   * @param   : [输入/出]
  250.   * @retval  返回值
  251.   */
  252. void dataSub()
  253. {
  254.         if(changeCount == 0)
  255.         {
  256.                 secondTemp --;
  257.                 if((char)secondTemp < 0)
  258.                         secondTemp = 59;
  259.         }else if(changeCount == 1)
  260.         {
  261.                 minuteTemp --;
  262.                 if((char)minuteTemp < 0)
  263.                         minuteTemp = 59;
  264.         }else if(changeCount == 2)
  265.         {
  266.                 hourTemp --;
  267.                 if((char)hourTemp < 0)
  268.                         hourTemp = 23;
  269.         }else if(changeCount == 3)
  270.         {
  271.                 dayTemp --;
  272.                 if(monthTemp == 1 || monthTemp == 3 || monthTemp == 5 || monthTemp == 7 || monthTemp == 8 || monthTemp == 10 || monthTemp == 12)
  273.                 {
  274.                         if(dayTemp < 1)
  275.                                 dayTemp = 31;
  276.                 }else if(monthTemp == 3 || monthTemp == 6 || monthTemp == 9 || monthTemp == 11)
  277.                 {
  278.                         if(dayTemp < 1)
  279.                                 dayTemp = 30;
  280.                 }else if(monthTemp == 2)
  281.                 {
  282.                         if((2000+year)%400==0)
  283.                         {
  284.                                 if(dayTemp < 1)
  285.                                         dayTemp = 29;
  286.                         }
  287.                         else
  288.                         {
  289.                                 if((2000+year)%4==0&&(2000+year)%100!=0)
  290.                                 {
  291.                                         if(dayTemp < 1)
  292.                                                 dayTemp = 29;
  293.                                 }else
  294.                                 {
  295.                                         if(dayTemp < 1)
  296.                                                 dayTemp = 28;
  297.                                 }
  298.                         }
  299.                        
  300.                 }
  301.         }else if(changeCount == 4)
  302.         {
  303.                 monthTemp --;
  304.                 if(monthTemp < 1)
  305.                         monthTemp = 12;
  306.         }else if(changeCount == 5)
  307.         {
  308.                 yearTemp --;
  309.                 if((char)yearTemp < 0)
  310.                         yearTemp = 99;
  311.         }
  312. }

  313. /**
  314.   * @name    dataBlink
  315.   * @brief   修改时间模式下,选中的时间变量闪烁
  316.   * @param   : [输入/出]
  317.   * @retval  返回值
  318.   */
  319. void dataBlink()
  320. {
  321.         static u8  blinkCount = 0;
  322. ……………………

  323. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

Keil代码与Proteus8.9仿真下载:
1、基于51单片机的电子时钟设计.zip (221.99 KB, 下载次数: 35)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:529213 发表于 2023-3-10 23:05 来自手机 | 只看该作者
楼主大神级别,做得非常漂亮,厉害了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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