大一时候做的单片机设计,在b站录了视频进行相应的介绍(BV1mJ411L7Ek)很多朋友一直想要但是以前的代码水平并不咋地(怕放出来丢人)也就一直没有开源,之后有时间会用状态机+时间片轮的思想进行重构给朋友们进行对比学习,这次就先给各位放出来了
基本的时间与温度显示功能/时间校准/闹钟功能/秒表(开始、暂停、继续,记录一个秒表时间,秒表进行清零,长按显示记录的秒表时间)/倒计时(开始、暂停、继续,重新倒计时,倒计时清零)/12/24时显示选择
因为各种中断的原因,这个电子钟本身去记录时间的功能已经被破坏掉了,后续应该可以在增加变量,去记录所经历的中断数,对于基础时钟的时间进行补偿,使其达到更加精准的效果。(不过那样又是得花费很多时间去计算所占用的时间啊什么的,实在是肝不动了)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h>
- #include<absacc.h>
- #include<stdio.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define out P0
- sbit RS=P2^0;
- sbit RW=P2^1;
- sbit E=P2^2;
- sbit ctime=P3^2;//外部中断0,时间校准
- sbit s_alarm=P3^3;//外部中断1,闹钟设定
- sbit LED=P1^2;//低电平点亮
- sbit P2_4=P1^1;//24时12时标记位,实在没办法了,data区已经用完了
- //五个按键低电平有效,上下左右 确认 1234 0
- void lcd_initial(void);
- void lcd_initial2(void);
- void check_busy(void);
- void write_command(uchar com);
- void write_data(uchar dat);
- void string(uchar ad,uchar*s);
- void delay(uint);
- int read_keys(void);
- void c_string(uchar ad,uchar *s);
- void s_string(uchar ad,uchar s);
- void write_time(void);
- void inter_init(void);
- void base_time(void);
- void C_time(void);
- void alarm(void);
- void stopwatch(void);
- void countdown(void);
- void c_down(void);
- void t24_12(void);
- struct xwei
- {
- uchar x_address;//显示屏的地址
- uchar* zhi;//指向传递值的指针
- }wei[2][7];
- struct zwei
- {
- uchar x_address;//显示屏的地址
- uchar zhi;//存储值
- };
- uchar code mdays[12]={31,29,31,30,31,30,31,31,30,31,30,31};
- uchar code weeks[7][5]={"Mon","Tues","Wed","Thur","Fri","Sat","Sun"};
- uchar code tab1[]={"20 - - "};
- uchar code tab2[]={" : : "};
- uchar second[3]={53,55};//记录s//所有数值均以ASCII值表示
- uchar minute[3]={53,57};//记录min
- uchar hour[3]={50,51};//记录h
- uchar day[3]={51,49};//记录日
- uchar month[3]={49,50};//记录月
- uchar year[3]={49,56};//记录年
- uchar week=7;//记录星期几
- uchar x=0,y=0;//光标位置
- uchar a_p_m=0;//am,pm标记量
- uchar pFlag=0;
- uchar btFlag=1;//基本事件标记
- uchar bpFlag=0;//基本校准标记
- uchar bfFlag=0;//基本选择标记
- uchar swFlag=0;//秒表标记
- uchar cdFlag=0;//倒计时标记
- uchar acFlag=0;//闹钟标记
- uint timer=0;//中断记录变量
- uint sd=0;//秒表,倒计时记录变量
- uchar sdFlag=0;//毫秒级计时标记位
- int B_state_tag=-1;//按键状态标记位
- //闹钟变量
- struct zwei alarm_clock[4];
- struct zwei TIME_clock[4];
- void timer0() interrupt 1 using 1//基本时钟
- {
- timer++;
- if(timer==10000)
- {
- timer=0;
- btFlag=1;
- }
- }
- void timer1() interrupt 3 using 1//秒表,倒计时时钟
- {
- sd++;
- if(sd==800)//每100ms加加//由实际测试得出非计算值
- {
- sd=0;
- sdFlag=1;
- }
- }
- void int0() interrupt 0 using 0//时间校准
- {
- bpFlag=1;
- }
- void int1() interrupt 2//功能选择
- {
- bfFlag=1;//带选择
- EA=0;
- //TR0=0;
- pFlag=1;
- lcd_initial2();
- delay(1);
- write_command(0x01);
- delay(1);
- x=0;
- while(bfFlag)
- {
- while(read_keys()==-1);//等待按键按下
- B_state_tag=read_keys();
- x=B_state_tag-1;//上下按键选择日期或者时间
- while(bfFlag)//按键与显示屏操作
- {
- while(read_keys()==-1);
- B_state_tag=read_keys();//读取按键值
- while(read_keys()!=-1);
- switch(B_state_tag)
- {
- case 1://上
- {
- string(0x80,"alarm clock");
- acFlag=1;
- }break;
- case 2://下
- {
- string(0x80,"stopwatch");
- swFlag=1;
- }break;
- case 3://左
- {
- string(0x80,"countdown");
- cdFlag=1;
- }break;
- case 4://右
- {
- if(P2_4==0)
- P2_4=1;
- if(P2_4==1)
- string(0xce," ");
- string(0x80,"24or12");
- }break;
- case 0://确认
- {
- bfFlag=0;
- }break;
- default:break;
- }
- while(read_keys()!=-1);
- }
- }
- lcd_initial();
- inter_init();
- bfFlag=0;
- }
- //系统时钟为12MHZ
- void main()
- {
- P2_4=0;
- lcd_initial();
- inter_init();
- P1=0xff;//读取按键,先写入
- string(0x80,tab1);
- string(0xc0,tab2);
-
- while(1)
- {
- if(swFlag==1)//秒表
- {
- for(x=1;x<=1;)//只执行一次清屏操作
- {
- TR1=1;
- TH1=0x9C;//100us 中断一次
- TL1=0x9C;
- write_command(0x01);
- string(0x83,":");
- x=2;
- }
- stopwatch();
- }
- else
- {
- write_time();
- }
-
- if(cdFlag==1)//倒计时
- {
- for(x=1;x<=1;)//只执行一次清屏操作
- {
- write_command(0x01);
- string(0x83,":");
- countdown();
- TH1=0x9C;//100us 中断一次
- TL1=0x9C;
- x=2;
- }
- countdown();
- c_down();
- }
- else
- {
- write_time();
- }
-
- if(btFlag==1)
- {
- base_time();
- }
- if(bpFlag==1)
- {
- C_time();
- }
- if(acFlag==1)
- {
- LED=1;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
仿真代码51hei附件下载:
多功能电子钟.7z
(75.87 KB, 下载次数: 262)
|