找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5804|回复: 7
收起左侧

基于51单片机的电子钟仿真程序(7个功能,具体功能见帖内介绍)

  [复制链接]
ID:750420 发表于 2021-12-13 14:14 | 显示全部楼层 |阅读模式
大一时候做的单片机设计,在b站录了视频进行相应的介绍(BV1mJ411L7Ek)很多朋友一直想要但是以前的代码水平并不咋地(怕放出来丢人)也就一直没有开源,之后有时间会用状态机+时间片轮的思想进行重构给朋友们进行对比学习,这次就先给各位放出来了

基本的时间与温度显示功能/时间校准/闹钟功能/秒表(开始、暂停、继续,记录一个秒表时间,秒表进行清零,长按显示记录的秒表时间)/倒计时(开始、暂停、继续,重新倒计时,倒计时清零)/12/24时显示选择
因为各种中断的原因,这个电子钟本身去记录时间的功能已经被破坏掉了,后续应该可以在增加变量,去记录所经历的中断数,对于基础时钟的时间进行补偿,使其达到更加精准的效果。(不过那样又是得花费很多时间去计算所占用的时间啊什么的,实在是肝不动了)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<absacc.h>
  3. #include<stdio.h>
  4. #include<intrins.h>
  5. #define uchar unsigned char
  6. #define uint  unsigned int
  7. #define out P0
  8. sbit RS=P2^0;
  9. sbit RW=P2^1;
  10. sbit E=P2^2;
  11. sbit ctime=P3^2;//外部中断0,时间校准
  12. sbit s_alarm=P3^3;//外部中断1,闹钟设定
  13. sbit LED=P1^2;//低电平点亮
  14. sbit P2_4=P1^1;//24时12时标记位,实在没办法了,data区已经用完了
  15. //五个按键低电平有效,上下左右 确认 1234 0

  16. void lcd_initial(void);
  17. void lcd_initial2(void);
  18. void check_busy(void);
  19. void write_command(uchar com);
  20. void write_data(uchar dat);
  21. void string(uchar ad,uchar*s);
  22. void delay(uint);
  23. int read_keys(void);
  24. void c_string(uchar ad,uchar *s);
  25. void s_string(uchar ad,uchar s);
  26. void write_time(void);
  27. void inter_init(void);
  28. void base_time(void);
  29. void C_time(void);
  30. void alarm(void);
  31. void stopwatch(void);
  32. void countdown(void);
  33. void c_down(void);
  34. void t24_12(void);

  35. struct xwei
  36. {
  37.         uchar x_address;//显示屏的地址
  38.         uchar* zhi;//指向传递值的指针
  39. }wei[2][7];

  40. struct zwei
  41. {
  42.         uchar x_address;//显示屏的地址
  43.         uchar zhi;//存储值
  44. };

  45. uchar code mdays[12]={31,29,31,30,31,30,31,31,30,31,30,31};
  46. uchar code weeks[7][5]={"Mon","Tues","Wed","Thur","Fri","Sat","Sun"};
  47. uchar code tab1[]={"20  -  - "};
  48. uchar code tab2[]={"  :  :    "};
  49. uchar second[3]={53,55};//记录s//所有数值均以ASCII值表示
  50. uchar minute[3]={53,57};//记录min
  51. uchar hour[3]={50,51};//记录h
  52. uchar day[3]={51,49};//记录日
  53. uchar month[3]={49,50};//记录月
  54. uchar year[3]={49,56};//记录年
  55. uchar week=7;//记录星期几
  56. uchar x=0,y=0;//光标位置
  57. uchar a_p_m=0;//am,pm标记量
  58. uchar pFlag=0;
  59. uchar btFlag=1;//基本事件标记
  60. uchar bpFlag=0;//基本校准标记
  61. uchar bfFlag=0;//基本选择标记
  62. uchar swFlag=0;//秒表标记
  63. uchar cdFlag=0;//倒计时标记
  64. uchar acFlag=0;//闹钟标记
  65. uint timer=0;//中断记录变量
  66. uint sd=0;//秒表,倒计时记录变量
  67. uchar sdFlag=0;//毫秒级计时标记位
  68. int  B_state_tag=-1;//按键状态标记位

  69. //闹钟变量
  70. struct zwei alarm_clock[4];
  71. struct zwei TIME_clock[4];
  72. void timer0() interrupt 1 using 1//基本时钟
  73. {
  74.         timer++;
  75.         if(timer==10000)
  76.         {
  77.                 timer=0;
  78.                 btFlag=1;
  79.         }
  80. }
  81. void timer1() interrupt 3 using 1//秒表,倒计时时钟
  82. {
  83.         sd++;
  84.         if(sd==800)//每100ms加加//由实际测试得出非计算值
  85.         {
  86.                 sd=0;
  87.                 sdFlag=1;
  88.         }
  89. }
  90. void int0() interrupt 0 using 0//时间校准
  91. {
  92.         bpFlag=1;
  93. }
  94. void int1() interrupt 2//功能选择
  95. {
  96.         bfFlag=1;//带选择
  97.         EA=0;
  98.         //TR0=0;
  99.         pFlag=1;
  100.         lcd_initial2();
  101.         delay(1);
  102.         write_command(0x01);
  103.         delay(1);
  104.         x=0;
  105.         while(bfFlag)
  106.         {
  107.                 while(read_keys()==-1);//等待按键按下
  108.                 B_state_tag=read_keys();
  109.                 x=B_state_tag-1;//上下按键选择日期或者时间
  110.                 while(bfFlag)//按键与显示屏操作
  111.                 {
  112.                         while(read_keys()==-1);
  113.                         B_state_tag=read_keys();//读取按键值
  114.                         while(read_keys()!=-1);
  115.                         switch(B_state_tag)
  116.                         {
  117.                                 case 1://上
  118.                                 {
  119.                                         string(0x80,"alarm clock");
  120.                                         acFlag=1;
  121.                                 }break;
  122.                                 case 2://下
  123.                                 {
  124.                                         string(0x80,"stopwatch");
  125.                                         swFlag=1;
  126.                                 }break;
  127.                                 case 3://左
  128.                                 {
  129.                                         string(0x80,"countdown");
  130.                                         cdFlag=1;
  131.                                 }break;
  132.                                 case 4://右
  133.                                 {
  134.                                         if(P2_4==0)
  135.                                           P2_4=1;
  136.                                         if(P2_4==1)
  137.                                                 string(0xce,"  ");
  138.                                         string(0x80,"24or12");
  139.                                 }break;
  140.                                 case 0://确认
  141.                                 {
  142.                                         bfFlag=0;
  143.                                 }break;
  144.                                 default:break;
  145.                         }
  146.                         while(read_keys()!=-1);
  147.                 }
  148.         }
  149.         lcd_initial();
  150.         inter_init();
  151.         bfFlag=0;
  152. }
  153. //系统时钟为12MHZ
  154. void main()
  155. {
  156.         P2_4=0;
  157.         lcd_initial();
  158.         inter_init();
  159.         P1=0xff;//读取按键,先写入
  160.         string(0x80,tab1);
  161.         string(0xc0,tab2);
  162.         
  163.         while(1)
  164.         {
  165.                 if(swFlag==1)//秒表
  166.                 {
  167.                         for(x=1;x<=1;)//只执行一次清屏操作
  168.                         {
  169.                                 TR1=1;
  170.                                 TH1=0x9C;//100us 中断一次
  171.               TL1=0x9C;
  172.                                 write_command(0x01);
  173.                                 string(0x83,":");
  174.                                 x=2;
  175.                         }
  176.                         stopwatch();
  177.                 }
  178.                 else
  179.                 {
  180.                         write_time();
  181.                 }
  182.                
  183.                 if(cdFlag==1)//倒计时
  184.                 {
  185.                         for(x=1;x<=1;)//只执行一次清屏操作
  186.                         {
  187.                                 write_command(0x01);
  188.                                 string(0x83,":");
  189.                                 countdown();
  190.                                 TH1=0x9C;//100us 中断一次
  191.               TL1=0x9C;
  192.                                 x=2;
  193.                         }
  194.                         countdown();
  195.                         c_down();
  196.                 }
  197.                 else
  198.                 {
  199.                         write_time();
  200.                 }
  201.                
  202.                 if(btFlag==1)
  203.                 {
  204.                         base_time();
  205.                 }
  206.                 if(bpFlag==1)
  207.                 {
  208.                         C_time();
  209.                 }
  210.                 if(acFlag==1)
  211.                 {
  212.                         LED=1;
  213. ……………………

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

仿真代码51hei附件下载:
多功能电子钟.7z (75.87 KB, 下载次数: 242)

评分

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

查看全部评分

回复

使用道具 举报

ID:615687 发表于 2021-12-13 23:51 | 显示全部楼层
没仔细看呢,但看到这么多定义内容先顶一个以表敬意
回复

使用道具 举报

ID:91165 发表于 2021-12-14 10:18 | 显示全部楼层
支持一下楼主,希望多发好帖
回复

使用道具 举报

ID:991417 发表于 2021-12-14 13:54 | 显示全部楼层
需要用Proteus8.8仿真
回复

使用道具 举报

ID:992298 发表于 2021-12-14 17:21 | 显示全部楼层
挺好的,支持一下楼主
回复

使用道具 举报

ID:1034880 发表于 2022-6-15 18:52 | 显示全部楼层
请问一下,这个调时间应该怎么调,只会调日期,不能调时间啊
回复

使用道具 举报

ID:1043718 发表于 2022-9-3 14:54 | 显示全部楼层
真的很有效地解决了我的问题,看到楼主的这篇,我忽然茅塞顿开
回复

使用道具 举报

ID:1058977 发表于 2022-12-24 11:11 | 显示全部楼层
楼主太强了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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