找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机实训做的多功能电子时钟用(数码管显示)有proteus仿真

[复制链接]
跳转到指定楼层
楼主
51单片机实训做到的多功能电子时钟用数码管显示的
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. /*
  2. ************************************ (C) COPYRIGHT 2017 Sourcelink **************************************
  3. * File Name        : main.c
  4. * Author                : Sourcelink
  5. * Version                : V1.0
  6. * Date                 : 2017/3/3
  7. * Description        : 2017/3/3: 完成切换功能和设置功能;
  8. *                                  2017/3/4: 完成设置闪烁和点码闪烁功能,星期计算功能;
  9. *                                                        防真发现闪烁时快时慢,初步判断为proteus仿真问题。因为程序中没有阻塞。
  10. *                                                        完成數字鍵設置時間的功能。
  11. *                                                        添加退出功能,在不想設置或切換時可以直接退出。
  12. ********************************************************************************************************
  13. */

  14. #include <reg52.H>
  15. #include "main.h"
  16. #include "Led_8Seg.h"
  17. #include "Key.h"
  18. #include "DS1302.h"


  19. typedef  void (*dispaly_callback)(RealTimeTypeDef*);


  20. /************************************************************************************************/

  21. static void display_hour(RealTimeTypeDef *_RealTime);
  22. static void display_year(RealTimeTypeDef *_RealTime);
  23. static void display_month(RealTimeTypeDef *_RealTime);
  24. static void display_day(RealTimeTypeDef *_RealTime);
  25. static void undisplay(unsigned char time_state);

  26. void display_switch(dispaly_callback display, RealTimeTypeDef *time, unsigned char next_state);
  27. void display_set(dispaly_callback display, unsigned char next_state);


  28. void calculation_week(RealTimeTypeDef *_RealTime);

  29. void display_switch_state(void);
  30. void inc_dec_time_handle(unsigned char *val, unsigned char keyval, unsigned char state);
  31. void num_time_handle(unsigned char *val, unsigned char keyval, unsigned char state);
  32. void is_exit(void);




  33. /************************************************************************************************/



  34. unsigned char globa_state  = STATE_STATIC;                        /* 全局三个状态,静态显示时间,切换显示状态,设置时间状态 */
  35. unsigned char switch_state = SWITCH_YEAR;                        
  36. unsigned char set_state    = SET_HOUR;

  37. unsigned char display_twinkle = 0;                                        /* 500ms 的闪烁信号 */
  38. unsigned char display_step = DISPLAY;                                /* 闪烁状态 二值 */
  39. unsigned char num_bit = num_bitl;
  40. unsigned char key_continuit = 0;                                        /* key连按信号 */
  41. RealTimeTypeDef        tmp_real_time;                                                /* 实时时间的中间变量 */


  42. /************************************************************************************************/

  43. void Delay_ms(unsigned int Cnt)
  44. {
  45.         unsigned int t;
  46.         while(Cnt--)
  47.         {
  48.                 t = 100;
  49.                 while(--t);
  50.         }
  51. }

  52. void SystemInit()
  53. {
  54.         TMOD = 0x01;
  55.         TH0 = (65536-2000)/256;
  56.         TL0 = (65536-2000)%256;
  57.         ET0 = 1;
  58.         EA  = 1;
  59.         TR0 = 1;
  60. }

  61. /************************************************************************************************/




  62. void main()
  63. {
  64.         SystemInit();
  65.         DS1302_Init();
  66.         RealTime.YearH = 0x20;
  67.         
  68.         while(1)
  69.         {
  70.                 GetTime(&RealTime);
  71.         
  72.                 display_switch_state();
  73.                
  74.                 switch (globa_state) {
  75.                         case STATE_STATIC : {
  76.                                 display_hour(&RealTime);
  77.                                 
  78.                                 if (display_step == UNDISPLAY) {
  79.                                         Led[1] = (RealTime.Hour & 0x0F);
  80.                                         Led[3] = (RealTime.Min & 0x0F);
  81.                                 }
  82.                                 
  83.                                 
  84.                                 /* 检测状态 */
  85.                                 switch (KeyNum) {
  86.                                         case SL_SWITCH : {
  87.                                                         /* 等待按键松开 */
  88.                                                         globa_state = STATE_SWITCH;
  89.                                                         while( KeyNum == SL_SWITCH );
  90.                                                         
  91.                                                         
  92.                                         }
  93.                                         break;
  94.                                        
  95.                                         case SL_SET : {                                                        
  96.                                                         
  97.                                                         /* 进行下中间变量存储 */
  98.                                                         tmp_real_time = RealTime;
  99.                                                         globa_state = STATE_SET;
  100.                                                         /* 等待按键松开 */
  101.                                                         while( KeyNum == SL_SET );
  102.                                                         

  103.                                         }
  104.                                         break;                        
  105.                                         default :  break;
  106.                                 }                                
  107.                         }               
  108.                         break;

  109.                         case STATE_SWITCH : {
  110.                                         switch (switch_state) {
  111.                                                 case SWITCH_YEAR : {
  112.                                                         display_switch(display_year, &RealTime, SWITCH_MONTH);
  113.                                                 break;
  114.                                                 
  115.                                                 case SWITCH_MONTH : {                        
  116.                                                         display_switch(display_month, &RealTime, SWITCH_WEEK);
  117.                                                 }
  118.                                                 break;
  119.                                                 
  120.                                                 case SWITCH_WEEK : {
  121.                                                         calculation_week(&RealTime);
  122.                                                         display_switch(display_day, &RealTime, SWITCH_YEAR);
  123.                                                 }
  124.                                                 break;

  125.                                                 default : break;
  126.                                         }
  127.                                 }
  128.                                 is_exit();
  129.                         }
  130.                         break;

  131.                         case STATE_SET : {
  132.                                 switch (set_state) {
  133.                                         case SET_HOUR :
  134.                                                 display_set(display_hour, SET_MINUTE);                        
  135.                                         break;

  136.                                         case SET_MINUTE :
  137.                                                 display_set(display_hour, SET_SECOND);
  138.                                         break;

  139.                                         case SET_SECOND :
  140.                                                 display_set(display_hour, SET_YEAR);
  141.                                         break;
  142.                                        
  143.                                         case SET_YEAR :
  144.                                                 display_set(display_year, SET_MONTH);
  145.                                         break;
  146.                                        
  147.                                         case SET_MONTH :
  148.                                                 display_set(display_month, SET_DAYTE);
  149.                                         break;
  150.                                        
  151.                                         case SET_DAYTE :
  152.                                                 display_set(display_month, SET_WEEK);
  153.                                         break;

  154.                                         case SET_WEEK :
  155.                                                 /* 计算星期 */
  156.                                                 calculation_week(&tmp_real_time);
  157.                                                 
  158.                                                 display_day(&tmp_real_time);                                       
  159.                                                 if (KeyNum == SL_SET) {
  160.                                                         /* 写入到ds1302 */        
  161.                                                         globa_state = STATE_STATIC;
  162.                                                         set_state = SET_HOUR;
  163.                                                         SetTime(&tmp_real_time);
  164.                                                         while( KeyNum == SL_SET );        
  165.                                                 }
  166.                                         break;

  167.                                         default : break;
  168.                                 }
  169.                                 
  170.                                 is_exit();
  171.                         }               
  172.                         break;

  173.                         default : break;        
  174.                 }
  175.         }
  176. }

  177. void T0_Int() interrupt 1
  178. {
  179.         static char KeyTemp,KeyTempOld;
  180.         static unsigned char T0IntCnt;

  181.         static unsigned short is_time500ms;
  182.         static unsigned char  is_time200ms;

  183.         if (++is_time500ms >= 249) {
  184.                         is_time500ms = 0;
  185.                         display_twinkle = 1;
  186.         }


  187.         if ((KeyNum == SL_INC) || (KeyNum == SL_DEC)) {
  188.                 if (++is_time200ms >= 69) {
  189.                                 is_time200ms = 0;
  190.                                 key_continuit = 1;
  191.                         }
  192.         } else {
  193.                 is_time200ms = 0;        
  194.         }
  195.                
  196.         
  197.         TH0 = (65536-2000)/256;
  198.         TL0 = (65536-2000)%256;
  199.         
  200.         T0IntCnt = (T0IntCnt+1)%10;
  201.         
  202.         if( T0IntCnt<7 )        Dis1bit(T0IntCnt);
  203.         else if( T0IntCnt==9 )
  204.         {
  205.                 KeyTempOld = KeyTemp;
  206.                 KeyTemp = KeyScan();
  207.                 if(KeyTemp==KeyTempOld)
  208.                 {
  209.                         KeyNum = KeyTemp;
  210.                         if(KeyNum==-1)
  211.                         {
  212.                                 KeyDownCnt = 0;
  213.                                 KeyUpCnt++;
  214.                         }
  215.                         else
  216.                         {
  217.                                 KeyDownCnt ++ ;
  218.                                 KeyUpCnt = 0;
  219.                         }
  220.                 }
  221.         }
  222. }

  223. /*
  224. *********************************************************************************************************
  225. *    函 数 名: is_exit
  226. *    功能说明: 退出設置和切換狀態
  227. *    形    参: _RealTime: 实时时间的实体
  228. *    返 回 值: 无
  229. *********************************************************************************************************
  230. */
  231. void is_exit(void)
  232. {
  233.         if (KeyNum == SL_EXIT){
  234.                 globa_state = STATE_STATIC;
  235.                 switch_state = SWITCH_YEAR;                        
  236.                 set_state    = SET_HOUR;
  237.                 while( KeyNum == SL_EXIT);
  238.         }
  239. }



  240. /*
  241. *********************************************************************************************************
  242. *    函 数 名: calculation_week
  243. *    功能说明: 计算星期功能函数
  244. *    形    参: _RealTime: 实时时间的实体
  245. *    返 回 值: 无
  246. *********************************************************************************************************
  247. */

  248. void calculation_week(RealTimeTypeDef *_RealTime)
  249. {
  250.         unsigned char tmp_month, tmp_date;
  251.         unsigned short tmp_year;
  252.         
  253.         tmp_year = ((_RealTime->YearH >> 4) * 1000) + ((_RealTime->YearH & 0x0F) * 100) + ((_RealTime->YearL >> 4) * 10) + _RealTime->YearL & 0x0F;
  254.         tmp_date = ((_RealTime->Date >> 4) * 10) + (_RealTime->Date & 0x0F);
  255.         tmp_month = ((_RealTime->Month >> 4) * 10) + (_RealTime->Month & 0x0F);

  256.         _RealTime->Day = (tmp_date + 2 * tmp_month + 3 * (tmp_month + 1) / 5 + tmp_year + tmp_year / 4 - tmp_year / 100 + tmp_year / 400) % 7;

  257.         if (_RealTime->Day == 0)
  258.                 _RealTime->Day = 7;
  259. }

  260. static void display_hour(RealTimeTypeDef *_RealTime)
  261. {
  262.                 Led[0] = _RealTime->Hour >> 4;
  263.                 Led[1] = (_RealTime->Hour & 0x0F) + 0x10;
  264.                 Led[2] = _RealTime->Min >> 4;
  265.                 Led[3] = (_RealTime->Min & 0x0F) + 0x10;
  266.                 Led[4] = _RealTime->Sec >> 4;
  267.                 Led[5] = _RealTime->Sec & 0x0F;
  268. }




  269. static void display_year(RealTimeTypeDef *_RealTime)
  270. {
  271.                 Led[0] = 0x1b;
  272.                 Led[1] = 0x1b;
  273.                 Led[2] = _RealTime->YearH >> 4;
  274.                 Led[3] = _RealTime->YearH & 0x0F;
  275.                 Led[4] = _RealTime->YearL >> 4;
  276.                 Led[5] = _RealTime->YearL & 0x0F;
  277. }


  278. static void display_month(RealTimeTypeDef *_RealTime)
  279. {
  280.                 Led[0] = 0x1b;
  281.                 Led[1] = _RealTime->Month >> 4;
  282.                 Led[2] = _RealTime->Month & 0x0F;
  283.                 Led[3] = 0x1c;
  284.                 Led[4] = _RealTime->Date >> 4;
  285.                 Led[5] = _RealTime->Date & 0x0F;
  286. }

  287. static void display_day(RealTimeTypeDef *_RealTime)
  288. {
  289.                 Led[0] = 0x1b;
  290.                 Led[1] = 0x1b;
  291.                 Led[2] = 0x1b;
  292.                 Led[3] = 0x1b;
  293.                 Led[4] = 0x1b;
  294.                 Led[5] = _RealTime->Day;
  295. }


  296. /*
  297. *********************************************************************************************************
  298. *    函 数 名: undisplay
  299. *    功能说明: 用于设置闪烁
  300. *    形    参: time_state: 当前要设置的段位
  301. *    返 回 值: 无
  302. *********************************************************************************************************
  303. */

  304. static void undisplay(unsigned char time_state)
  305. {
  306.         switch (time_state) {
  307.                 case SET_HOUR :
  308.                         Led[0] = 0x1b;
  309.                         Led[1] = 0x1b;
  310.                 break;

  311.                 case SET_MINUTE :
  312.                         Led[2] = 0x1b;
  313.                         Led[3] = 0x1b;
  314.                 break;

  315.                 case SET_SECOND :
  316.                         Led[4] = 0x1b;
  317.                         Led[5] = 0x1b;
  318.                 break;

  319.                 case SET_YEAR :
  320.                         Led[4] = 0x1b;
  321.                         Led[5] = 0x1b;
  322.                 break;

  323.                 case SET_MONTH :
  324.                         Led[1] = 0x1b;
  325.                         Led[2] = 0x1b;
  326.                 break;

  327.                 case SET_DAYTE:
  328.                         Led[4] = 0x1b;
  329.                         Led[5] = 0x1b;
  330.                 break;

  331.                 default : break;
  332.         }        
  333. }



  334. /*
  335. *********************************************************************************************************
  336. *    函 数 名: display_switch_state
  337. *    功能说明: DISPLAY 和 UNDISPLAY的切换
  338. *    形    参: 无
  339. *    返 回 值: 无
  340. *********************************************************************************************************
  341. */

  342. void display_switch_state(void)
  343. {
  344.         if (display_twinkle == 1) {
  345.                 display_twinkle = 0;
  346.                
  347.                 switch (display_step) {
  348.                         case DISPLAY :
  349.                                 display_step = UNDISPLAY;        
  350.                         break;

  351.                         case UNDISPLAY :
  352.                                 display_step = DISPLAY;
  353.                         break;
  354.                         
  355.                         default : break;        
  356.                 }
  357.         }
  358. }



  359. /*
  360. *********************************************************************************************************
  361. *    函 数 名: display_switch
  362. *    功能说明: 切换显示时间
  363. *    形    参: 无
  364. *    返 回 值: 无
  365. *********************************************************************************************************
  366. */

  367. void display_switch(dispaly_callback display, RealTimeTypeDef *time, unsigned char next_state)
  368. {
  369.         display(time);
  370.         if( KeyNum == SL_SWITCH ) {
  371.                 switch_state = next_state;
  372.                 if (next_state == SWITCH_YEAR)
  373.                         globa_state = STATE_STATIC;
  374.                 while( KeyNum == SL_SWITCH );
  375.         }
  376. }



  377. /*
  378. *********************************************************************************************************
  379. *    函 数 名: display_set
  380. *    功能说明: 设置时间
  381. *    形    参: 无
  382. *    返 回 值: 无
  383. *********************************************************************************************************
  384. */

  385. void display_set(dispaly_callback display, unsigned char next_state)
  386. {
  387.         unsigned char tmp;
  388.         unsigned char tmp_month;
  389.         unsigned short tmp_year;

  390.         unsigned char tmp_keynum;
  391.         
  392.         unsigned char currten_state = next_state - 1;
  393.         
  394.         switch (KeyNum) {
  395.                 case SL_ZERO :                        
  396.                 case SL_ONE :
  397.                 case SL_TWO :
  398.                 case SL_THREE :
  399.                 case SL_FOUR :
  400.                 case SL_FIVE :
  401.                 case SL_SIX :
  402.                 case SL_SEVEN :
  403.                 case SL_EIGHT :
  404.                 case SL_NINE :
  405.                         tmp_keynum = KeyNum;
  406.                         switch (currten_state) {
  407.                                 case SET_HOUR :
  408.                                         num_time_handle(&tmp_real_time.Hour, tmp_keynum, currten_state);
  409.                                 break;
  410.                                 
  411.                                 case SET_MINUTE :
  412.                                         num_time_handle(&tmp_real_time.Min, tmp_keynum, currten_state);
  413.                                 break;
  414.                                 
  415.                                 case SET_SECOND :
  416.                                         num_time_handle(&tmp_real_time.Sec, tmp_keynum, currten_state);
  417.                                 break;
  418.                                 case SET_YEAR :
  419.                                         num_time_handle(&tmp_real_time.YearL, tmp_keynum, currten_state);
  420.                                 break;
  421.                                 
  422.                                 case SET_MONTH :
  423.                                         num_time_handle(&tmp_real_time.Month, tmp_keynum, currten_state);
  424.                                 break;
  425.                                 
  426.                                 case SET_DAYTE :
  427.                                         num_time_handle(&tmp_real_time.Date, tmp_keynum, currten_state);
  428.                                 break;

  429.                                 default : break;
  430.                         }        
  431.                         while (KeyNum == tmp_keynum);
  432.                 break;
  433.                
  434.                 case SL_INC :
  435.                 case SL_DEC :
  436.                         if (key_continuit == 1) {
  437.                                 key_continuit = 0;                                                                        
  438.                                 switch (currten_state) {
  439.                                         case SET_HOUR :
  440.                                                 inc_dec_time_handle(&tmp_real_time.Hour, KeyNum, currten_state);
  441.                                                 
  442.                                         break;

  443.                                         case SET_MINUTE :
  444.                                                 inc_dec_time_handle(&tmp_real_time.Min, KeyNum, currten_state);
  445.                                        
  446.                                         break;

  447.                                         case SET_SECOND :
  448.                                                 inc_dec_time_handle(&tmp_real_time.Sec, KeyNum, currten_state);

  449.                                         break;

  450.                                         case SET_YEAR :
  451.                                                 inc_dec_time_handle(&tmp_real_time.YearL, KeyNum, currten_state);

  452.                                         break;
  453.                                        
  454.                                         case SET_MONTH :
  455.                                                 inc_dec_time_handle(&tmp_real_time.Month, KeyNum, currten_state);

  456.                                         break;

  457.                                         case SET_DAYTE :
  458.                                                 if (KeyNum == SL_INC) {
  459.                                                         /* 日期处理功能 */
  460.                                                         tmp = ((tmp_real_time.Date >> 4) * 10) + (tmp_real_time.Date & 0x0F);
  461.                                                         tmp++;
  462.                                                         
  463.                                                         tmp_month = ((tmp_real_time.Month >> 4) * 10) + (tmp_real_time.Month & 0x0F);
  464.                                                         
  465.                                                         #if 1

  466.                                                         /* 判断月份 */
  467.                                                         switch (tmp_month) {
  468.                                                                 case 1 :
  469.                                                                 case 3 :
  470.                                                                 case 5 :
  471.                                                                 case 7 :
  472.                                                                 case 8 :
  473.                                                                 case 10 :
  474.                                                                 case 12 :
  475.                                                                         if (tmp > 31)        /* 上限处理 */
  476.                                                                                 tmp = 0;
  477.                                                                
  478. ……………………

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

所有资料51hei提供下载:
多功能电子时钟(数码管显示).rar (152.08 KB, 下载次数: 108)




评分

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

查看全部评分

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

使用道具 举报

沙发
ID:364328 发表于 2018-7-10 21:20 | 只看该作者
请问一下有没有功能备注啥的啊    设定是改时间还是?闹钟啊
回复

使用道具 举报

板凳
ID:672293 发表于 2019-12-24 15:43 | 只看该作者
程序中怎么去实现报时功能啊
回复

使用道具 举报

地板
ID:435618 发表于 2021-2-8 20:22 | 只看该作者
刚开始学,感觉好难的样子。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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