日历时钟单片机课程设计附汇编程序方案图模块图ddb模拟图样本
单片机万年历设计编程
单片机万年历设计编程一.实验目的1.掌握时钟程序的使用方法2.掌握时间函数的使用方法3.利用单片机设计万年历二.设计要求通过与单片机连接数码管动态显示年、月、日、时、分、秒、星期等功能,并能准确计算闰年闰月的显示,七个按钮连接P0口可以精确调整每一个时间数值,通过对所设计的万年历时钟电路进行实验测试,达到了动态显示时间,随时调整时间等技术指标。
三.设计方案1.原理构成框图本设计用AT89C51作为核心控制部分,外接晶振电路与复位电路,74LS138作为位选扩展电路,P0口接七个开关作为时间调整部分,以两个四位数码管作为显示部分,开关控制显示时间与日期,P2口作为段选,P1口作为位选部分。
具体框图如图所示:2.主程序设计系统程序采用C语言按模块化方式进行设计,然后通过KeilC51L软件开发平台将程序转变成十六进制程序语言,得到HEX文件,接着使用Proteous进行仿真,其次,按照Proteous 的仿真电路图,在Protel99SE中完成电路板的逻辑布局及布线。
系统程序主要包括主程序,读出时钟子程序、计算时间子程序、键盘扫描子程序和显示数据刷新子程序。
主程序流程图如图所示:3时间调整电路的设计采用按键设计,独立式按键直接与单片机I/O口相连构成键盘,每个按键不会相互影响,按下SHI JIAN键两个四位数码管显示时间和星期,按下RI QI键两个数码管显示日期,按下TIAO SHI键可以对时间和日期进行调节,JIA键表示加,JIAN键表示减,YI WEI表示选择所要调节的位置,QUE DING按键按下,时间调节结束。
所连线路和单片机接口仿真图如图所示:4.LED数码管的选择LED数码管分为共阴和共阳两种,以利用AT89C51的P2口作为LED显示的段选部分,以P1口的P1.0、P1.1、P1.2、三个口作为显示部分的位选,通过三八译码器扩展为八位的位选分别接在两个四位数码管的位选部分。
详细电路图如图所示:5.实物的制作与调试原理图的绘制PCB的绘制四.设计总结这次的设计的任务是万年历时钟的设计,对于时钟以前学习C51时有些接触,通过C51芯片程序控制显示万年历。
单片机制作数字钟(含万年历、秒表功能)
数字钟、万年历制作(基于单片机)电路原理图:程序://********************20131206****数字钟程序#pragma SMALL#include <reg51.h>#include <absacc.h>#include <intrins.h>//********************************************************* *********编译预处理void display(unsigned char *p); //显示函数,P为显示数据首地址unsigned char keytest(); //按键检测函数unsigned char search(); //按键识别函数void alarm(); //闹钟判断启动函数void ftion0(); //始终修改函数void ftion1(); //闹钟修改函数void ftion3(); //日期修改函数void cum(); //加1修改函数void minus(); //减1修改函数void jinzhi(); //进制修改函数void riqi(); //日期void stopwatch(); //秒表函数//********************************************************* *******函数声明sbit P2_7=P2^7;//********************************************************* *******端口定义unsigned char clockbuf[3]={0,0,0};unsigned char bellbuf[3]={0,0,0};unsigned char date[3]={1,1,1}; //日期存放数组unsigned char stop[3]={0,0,0};unsigned char msec1,msec2;unsigned char timdata,rtimdata,dtimdata;unsigned char count;unsigned char *dis_p;unsigned char or; //12进制控制标志unsigned char ri; //日期显示控制标志位unsigned char mb; //秒表控制标志位bit arm,rtim,rhour,rmin,hour,min,sec,day,mon,year; //定义位变量//********************************************************* *****全局变量定义void main(){unsigned char a;or=0; //12进制修改标志清零ri=0;mb=0;P2_7=0;arm=0;msec1=0;msec2=0;timdata=0;rtimdata=0;count=0;TMOD=0x12;TL0=0x06;TH0=0x06;TH1=(65536-10000)/256;TL1=(65536-10000)%256;EA=1;ET0=1;ET1=1;TR0=1;TR1=0;dis_p=clockbuf;while(1){a=keytest();if(a==0x78) //判断是否有键按下{display(dis_p);if(arm==1) alarm();}else{display(dis_p);a=keytest();if(a!=0x78){a=search();switch(a){case 0x00:ftion0();break;case 0x01:ftion1();break;case 0x02:cum();break;case 0x06:jinzhi();break;case 0x03:riqi();break;case 0x04:ftion3();break;case 0x05:minus();break;case 0x07:stopwatch();break;case 0x09:TR1=1;break;case 0x0a:TR1=0;break;case 0x0b:stop[0]=0;stop[1]=0;stop[2]=0;break;default:break;}}}}}//********************************************主函数【完】void display(unsigned char *p){unsigned char buffer[]={0,0,0,0,0,0};unsigned char k,i,j,m,temp;unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};buffer[0]=p[0]/10;buffer[1]=p[0]%10;buffer[2]=p[1]/10;buffer[3]=p[1]%10;buffer[4]=p[2]/10;buffer[5]=p[2]%10;if((sec==0)&&(min==0)&&(hour==0)&&(rmin==0)&&(rhour==0)&&( day==0)&&(mon==0)&&(year==0)) //没有修改标志,正常显示{for(k=0;k<3;k++){temp=0x01;for(i=0;i<6;i++){P0=0x00; //段选端口j=buffer[i];P0=led[j];P1=~temp; //位选端口temp<<=1;for(m=0;m<200;m++);}}}else //若有修改标志,则按以下标志分别显示{if(sec==1||day==1){P1=0x1f;i=buffer[5];P0=led[i];for(m=0;m<200;m++);P1=0x2f;j=buffer[4];P0=led[j];for(m=0;m<200;m++);}if(min==1||rmin==1||mon==1){P1=0x3b;i=buffer[2];P0=led[i];for(m=0;m<200;m++);P1=0x37;j=buffer[3];P0=led[j];for(m=0;m<200;m++);}if(hour==1||rhour==1||year==1) {P1=0x3e;i=buffer[0];P0=led[i];for(m=0;m<200;m++);P1=0x3d;j=buffer[1];P0=led[j];for(m=0;m<200;m++);}}}//**********************************LED显示函数【完】unsigned char keytest(){unsigned char c;P2=0x78; //检测是否有键按下c=P2;c=c&0x78;return(c);}//******************************************键盘检测函数【完】unsigned char search(){unsigned char a,b,c,d,e;c=0x3f;a=0; //行号while(1){P2=c;d=P2;d=d&0x07;if(d==0x03){b=0;break;} //列号else if(d==0x05){b=1;break;}else if(d==0x06){b=2;break;}a++;c>>=1;if(a==5){a=0;c=0x3f;}}e=a*3+b;do{display(dis_p);}while((d=keytest())!=0x78);return(e);}//***********************************************查键值函数【完】void alarm(){if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1])){P2_7=1;rtim=1;if(count==10){count=0;P2_7=0;arm=0;rtim=0;}}}//****************************************闹钟判断启动函数【完】void ftion0(){TR0=0;rhour=0;rmin=0;dis_p=clockbuf;rtimdata=0;timdata++;switch(timdata){case 0x01:sec=1;break;case 0x02:sec=0;min=1;break;case 0x03:min=0;hour=1;break;case 0x04:timdata=0;hour=0;TR0=1;break;default:break;}}//*********************************************时钟设置函数【完】void ftion1(){if(TR0==0) TR0=1;sec=0;min=0;hour=0;dis_p=bellbuf;timdata=0;rtimdata++;switch(rtimdata){case 0x01:rmin=1;break;case 0x02:rmin=0;rhour=1;break;case 0x03:rtimdata=0;rhour=0;arm=1;dis_p=clockbuf;break;default:break;}}//*********************************************闹钟设置函数【完】void ftion3(){if(TR0==0) TR0=1;day=0;mon=0;year=0;dis_p=date;timdata=0;rtimdata=0;dtimdata++;switch(dtimdata){case 0x01:day=1;break;case 0x02:day=0;mon=1;break;case 0x03:mon=0;year=1;break;case 0x04:dtimdata=0;year=0;dis_p=clockbuf;break;default:break;}}//*************************************************日期修改函数【完】void minus(){if(sec==1){if(0==clockbuf[2]) clockbuf[2]=59;else clockbuf[2]--;}else if(min==1){if(0==clockbuf[1]) clockbuf[1]=59;else clockbuf[1]--;}else if(hour==1){if(or==0) //判断进制{if(0==clockbuf[0]) clockbuf[0]=23;else clockbuf[0]--;}if(or==1){if(1==clockbuf[0]) clockbuf[0]=12;else clockbuf[0]--;}}else if(rmin==1){if(bellbuf[1]==0) bellbuf[1]=59;else bellbuf[1]--;}else if(rhour==1){if(or==0){if(bellbuf[0]==0) bellbuf[0]=23;else bellbuf[0]--;}if(or==1){if(bellbuf[0]==1) bellbuf[0]=12;else bellbuf[0]--;}}else if(day==1){if(date[2]==1) date[2]=31;else date[2]--;}else if(mon==1){if(date[1]==1) date[1]=12;else date[1]--;}else if(year==1){if(date[0]==1) date[0]=99;else date[0]--;}}//*************************************减1修改功能函数【完】void cum(){if(sec==1){if(59==clockbuf[2]) clockbuf[2]=0;else clockbuf[2]++;}else if(min==1){if(59==clockbuf[1]) clockbuf[1]=0;else clockbuf[1]++;}else if(hour==1){if(or==0) //判断进制{if(23==clockbuf[0]) clockbuf[0]=0;else clockbuf[0]++;}if(or==1){if(12==clockbuf[0]) clockbuf[0]=1;else clockbuf[0]++;}}else if(rmin==1){if(bellbuf[1]==59) bellbuf[1]=0;else bellbuf[1]++;}else if(rhour==1){if(or==0){if(bellbuf[0]==23) bellbuf[0]=0;else bellbuf[0]++;}if(or==1){if(bellbuf[0]==12) bellbuf[0]=1;else bellbuf[0]++;}}else if(day==1){if(date[2]==31) date[2]=1;else date[2]++;}else if(mon==1){if(date[1]==12) date[1]=1;else date[1]++;}else if(year==1){if(date[0]==99) date[0]=0;else date[0]++;}}//*************************************加1修改功能函数【完】void jinzhi(){if(or==0) or=1;else or=0;}//***********************************进制修改控制函数【完】void riqi(){if(ri==0){dis_p=date;}if(ri==1){dis_p=clockbuf;}ri++;if(ri==2) ri=0;}//********************************日期控显示函数【完】void stopwatch(){if(mb==0){dis_p=stop;mb=1;}else{mb=0;dis_p=clockbuf;}}//************秒表**********秒表**********秒表函数【完】void clock() interrupt 1{EA=0;if(msec1!=0x14) msec1++; //6MHz晶振定时10mselse{msec1=0;if(msec2!=100) msec2++; //定时1selse{if(rtim==1) count++; //闹钟启动标志计时10smsec2=0;if(clockbuf[2]!=59) clockbuf[2]++;else{clockbuf[2]=0;if(clockbuf[1]!=59) clockbuf[1]++;else{clockbuf[1]=0;if(or==0){if(clockbuf[0]!=23) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}if(or==1){if(clockbuf[0]!=12) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}}}}}EA=1;}//*******************************定时器0中断函数【完】void miaobiao() interrupt 3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;if(stop[2]!=99) stop[2]++;else{stop[2]=0;if(stop[1]!=59) stop[1]++;else{stop[1]=0;if(stop[0]!=59) stop[0]++;else stop[0]=0;}}}//***********************************定时器1中断函数【完】。
51单片机12864万年历(图片+主要程序C语言)
51单片机做的12864万年历这是我花了一个星期时间做的万年历;一开始是一些图片,后面是这个制作的C语言源程序;希望大家稀饭:Main.c#include "reg52.h"#include "macroconst.h"#include "keyscan.h"#include "screen.h"#include "18b20.h"#include "ds1302.h"#include "atao_12864.h"#include "24c02.h"idata unsigned char state1[1];unsigned char screennum=1;//屏幕号#define time_task_sec 200 //节拍200Hz#define clock 24000000 //晶振#define max_task 4 //最大任务数idata unsigned char task_delay[4];#define task_delay0 time_task_sec/1 //2赫兹18b20 #define task_delay1 time_task_sec/5 //10赫兹屏幕#define task_delay2 time_task_sec/3 //4赫兹1302 #define task_delay3 time_task_sec/20 //20赫兹键盘void init(){unsigned char i;init18b20();ds1302_init();initina1(); //---------------------------LCD字库初始化程序RdFromROM(state1,8,1);state[0]=state1[0]; //-------界面RdFromROM(state1,15,1);state[1]=state1[0];//------- 闹钟RdFromROM(state1,11,1);key_sound=state1[0];//-------按键音// state[2]=state1[2];// state[3]=state1[3];screennum=1;//------默认一号屏for(i=0;i<max_task;i++)//清除任务延时{task_delay[i]=0;}TMOD=0x11;EA=1;TH0=255-clock/time_task_sec/12/526;TL0=255-clock/time_task_sec/12%526;ET0=1;TR0=1;}void main(){init();while(1){ if(task_delay[0]==0){readtemp(); task_delay[0]=task_delay0;} if(task_delay[3]==0){MenuCheckKey();task_delay[3]=task_delay1;}if(task_delay[1]==0){screen_select(screennum);task_delay[1]=task_delay1;} if(task_delay[2]==0){ds1302_read_time(); task_delay[2]=task_delay0;} }}void timer0() interrupt 1{uchar i=0;TH0=255-clock/time_task_sec/12/526;TH1=255-clock/time_task_sec/12%526;for(i=0;i<max_task;i++)if(task_delay[i]) task_delay[i]--; // miao=21,fen=33,xiaomiao=94;if(ma_start==1){tt++;if(tt==8){tt=0;xiaomiao++;if(xiaomiao==99){xiaomiao=0;miao++;if(miao==60){miao=0;fen++;if(fen==99){fen=0;}}}}}}Screen.c:#include "reg52.h"#include "macroconst.h"#include "delay.h"#include "18b20.h"#include "atao_12864.h"#include "ds1302.h"#include "24c02.h"#include "festival.h"#include "keyscan.h"idata unsigned char miao=0,fen=78,xiaomiao=0,tt=0;idata unsigned char bai,shi,ge,shinian,genian,shiyue,geyue,shiri,geri,shishi,geshi,shifen,gefen,shimi ao,gemiao;idata unsigned char Number[4];unsigned char code mainmenu[]={" 主菜单""3.查询 4.温度""1.调时 2.秒表""5.设置 6.返回"};unsigned char code setmenu[]={" 设置""3.查温 4.按键""1.界面 2.闹铃""5.报时 6.返回"};void gettime(){shinian=(time_buf1[1]%100)/10;genian=(time_buf1[1]%100)%10;shiyue=(time_buf1[2])/10;geyue=(time_buf1[2])%10;shiri=(time_buf1[3])/10;geri=(time_buf1[3])%10;shishi=(time_buf1[4])/10;geshi=(time_buf1[4])%10;shifen=(time_buf1[5])/10;gefen=(time_buf1[5])%10;shimiao=(time_buf1[6])/10;gemiao=(time_buf1[6])%10;}void screen_select(uchar num){// initina1();gettime() ;if(num==1) //----------主界面{Lcd_Set_Post(1,0);TransferData(shinian+48,1);//----------------------年TransferData(genian+48,1);TransferData('/',1);TransferData(shiyue+48,1);//----------------------月TransferData(geyue+48,1);TransferData('/',1);TransferData(shiri+48,1);//----------------------日TransferData(geri+48,1);Lcd_Set_Post(1,4);if(state[1]==1)//----------------闹铃的状态图标{TransferData(' ',1);TransferData(14,1);}Lcd_Set_Post(1,5);if(key_sound==1){TransferData(13,1);}if(state[0]==0){Lcd_Set_Post(1,7); //----------------农历年nian(0);Lcd_Set_Post(2,0);//----------------------- 农历日月LCD_WRITE_CHAR("农历");Conversion(0,time_buf[1],time_buf[2],time_buf[3]);TransferData(month_moon/16+'0',1);TransferData(month_moon%16+'0',1);TransferData('/',1);TransferData(day_moon/16+'0',1);TransferData(day_moon%16+'0',1);}if(state[0]==1){Lcd_Set_Post(3,5);}else {Lcd_Set_Post(2,5);}LCD_WRITE_CHAR("星期");//----------------------星期if(time_buf1[7]==7) {LCD_WRITE_CHAR("日");}if(time_buf1[7]==6) {LCD_WRITE_CHAR("六");}if(time_buf1[7]==5) {LCD_WRITE_CHAR("五");}if(time_buf1[7]==4) {LCD_WRITE_CHAR("四");}if(time_buf1[7]==3) {LCD_WRITE_CHAR("三");}if(time_buf1[7]==2) {LCD_WRITE_CHAR("二");}if(time_buf1[7]==1) {LCD_WRITE_CHAR("一");}Lcd_Set_Post(3,0);TransferData(shishi+48,1);//----------------------时TransferData(geshi+48,1);TransferData(58,1);TransferData(shifen+48,1);//----------------------分TransferData(gefen+48,1);TransferData(58,1);TransferData(shimiao+48,1);//----------------------秒TransferData(gemiao+48,1);if(state[0]==0){bai=(temph/100); //---------------------------------温度shi=(temph%100)/10;ge=(temph%100)%10;Lcd_Set_Post(3,4);if(zerotemp==0){TransferData(' ',1);TransferData(' ',1);} Lcd_Set_Post(3,5);TransferData(shi+48,1);TransferData(ge+48,1);TransferData('.',1);TransferData(templ+48,1);TransferData(0xa1,1);TransferData(0xe6,1);Lcd_Set_Post(4,0);festival(time_buf[2],time_buf[3],time_buf[4]);//农历}}if(num==3)//----------主菜单{Lcd_Set_Post(1,0);//--------设置显示位置LCD_WRITE_CHAR(mainmenu);}if(num==4)//----------设置菜单{Lcd_Set_Post(1,0);//--------设置显示位置LCD_WRITE_CHAR(setmenu);}if(num==5)//----------时间设置{Lcd_Set_Post(1,2);//--------设置显示位置LCD_WRITE_CHAR("时间设置");Lcd_Set_Post(2,1);TransferData(shinian+48,1);//----------------------年TransferData(genian+48,1);LCD_WRITE_CHAR("年");TransferData(shiyue+48,1);//----------------------月TransferData(geyue+48,1);LCD_WRITE_CHAR("月");TransferData(shiri+48,1);//----------------------日TransferData(geri+48,1);LCD_WRITE_CHAR("日");TransferData(time_buf1[7]+48,1);//---------------星期Lcd_Set_Post(3,2);TransferData(shishi+48,1);//--------------------时TransferData(geshi+48,1);LCD_WRITE_CHAR("时");TransferData(shifen+48,1);//---------------------分TransferData(gefen+48,1);LCD_WRITE_CHAR("分");TransferData(shimiao+48,1);//--------------------秒TransferData(gemiao+48,1);}if(num==6)//----------秒表{uchar shi1,shi2,shi3,ge1,ge2,ge3;Lcd_Set_Post(1,3);//--------设置显示位置LCD_WRITE_CHAR("秒表");Lcd_Set_Post(3,2);shi1=fen/10;ge1=fen%10;TransferData(shi1+48,1);TransferData(ge1+48,1);TransferData(':',1);shi2=miao/10;ge2=miao%10;TransferData(shi2+48,1);TransferData(ge2+48,1);TransferData(':',1);shi3=xiaomiao/10;ge3=xiaomiao%10;TransferData(shi3+48,1);TransferData(ge3+48,1);}if(num==8){Lcd_Set_Post(1,2);//--------农历查询LCD_WRITE_CHAR("温度查询");Lcd_Set_Post(3,0);//--------农历查询LCD_WRITE_CHAR("最高温度"); TransferData(':',1);RdFromROM(Number,0,4);if(Number[3]==0){TransferData('-',1);}Lcd_Set_Post(3,5);TransferData(Number[0]+48,1); TransferData(Number[1]+48,1); TransferData('.',1);TransferData(Number[2]+48,1); TransferData(0xa1,1);TransferData(0xe6,1); Lcd_Set_Post(4,0);//--------农历查询LCD_WRITE_CHAR("最低温度"); TransferData(':',1);RdFromROM(Number,4,4);if(Number[3]==0){TransferData('-',1);}Lcd_Set_Post(4,5);TransferData(Number[0]+48,1); TransferData(Number[1]+48,1); TransferData('.',1);TransferData(Number[2]+48,1); TransferData(0xa1,1);TransferData(0xe6,1); }if(num==9)//----------界面菜单{Lcd_Set_Post(1,2);//--------设置显示位置LCD_WRITE_CHAR("界面选择");Lcd_Set_Post(2,0);TransferData(1+48,1);TransferData('.',1);LCD_WRITE_CHAR("多功能界面");Lcd_Set_Post(3,0);TransferData(2+48,1);TransferData('.',1);LCD_WRITE_CHAR("简洁界面");}。
自己制作的单片机万年历程序+原理图
自己制作的单片机万年历程序+原理图单片机万年历仿真原理图如下仿真Altium Designer画的万年历原理图和PCB图如下:PCB原理图基于51单片机,可以完成时钟显示、公历显示、农历显示、温度显示、闹钟报警定时的LCD时钟PPT内容预览:本设计使用AT89C51来做主控芯片,其强大的功能足够实现我们设计的所有功能。
使用LCD1602的液晶显示器来进行显示。
使用Keil uVision5进行编程。
通过Proteus8.6来进行仿真。
点击一次K1进入时钟设置页面,通过点击K2切换时、秒、分、星期、年、月、日,通过K3与K4实现加减来完成时钟的设置点击两次K1进入闹钟设置页面,通过点击K2切换开关、时、秒、分,通过K3与K4实现加减完成闹钟的设置。
单片机源程序如下注释是很全的#include //调用单片机头文件#define uchar unsigned char //无符号字符型宏定义变量范围0~255#define uint unsigned int //无符号整型宏定义变量范围0~65535#include "eeprom52.h"#include "nongli.h"#include "intrins.h"bit flag_200ms ;bit flag_100ms ;sbit beep = P3^7; //蜂鸣器定义bit flag_beep_en;uint clock_value; //用作闹钟用的sbit dq = P3^1; //18b20 IO口的定义uint temperature ; //温度变量uchar flag_nl; //农历阳历显示标志位uchar menu_1,menu_2;uchar key_time,flag_value; //用做连加的中间变量bit key_500ms ;uchar n_nian,n_yue,n_ri; //农历显示的函数#include "ds1302.h"#include "lcd1602.h"/******************把数据保存到单片机内部eeprom中******************/void write_eeprom(){SectorErase(0x2000);byte_write(0x2000, fen1);byte_write(0x2001, shi1);byte_write(0x2002, open1);byte_write(0x2058, a_a);}/******************把数据从单片机内部eeprom中读出来*****************/void read_eeprom(){fen1 = byte_read(0x2000);shi1 = byte_read(0x2001);open1 = byte_read(0x2002);a_a = byte_read(0x2058);}/**************开机自检eeprom初始化*****************/void init_eeprom(){read_eeprom(); //先读if(a_a != 1) //新的单片机初始单片机内问eeprom{fen1 = 3;shi1 = 8;a_a = 1;write_eeprom(); //保存数据}}/***********************18b20初始化函数*****************************/void init_18b20(){bit q;dq = 1; //把总线拿高delay_uint(1); //15usdq = 0; //给复位脉冲delay_uint(80); //750usdq = 1; //把总线拿高等待delay_uint(10); //110usq = dq; //读取18b20初始化信号delay_uint(20); //200usdq = 1; //把总线拿高释放总线}/*************写18b20内的数据***************/void write_18b20(uchar dat){uchar i;for(i=0;i<8;i++){ //写数据是低位开始dq = 0; //把总线拿低写时间隙开始dq = dat & 0x01; //向18b20总线写数据了delay_uint(5); // 60usdq = 1; //释放总线}}/*************读取18b20内的数据***************/uchar read_18b20(){uchar i,value;for(i=0;i<8;i++){dq = 0; //把总线拿低读时间隙开始value >>= 1; //读数据是低位开始dq = 1; //释放总线if(dq == 1) //开始读写数据value |= 0x80;delay_uint(5); //60us 读一个时间隙最少要保持60us 的时间}return value; //返回数据}/*************读取温度的值读出来的是小数***************/uint read_temp(){uint value;uchar low; //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序init_18b20(); //初始化18b20write_18b20(0xcc); //跳过64位ROMwrite_18b20(0x44); //启动一次温度转换命令delay_uint(50); //500usinit_18b20(); //初始化18b20write_18b20(0xcc); //跳过64位ROMwrite_18b20(0xbe); //发出读取暂存器命令EA = 0;low = read_18b20(); //读温度低字节value = read_18b20(); //读温度高字节EA = 1;value <<= 8; //把温度的高位左移8位value |= low; //把读出的温度低位放到value的低八位中value *= 0.625; //转换到温度值小数return value; //返回读出的温度带小数}/******************1ms 延时函数*******************/void delay_1ms(uint q){uint i,j;for(i=0;i<>< p=""><>for(j=0;j<120;j++);}/******************写星期函数*******************/void write_week(uchar hang,uchar add,uchar week)//写星期函数{if(hang==1)write_com(0x80+add);elsewrite_com(0x80+0x40+add);。
单片机课程设计(论文)电子万年历的设计
目录1设计要求 (2)2方案论证与对比 (2)液晶显示器控制方式选择 (2)2.2并行接口动态显示电路选择 (2)2.3LCD液晶显示器的接口方法选择 (3)液晶显示器限流电阻选择 (4)3系统硬件电路的设计 (5)主控模块AT89C52 (5)3.2显示模块电路设计 (6)4系统软件设计 (7)4.1系统软件概述 (7)4.2主要子程序设计 (8)4.2.1 时钟中断服务子程序设计 (8)时间调整子程序设计 (9)4.2.3 判断闰年子程序设计 (9)4.2.4 精度分析分析与计算 (10)4.2.5 第一次初值的设置 (10)4.2.6 重载初值的方法 (10)5系统仿真与测试 (11)5.1系统仿真 (11)功能测试 (11)6总结 (12)参考文献 (13)1设计要求本课题以AT89C52单片机为核心,设计并制作出智能LCD电子钟,具有以下基本功能:能进行时间、年份、日期、星期显示;能区分是否闰年;能检测室温并显示。
扩展功能部分可以通过控制按键使时间暂停、可以调整校正时间并通过按键切换轮流显示时间、年份、日期、星期。
2方案论证与对比2.1液晶显示器控制方式选择采用LCD液晶显示,具有超精致影像画质、十足平面显示、节省空间、节省能源等优点,但按控制方式不同,LCD可分为被动矩阵式LCD及主动矩阵式LCD两种。
可根据不同需要采用不同的方式。
方案一被动矩阵式LCD被动矩阵式LCD在亮度及可视角方面受到较大的限制,反应速度也较慢。
由于画面质量方面的问题,使得这种显示设备不利于发展为桌面型显示器,但成本低廉。
方案二主动矩阵式LCD目前应用比较广泛的主动矩阵式LCD,也称TFT-LCD(Thin Film Transistor-LCD,薄膜晶体管LCD)。
TFT液晶显示器是在画面中的每个像素内建晶体管,可使亮度更明亮、色彩更丰富及更宽广的可视面积。
与CRT显示器相比,LCD显示器的平面显示技术体现为较少的零件、占据较少的桌面及耗电量较小,但CRT技术较为稳定成熟。
51单片机课程设计——电子万年历
电子万年历的设计学院计算机与控制工程学院专业班级自动化学生姓名指导教师2010年6月25日引言随着社会、科技的发展,人类得知时间,从观太阳、摆钟到现在电子钟,不断研究、创新。
为了在观测时间的同时,能够了解其它与人类密切相关的信息,比如温度、星期、日期等,电子万年历诞生了,它集时间、日期、星期和温度功能于一身,具有读取方便、显示直观、功能多样、电路简洁等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
二十一世纪的今天,最具代表性的计时产品就是电子万年历,它是近代世界钟表业界的第三次革命。
第一次是摆和摆轮游丝的发明,相对稳定的机械振荡频率源使钟表的走时差从分级缩小到秒级,代表性的产品就是带有摆或摆轮游丝的机械钟或表。
第二次革命是石英晶体振荡器的应用,发明了走时精度更高的石英电子钟表,使钟表的走时月差从分级缩小到秒级。
第三次革命就是单片机数码计时技术的应用(电子万年历),使计时产品的走时日差从分级缩小到1/600万秒,从原有传统指针计时的方式发展为人们日常更为熟悉的夜光数字显示方式,直观明了,并增加了全自动日期、星期、温度以及其他日常附属信息的显示功能,它更符合消费者的生活需求!因此,电子万年历的出现带来了钟表计时业界跨跃性的进步……我国生产的电子万年历有很多种,总体上来说以研究多功能电子万年历为主,使万年历除了原有的显示时间,日期等基本功能外,还具有闹铃,报警等功能。
商家生产的电子万年历更从质量,价格,实用上考虑,不断的改进电子万年历的设计,使其更加的具有市场。
本设计主要采用AT89C51单片机作为主控核心,由DS1302时钟芯片提供时钟、LED 动态扫描显示屏显示。
AT89C51单片机是由Atmel公司推出的,功耗小,电压可选用4~6V电压供电;DS1302时钟芯片是美国DALLAS公司推出的具有涓细电流充电功能的低功耗实时时钟芯片,它可以对年、月、日、星期、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小;数字显示是采用的LED液晶显示屏来显示,可以同时显示年、月、日、星期、时、分、秒和温度等信息。
单片机课程设计-年月日时分秒设计(汇编语言)带Proteus图
//////////时间控制器/////////////////////////////////////////////***********************************************/ SEC EQU 30HMIN EQU 31HHOUR EQU 32HDAY EQU 33HMONTH EQU 34HYEAR EQU 35HAMIN EQU 36HAHOUR EQU 37HLEDMIN EQU 38HLEDHOUR EQU 39HS_SET BIT P1.0//秒的调整按键M_SET BIT P1.1//分的调整按键H_SET BIT P1.2//时的调整按键D_SET BIT P1.3//日的调整按键MONTH_SET BIT P1.4//月的调整按键Y_SET BIT P1.5//年的调整按键CLRR BIT P1.6//清0的按键TIME BIT P3.6//闹钟的按键LED BIT P3.7//LED的按键/***********************************************/ORG 0000HLJMP MAINORG 000BH//定时器0入口LJMP INT_T0//定时器中断程序ORG 0010H/***********************************************/ MAIN:MOV DPTR,#TABLEMOV SEC,#0MOV MIN,#0MOV HOUR,#0MOV DAY,#1MOV MONTH,#1MOV YEAR,#0MOV AMIN,#0MOV AHOUR,#12MOV LEDMIN,#30MOV LEDHOUR,#6MOV R0,#0MOV TMOD,#01H //模式1MOV TH0,#3CH ; 设置初值(定时50毫秒)MOV TL0,#0B0HSETB TR0 ;启动定时SETB ET0SETB EA;***************************************************** ;判断是否有控制键按下A0:LCALL ALARM//比较当前时间与闹钟的时间//LCALL ALARM1 //整点报时LCALL LED_L //比较当前时间与设置的LED亮的时间LCALL DISPLAYJNB S_SET,S1 //按下就跳转JNB M_SET,S2 //按下就跳转JNB H_SET,S3 //按下就跳转JNB D_SET,S4 //按下就跳转JNB MONTH_SET,TIAO_S5 //按下就跳转JNB Y_SET,TIAO_S6 //按下就跳转JNB CLRR,TIAO_S7 //按下就跳转JNB TIME,TIAO_S8//按下就跳转JNB LED,TIAO_S9//按下就跳转LJMP A0TIAO_S5:LJMP S5TIAO_S6:LJMP S6TIAO_S7:LJMP S7TIAO_S8:LJMP S8TIAO_S9:LJMP S9//秒调整S1:LCALL DELAY ;去抖动JB S_SET,A0INC SEC ;秒值加1MOV A,SECCJNE A,#60,J0 ;判断是否加到60秒MOV SEC,#0LJMP J0;************************************ ;等待按键抬起J0:JB S_SET,A0LCALL DISPLAYLJMP J0//分调整S2:LCALL DELAY;去抖动JB M_SET,A0K1: INC MIN ;分钟值加1MOV A,MINCJNE A,#60,J1 ;判断是否加到60分MOV MIN,#0LJMP J1;************************************ ;等待按键抬起J1:JB M_SET,A0LCALL DISPLAYLJMP J1//时调整S3:LCALL DELAY;去抖动JB H_SET,A0K2: INC HOUR ;小时值加1MOV A,HOURCJNE A,#24,J2 ;判断是否加到24小时MOV HOUR,#0LJMP J2;************************************ ;等待按键抬起J2:JB H_SET,TIAO_A0LCALL DISPLAYLJMP J2TIAO_A0:LJMP A0//日调整S4:LCALL DELAY;去抖动JB D_SET,TIAO_A0K3: INC DAY ;日值加1MOV A,DAYCJNE A,#31,J3 ;判断是否加到30日MOV DAY,#1LJMP J3;************************************ ;等待按键抬起J3:JB D_SET,TIAO_A0LCALL DISPLAYLJMP J3//月调整S5:LCALL DELAY;去抖动JB MONTH_SET,TIAO_A0K4: INC MONTH ;月值加1MOV A,MONTHCJNE A,#13,J4 ;判断是否加到12月MOV MONTH,#1LJMP J4;************************************ ;等待按键抬起J4:JB MONTH_SET,TIAO_A0LCALL DISPLAYLJMP J4//年调整S6:LCALL DELAY;去抖动JB Y_SET,TIAO_A0K5: INC YEAR ;年值加1MOV A,YEARCJNE A,#100,J5 ;判断是否加到100年MOV YEAR,#0SJMP J5;************************************ ;等待按键抬起J5:JB Y_SET,TIAO_A0LCALL DISPLAYLJMP J5//清0S7:LCALL DELAY;去抖动JB CLRR,TIAO_A0MOV YEAR,#0MOV MONTH,#1MOV DAY,#1MOV HOUR,#0MOV MIN,#0MOV SEC,#0MOV AHOUR,#12MOV AMIN,#0MOV LEDHOUR,#6MOV LEDMIN,#30LJMP J6;************************************ ;等待按键抬起J6://JB CLRR,A0JB CLRR,TIAO_A0LCALL DISPLAYLJMP J6TIAO_A00:LJMP A0TIAO_S812:LJMP S8////////////////////////闹钟按键调整/////////////////S8:JB TIME,TIAO_A00JNB M_SET,S81 //按下就跳转JNB H_SET,S82 //按下就跳转LCALL TIME_DISPLAY//闹钟分调整S81:LCALL DELAY;去抖动JB M_SET,TIAO_S812K71:INC AMIN ;闹钟分钟值加1MOV A,AMINCJNE A,#60,J71 ;判断是否加到60分MOV AMIN,#0LJMP J71;************************************ ;等待按键抬起J71:JB M_SET,TIAO_S812LCALL TIME_DISPLAYLJMP J71//闹钟时调整S82:LCALL DELAY;去抖动JB H_SET,TIAO_S812K72: INC AHOUR ;闹钟小时值加1MOV A,AHOURCJNE A,#24,J72 ;判断是否加到24小时MOV AHOUR,#0LJMP J72;************************************ ;等待按键抬起J72:JB H_SET,TIAO_S812LCALL TIME_DISPLAYLJMP J72TIAO_A000:LJMP A0TIAO_S912:LJMP S9////////////////////////LED按键调整//////////////////////S9:JB LED,TIAO_A000JNB M_SET,S91 //按下就跳转JNB H_SET,S92 //按下就跳转LCALL LED_DISPLAY//LED分调整S91:LCALL DELAY;去抖动JB M_SET,TIAO_S912K81:INC LEDMIN ;LED分钟值加1MOV A,LEDMINCJNE A,#60,J81 ;判断是否加到60分MOV LEDMIN,#0LJMP J81;************************************ ;等待按键抬起J81:JB M_SET,TIAO_S912LCALL LED_DISPLAYLJMP J81//LED时调整S92:LCALL DELAY;去抖动JB H_SET,TIAO_S912K82: INC LEDHOUR ;LED小时值加1MOV A,LEDHOURCJNE A,#24,J82 ;判断是否加到24小时MOV LEDHOUR,#0LJMP J82;************************************ ;等待按键抬起J82:JB H_SET,TIAO_S912LCALL LED_DISPLAYLJMP J82/******************闹钟*************************************/ ALARM:JNB TIME,ALARM_CLOSEMOV A,HOUR ;比较小时CJNE A,37H,TIAO_RET ;不等返回。
单片机课程设计报告(万年历)
目录一、摘要 (2)二、设计任务 (4)三、总体方案设计与论证 (4)1、液晶显示模块 (4)2、实时时间计算模块 (5)3、实时环境温度采集模块 (5)4、报警模块 (6)5、设置模块 (6)四、总体方案组成框图 (7)五、系统硬件设计 (8)1、LCD显示模块 (8)2、实时时间计算模块 (12)3、实时环境温度检测模块 (16)4、报警模块 (21)5、设置模块 (22)六、系统软件设计 (23)七、系统硬件电路设计 (24)八、系统硬件PROTEUS仿真原理图 (25)九、系统硬件仿真运行情况图 (26)1、显示欢迎界面 (26)2、显示实时时间 (26)3、显示当前温度 (27)4、时间设置 (27)5、最高报警温度设置 (28)6、闹钟时间设置 (28)7、超温 (29)8、闹钟时间到 (29)附录一:实物图 (30)附录二:PCB图 (32)附录三:源程序代码 (33)附录四:参考文献 (62)摘要单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。
单片机接上晶振、复位电路和相应的接口电路,装载软件后就可以构成单片机应用系统。
将它嵌入到形形色色的应用系统中,就构成了众多产品、设备的智能化核心。
本设计就是应用单片机强大的控制功能制作而成的电子万年历,该电子万年历包括三大功能:实时显示年、月、日、时、分、秒;实时监测环境温度(可根据需要启动高温报警功能);电子闹钟。
M bn本设计采用的是AT89S52单片机,该单片机采用的MCU51内核,因此具有很好的兼容性,内部带有8KB的ROM,能够存储大量的程序,最突出特点是具有ISP在系统烧写功能,使得烧写程序更加方便。
计时芯片采用DALLAS公司的涓细充电时钟芯片DS1302,该芯片通过简单的串行通信与单片机进行通信,时钟/日历电路能够实时提供年、月、日、时分、秒信息,采用双电源供电,当外部电源掉电时能够利用后备电池准确计时。
温度检测采用DALLAS公司的数字化温度传感器,该芯片采用的是独特的“一线总线”的方式与单片机进行通信,一线总线独特而且经济的特点,是用户可以轻松的组建传感器网络,为测量系统的构建引入全新的概念。
基于51单片机汇编语言的数字钟课程设计报告(含有闹钟万年历)
单片微型计算机课程设计报告多功能电子数字钟姓 名 许伟敏学 号 060301021124班 级 电气二班指导教师 林卫2009-06-25目录一:概述 (1)二:设计基本原理简介 (2)三:设计要求及说明 (3)四:整体设计方案 (4)系统硬件电路设计 4系统软件总流程设计 5模块划分及分析 6五:单模块流程设计 (8)各模块设计概述、流程图 8模块源程序集合及注释 13六:单模块软件测试 (23)七:系统检测调试 (24)硬件电路调试软件部分烧写调试八:系统优化及拓展 (26)九:心得体会 (28)单片微型计算机课程设计 基于汇编语言的电子数字钟 概述课程设计流程图↑一、概述课程设计题目:电子数字钟应用知识简介:● 51单片机单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。
作为嵌入式系统控制核心的单片机具有其体积小、功能全、性价比高等诸多优点。
51系列单片机是国内目前应用最广泛的单片机之一,随着嵌入式系统、片上系统等概念的提出和普遍接受及应用,51系列单片机的发展又进入了一个新的阶段。
在今后很长一段时间内51系列单片机仍将占据嵌入式系统产品的中低端市场。
● 汇编语言汇编语言是一种面向机器的计算机低级编程语言,通常是为特定的计算机或系列计算机专门设计的。
汇编语言保持了机器语言的优点,具有直接和简捷的特点,其代码具有效率高实时性强等优点。
但是对于复杂的运算或大型程序,用汇编语言编写将非常耗时。
汇编语言可以与高级语言配合使用,应用十分广泛。
● ISPISP (In-System Programming )在系统可编程,是当今流行的单片机编程模式,指电路板上的空白元器件可以编程写入最终用户代码,而不需要从电路板上取下元器件。
已经编程的器件也可以用ISP 方式擦除或再编程。
本次课程设计便使用ISP 方式,直接将编写好的程序下载到连接好的单片机中进行调试。
数字电子钟设计(原理图+pcb图+程序)--课程设计.docx
1设计课题任务、功能要求说明及方案介绍1.1设计课题任务与要求设计一个具有特定功能的电子钟。
该电子钟上电或按键复位后能自动显示学 生班级学号,进入时钟准备状态;第一次按电子钟启动/调整键,电子钟从0时 0分0秒开始运行,进入时钟运行状态;再次按电子钟启动/调整键,则电子钟 进入时钟调整状态,此时可利用各调整键调整时间,调整结束后可按启动/调整 键再次进入吋钟运行状态。
1.2设计课题总体方案介绍及工作原理说明本电子钟主要由单片机、4个独立键盘、显示接口电路和复位电路构成,设 计课题的系统框图如图1. 1所示:图1.1系统框图本电子钟的所有的程序、参数均存放在AT89S52的Flash ROM 和内部RAM 中。
键盘采用动态扫描方式。
利用单片机定时器及计数器产生定时效果通过编程 形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据,同时通过 端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。
晶振电路复位电路数码管驱动数码管LED2设计课题硬件系统的设计2.1设计课题硬件系统各模块功能简要介绍本设计的硬件系统主要采用以下基本模块来实现,单片机最小系统模块,输入模块、输出模块、电源模块(1 )单片机最小系统模块:AT89S52单片机芯片;复位电路;晶振电路。
本模块AT89S52系统控制核心,单片机系统复位由按键电平复位电路完成,通过按键S1来控制,单片机通过芯片引脚XTAL1、XTAL2,外并接石英晶体振荡器和两只电容。
这样就为能为单片机提供频率为12MHz的晶振。
(2)输入模块:本模块共用到了5个按键,1个电源开关,1个复位键,单片机运行期间,利用按键S1完成复位操作。
4个独立按键,S2键控制电子钟的启动/调整状态,S3键为小时调整键,S4键为分钟调整键,S5键位秒调整键,且 S2、S3、S4、S5 任一键都独自连一个I/O (Pl.O、P1. 1、P1. 2、P1. 3) 口线,说明它们可以独立实现相应的电子钟功能。
电子实时时钟万年日历系统-单片机课程设计(含电路图、流程图、汇编语言)
一、题目:电子实时时钟/万年日历系统二、功能要求:1.基本要求:⑴显示准确的北京时间(时、分、秒),可用24小时制式;⑵随时可以调校时间。
2.发挥要求:⑴增加公历日期显示功能(年、月、日),年号只显示最后两位;⑵随时可以调校年、月、日;⑶允许通过转换功能键转换显示时间或日期。
三、方案考虑:1、硬件方案:⑴显示器采用6位LED数码管(共阳),可分别显示时间或日期。
⑵显示器的驱动采用动态扫描电路形式,以达到简化电路的目的。
但要注意所需的驱动电流比静态驱动时要大,因此要增加驱动电路。
可采用74LS244或者晶体管;其中74ls244是用来驱动段选码,晶体管是驱动位选码。
⑶采用“一键多用方案”,以减少按键数目。
本方案采用了4按键。
⑷整体上要考虑:结构简单、布局美观、操作方便、成本低廉。
2、设计电路图如下:3、元件清单:(我们使用的是TX-1C开发板)⑴ 89C52 1个⑵IC座(40脚) 3个(其中1个用于接插89C51、2个用于接插LED段数码管)。
⑶ 74LS244 1个(用于驱动6个共阳的LED段数码管)。
⑷ IC座(20脚) 1个(用于接插74LS244)。
(5)显示器:LED_8段数码管(共阳型)6个三极管:(6)PNP(8550)6个(用于驱动6个共阳型LED段数码管)。
(7)微型开关:3个(其中1个用于复位电路、其它用于键盘)。
(8)晶体振荡器(12MHz):1个(用于振荡电路)。
(9)电阻器:⑴ 3KΩ 1个(用于系统复位电路)。
⑵ 1KΩ 6个(用作PNP三极管基极电阻)。
⑶ 100Ω 7个(驱动器用作74LS244输出限流电阻)。
(10)电容器:⑴ 10μF1个(用于系统复位电路)。
⑵ 30 pF 2个(用于系统振荡电路)。
(11)其它:⑴万能电路板(10×15):1块⑵焊锡条: 2米⑶带插头、座的电源端子: 1条⑷各种颜色外皮的导线:各1米(12)工具:1.电烙铁:1把2.剪钳:1把3.镊子:1把4.万用表:1个(13)设备:编程器(MEP300或TOP851)6个4、软件方案:(1)使用全汇编编写(2)时钟基准时间由单片机内部定时中断来提供,定时时间应该乘以一个整数得到,且不宜太长或太短,最长不能超过16位定时器的最长定时时间,最短不能少于定时中断服务程序的执行时间。
单片机万年历程序(带闹钟)
第一章设计方案1.1.硬件设计1.1.1设计要求实现年月日、时分秒、星期的显示功能,用两个按键来实现日期和时间的调整功能,调整要求星期能自动更新,且能实现位调。
显示格式:四位年,两位月,两位日,星期字母前三位,两位时,两位分,两位秒。
比如:YYYY-MM-DD WEEKHH:MM:SS1.1.2硬件框图图1-1-硬件框图日期时间由硬件软件结合产生;按键之间相互配合完成当前日期时间的调整功能。
过程与结果由控制芯片分别输出到显示器上。
本设计附加了播放音乐的功能。
音乐从蜂鸣器产生。
1.1.3硬件选择1).显示模块本设计具体选用与实际应用与消耗资源相关。
万年历用到的地方大多都在室内。
现市场上与许多显示器,在日常生活中最常见的有数码管,led点阵屏,lcd液晶显示器等。
八段数码管的优点:亮度高,显示大。
驱动部份的软件简单;缺点:与液晶相比,耗电及体积大。
数码管只能单纯的显示数字,不能生动的表达各个参数的信息,消耗电力也比led液晶显示器大。
LCD液晶显示器它是一种专门用来显示字母、数字、符号等的点阵型液晶模块,在单片机系统中应用晶液显示器作为输出器件有以下几个优点:显示质量高,由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。
因此,液晶显示器画质高且不会闪烁。
数字式接口,液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。
体积小、重量轻,液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。
功耗低,相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。
Lcd液晶能一屏把本设计所要显示的信息表达完整。
而且lcd耗电小,体积小很适合与室内使用。
本设计的要求日期时间以数字表示、星期用3位英文字符表示共21个字符,lcd1602能显示32个字表 1-1 lcd1602引脚及功能2).按键与蜂鸣器本设计选用轻触按钮,型号为XDJT1102S。
单片机课程设计-万年历
单片机课程设计题目名称:姓名:学号:系别:班级:指导老师:完成时间:华南理工大学广州学院课程设计任务书一、实现功能利用51单片机芯片和DS1302芯片设计电子万年历功能图如下通过四个按键输入调整,在LCD液晶模块上能显示阳历年、月、日、星期、时、分、秒和阴历月、日,在显示农历时间时,能标明是否为闰年。
当切断主5V电源时,由3.3V 备用电池供电,1302内时钟仍然工作。
当重新接上5V电源后,则可以实时显示当前时间。
二、开发环境操作系统:windows XP开发芯片:89C52RC+编译器:keil51三、硬件实现1、整体仿真图如下2、12864LCD12864采用8位并行数据传送方式,占用单片机的P0口。
由于P0口用作普通I/O口时为开漏输出,所以为了输出高电平,增大负载能力,需在每个P0位接一个上拉电阻,本设计中采用10K的排阻接线。
图中的RV1为LCD背光调节电位器,可调节屏幕的亮度。
3、DS13021脚接+5V电源;8脚接3.3V备份电源;2、3脚接晶振;4脚接地;5脚接P2.6;6脚接P2.4;7脚接P2.5;+5V工作时,DS1302的7脚时钟信号由单片机的P2.5口提供,当以3.3V工作时时钟由其2、3脚外接的晶振提供时钟,晶振的震荡频率为32.768KHz。
4、按键选择按键一端接P2.0,另一端接地;加按键一端接P2.1,另一端接地;减按键一端接P3.1,另一端接地;确定按键一端接P3.2,另一端接地;四、软件实现程序流程图如下1、农历为复杂的历法,因此适宜采用查表法进行编程;2、编程中接按键的四个管脚皆为查询方式,单片机上电默认为高电平,当按键按下去的时候变为低电平,输入有效,并执行相应的事件处理程序;3、12864采用8位并行数据传送方式,占用单片机的P0口;4、DS1302位一线串行方式,所以在编程中对时序的要求非常严格,应认真注意时序的先后;主要程序源代码uchar Read1302(uchar ADDRorCOMM){uchar dat;DS1302_RST=0; //禁止数据传输DS1302_SCLK=0; //确保写写之前SCLK被拉低DS1302_RST=1; //启动数据传输DS1302InputByte(ADDRorCOMM); //写入命令或地址dat=DS1302OutputByte(); // 读出数据DS1302_SCLK=1; //将时钟电平置于高电平状态置高是为了让下次写的时候能准确的被拉低保证电平状态的正确性//DS1302_RST=0; //禁止数据传输return(dat);}void Init_1302(void) //(2008年7月12日12时00分00秒星期六){uchar flag;flag=Read1302(0x81); //读秒寄存器if(flag&0x80) //CH为0(flag最高位是0),时钟走动,不用初始化。
单片机课程设计--基于51单片机的万年历
单片机课程设计报告万年历的设计基于51单片机的万年历摘要:电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。
它可以对年、月、日、周日、时、分、秒进行计时,使用寿命长,误差小。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。
该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
本设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。
在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。
万年历的设计过程在硬件与软件方面进行同步设计。
硬件部分主要由AT89C52单片机,LCD显示电路,以及调时按键电路等组成。
在单片机的选择上本人使用了AT89C52单片机,该单片机适合于许多较为复杂控制应用场合。
显示器使用了1602液晶显示,并且使用蜂鸣器实现了整点报警的功能,温度测试的功能实现使用了DS18B20,并实现了温度过高或过低时的温度报警。
软件方面主要包括日历程序、时间调整程序,显示程序等。
程序采用C语言编写。
所有程序编写完成后,在KeilC51软件中进行调试,确定没有问题后,在Proteus软件中嵌入单片机内进行仿真,并最终实现基本要求。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
一、设计要求基本要求:1,8 个数码管上显示,显示时间的格式为(假如当前时间是19:32:20)“19-32-20”;2,具有日历功能;③时间可以通过按键调整。
发挥部分:④具有闹钟功能(可以设定多个)。
二:总体设计电路设计框图系统硬件概述本电路是由AT89S52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由单片机定时功能提供;温度的采集由DS18B20构成,它具有独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯,使用时不需要额外的外围电路。
基于51单片机电子闹钟或万年历的设计课程设计(精)
目录目录 (1)1.项目背景 (3)1.1 项目研究的目的和意义 (3)1.2课题研究的内容 (3)2.方案的选择和和论证 (4)2.1 单片机型号的选择 (4)2.2 按键的选择 (4)2.3 显示器的选择 (4)2.4 计时部分的选择 (5)2.5 发音部分的设计 (5)2.6电路设计最终方案 (5)3. AT89C52单片机简介 (6)3.1单片机基本特性 (6)3.2单片机内部结构图 (6)3.3 单片机I/O引脚结构 (6)3.3.1 P0口 (6)3.3.2 P1口 (7)3.3.3 P2口 (7)3.3.4 P3口 (7)3.4单片机最小系统板 (8)4. 数字电子钟的设计原理和方法 (9)4.1 设计原理 (9)4.2 硬件电路的设计 (9)4.2.1 DS1302时钟芯片 (9)4.2.2 1602 液晶简介 (11)4.2.3 蜂鸣器驱动电路 (12)4.2.4 独立键盘电路 (13)5.软件部分的设计 (14)5.1程序流程图 (14)5.1.1 系统总流程图 (14)5.1.2 DS1302时钟程序流程图 (15)5.1.3 LCD显示程序流程图 (16)5.2程序的设计 (17)5.2.1 DS1302读写程序 (17)5.2.2液晶显示程序 (17)7.心得体会 (20)参考文献 (21)附录一系统原理图 (22)附录二系统程序 (23)1.项目背景1.1 项目研究的目的和意义20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。
时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前的时间。
忘记了要做的事情,当事情不是很重要的时候,这种遗忘无伤大雅。
但是,一旦重要事情,一时的耽误可能酿成大祸。
例如,许多火灾都是由于人们一时忘记了关闭煤气或是忘记充电时间等造成的。
电子实时时钟万年日历系统-单片机课程设计(含电路图、流程图、PCB图、汇编语言)
摘要围绕电子钟系统的设计与开发工作进行研究和实践,详细介绍了电子钟系统的整体结构、硬件设计、软件设计,系统方案以及其的开发和具体实现。
介绍一种基于在系统可编程技术和C51编译器配有集成开发的新型电子钟的设计方法,阐述了其工作原理和软硬件设计。
在硬件上,用KEIL公司的C51大规模集成芯片对其外围电路进行集成,用1片8051实现了几十片分离元件才能实现的功能,几乎将整个系统下载于同一芯片中,实现了所谓的片上系统,从而大大简化了系统结构,增强了系统的可靠性和性价比。
该电子钟特别适用于家庭、办公大楼、公共场所等。
关键词电子钟;单片机;硬件设计;软件设计ABSTRACTAround the electronic clock system design and development of the study and practice, details the electronic clock system overall, hardware design, software design, system solutions as well as the development and implementation. Introduction of a new technology based on in-system programming and C51 compiler equipped with an integrated development of new electronic clock design method, explains how it works and software and hardware design. In the hardware companies with KEIL C51 large-scale integrated circuit chip on its surrounding, to integrate 1 tablet 8051 implementation of scores of tablets separation components to implement functionality, almost the entire system for download on the same chip, implementation of the so-called SOC, thereby greatly simplifies system structure, enhances system reliability and high performance/price ratio. The electronic clock is particularly relevant for home, office buildings and public place, etc.Key words electronic clock; single-chip; hardware; software design目录1 系统总体设计方案 (4)1.1 设计课题任务 (4)1.2 功能要求说明 (4)1.3 总体方案介绍及工作原理 (4)2 硬件系统的设计 (6)2.1 系统各功能模块介绍 (6)2.2 系统电路图 (7)2.3 系统元器件清单 (7)3 软件系统的设计 (8)3.1设计使用单片机资源介绍 (8)3.2 软件系统各功能模块介绍 (8)3.3 软件系统程序流程框图 (9)3.4 软件系统的程序 (10)4 系统的仿真分析及结论 (11)4.1 系统设计的使用说明 (11)4.2 系统设计的仿真结果 (11)4.3 系统的误差分析 (12)4.4 设计体会 (12)4.5 教学建议 (13)参考文献 (14)致谢 (15)附录(1) (16)附录(2) (17)1 系统总体设计方案1.1 设计课题任务设计一个具有特定功能的电子钟。
单片机编程的万年历带仿真图
#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code str1[]="2011-02-28 week7";uchar code str2[]="23:59:55 ";uchar code str3[]="0-22:00 ";uchar code str4[]="0-23:00 ";uchar c1=0,c2=0;//闹钟标志当c1=1或者c2=1时,闹钟才会响sbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;bit s=0,d=1;// s是开光标标志位,d=0时切换到闹钟屏bit jia,jian;uchar code string[]={0x0c,0xc7,0xc4,0xc1,0x89,0x86,0x83,0x8f,0x80,0x83,0x86,0xc0,0xc3,0xc6};//光标位置调节uchar second=58,minute=59,hour=23,month=2,day=28,week=7,count=0;uchar minute1=0,hour1=22,minute2=0,hour2=23;//闹钟uchar t_symbol; //温度的符号位,为1表示负温,为0表示正温uint T;unsigned int year=2011; //0-65535int m=0;sbit key1=P2^3;//按键设置sbit key2=P2^4;//加按键sbit key3=P2^5;//减按键sbit key4=P2^6;//闹钟按键sbit key5=P2^7;//复位键sbit beep=P1^0;//蜂鸣器sbit DQ=P3^3;//温度引脚void delayms(){ uchar i;for(i=0;i<122;i++);void busy_check(){ P0=0xff;RS=0;RW=1;E=1;E=0;while(P0&0x80){E=0;E=1;}delayms();}void write_LCD_com(uchar cmd) {busy_check();E=0;RS=0;RW=0;E=1;P0=cmd;E=0;delayms();}void write_LCD_data(uchar dat){ busy_check();E=0;RS=1;RW=0;E=1;P0=dat;E=0;delayms();}void SET_LCD_pos(uchar x,uchar y) { if(y==0)write_LCD_com(0x80|x);if(y==1)write_LCD_com(0xc0|x);}void show_LCD(uchar *str){ uchar i;for(i=0;i<16;i++)write_LCD_data(str[i]);/****初始化LCD****/void init_LCD(){ write_LCD_com(0x01);write_LCD_com(0x38);write_LCD_com(0x0c);write_LCD_com(0x06);}void delay_18B20(unsigned int i)//延时1-255微秒{while(i--);}uchar ds1820rst() //ds1820复位{ unsigned char g=0;DQ=1; //DQ复位delay_18B20(8); //延时DQ=0; //发送复位脉冲delay_18B20(80); //延时大于480usDQ=1; //DQ拉高delay_18B20(8);g=DQ; //若g=0,则ds1820存在,否则不存在delay_18B20(20);return(g);}uchar ds1820_rd()//读数据{ unsigned char e=0;unsigned char dat = 0; //暂存读取的数据for (e=8;e>0;e--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ==1)dat|=0x80;delay_18B20(10);}return(dat); //返回读取的值}void ds1820wr(uchar wdate)//写数据{unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdate&0x01; //低位在前delay_18B20(10);DQ = 1;wdate>>=1; //准备发送下一位}void read_temp() //读取温度值并转换{uchar a=0,b=0;ds1820rst(); //ds1820复位ds1820wr(0xcc); //跳过读序列号ds1820wr(0x44); //启动温度转换delay_18B20(150);ds1820rst(); //ds1820复位ds1820wr(0xcc); //跳过读序列号ds1820wr(0xbe); //读取温度delay_18B20(150);a=ds1820_rd(); //读出温度的低八位b=ds1820_rd(); //读出温度的高八位T=b;T<<=8;T=T|a;if(T<0x0fff) //比较温度t_symbol=0;else{T=~T+1; //负温度,取反加一t_symbol=1;}T=T*(0.625); //温度值扩大10倍返?位小数}void ds1820_show()//温度值显示{ uchar flagdat,T0,T1,T2;T0=T/100+'0';//十位数T1=T%100/10+'0';//个位数T2=T%10+'0';//小数位read_temp();if(t_symbol==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(T0==0x30){T0=0x20;} //如果十位为0,不显示}/****字符显示****/void zifushow1(){ uchar flagdat,T0,T1,T2;SET_LCD_pos(9,1);write_LCD_data(flagdat);//显示符号位SET_LCD_pos(10,1);write_LCD_data(T0); //显示十位SET_LCD_pos(11,1);write_LCD_data(T1); //显示个位SET_LCD_pos(12,1);write_LCD_data(0xa5); //显示小数点SET_LCD_pos(13,1);write_LCD_data(T2); //显示小数位SET_LCD_pos(15,1);write_LCD_data('C');SET_LCD_pos(14,1);write_LCD_data(0xdf);SET_LCD_pos(7,1);write_LCD_data(second%10+'0');SET_LCD_pos(6,1);write_LCD_data(second/10+'0');SET_LCD_pos(5,1);write_LCD_data(':');SET_LCD_pos(4,1);write_LCD_data(minute%10+'0');SET_LCD_pos(3,1);write_LCD_data(minute/10+'0');SET_LCD_pos(2,1);write_LCD_data(':');SET_LCD_pos(1,1);write_LCD_data(hour%10+'0');SET_LCD_pos(0,1);write_LCD_data(hour/10+'0');SET_LCD_pos(9,0);write_LCD_data(day%10+'0');SET_LCD_pos(8,0);write_LCD_data(day/10+'0');SET_LCD_pos(7,0);write_LCD_data('-');SET_LCD_pos(6,0);write_LCD_data(month%10+'0');SET_LCD_pos(5,0);write_LCD_data(month/10+'0');SET_LCD_pos(4,0);write_LCD_data('-');SET_LCD_pos(3,0);write_LCD_data(year%10+'0');SET_LCD_pos(2,0);write_LCD_data(year/10%10+'0');SET_LCD_pos(1,0);write_LCD_data(year/100%10+'0');SET_LCD_pos(0,0);SET_LCD_pos(11,0);write_LCD_data('w');SET_LCD_pos(12,0);write_LCD_data('e');SET_LCD_pos(13,0);write_LCD_data('e');SET_LCD_pos(14,0);write_LCD_data('k');SET_LCD_pos(15,0);write_LCD_data(week%8+'0');}/*******蜂鸣器*******/void speaker(){if(c1==1)if(hour1==hour&&minute1==minute) beep=!beep;if(c2==1)if(hour2==hour&&minute2==minute) beep=!beep;}/*******闹钟字符显示*******/void zifushow2(){SET_LCD_pos(0,0);write_LCD_data(c1+'0');SET_LCD_pos(1,0);write_LCD_data('-');SET_LCD_pos(2,0);write_LCD_data(hour1/10+'0');SET_LCD_pos(3,0);write_LCD_data(hour1%10+'0');SET_LCD_pos(4,0);write_LCD_data(':');SET_LCD_pos(5,0);write_LCD_data(minute1/10+'0');SET_LCD_pos(6,0);write_LCD_data(minute1%10+'0');SET_LCD_pos(0,1);write_LCD_data(c2+'0');SET_LCD_pos(1,1);write_LCD_data('-');SET_LCD_pos(2,1);SET_LCD_pos(3,1);write_LCD_data(hour2%10+'0');SET_LCD_pos(4,1);write_LCD_data(':');SET_LCD_pos(5,1);write_LCD_data(minute2/10+'0');SET_LCD_pos(6,1);write_LCD_data(minute2%10+'0');}/***时间和日期的行驶*****/void time_date(){ if(second==60){ second=0;minute++;}if(minute==60){ minute=0;hour++ ;}if(hour==24){ hour=0;day++;week++;}if(week==8){ week=1;}if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)//大月份判断{ if(day==32){ month++;day=1;}}if(month==4||month==6||month==9||month==11)//小月份判断{ if(day==31){ day=1;month++; }}if(month==2)//闰年的月份判断{{if(year%400==0||(year%4==0&&year%100!=0)){if(day==30){day=1;month++;}}else{if(day==29){day=1;month++;}}}}if(month==13){year++;month=0;}}/****按键加****/void jiakey(){ key2=1;if(key2==0){delayms();if(key2==0);while(key2==0);{ switch(count){ case 1:second++;if(second==60){second=0;}jia=1;break;case 2:minute++;if(minute==60){minute=0;}jia=1;break;case 3:hour++;if(hour==24){hour=0;}jia=1;break;case 4:day++;week++;if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){if(day==32){day=1;}}if(month==4||month==6||month==9||month==11){if(day==31){day=1;}}if(month==2&&year%4==0&&day==30){;day=1;}if(month==2&&year%4!=0&&day==29){;day=1;}if(week==8){week=1;}jia=1;break;case 5:month++;if(month==13){month=1;}jia=1;break;case 6:year++;if(year==2100){year=2000;}jia=1;break;case 7:if(d==1){week++;if(week==8){week=1;}jia=1;}break;case 8:c1=!c1;jia=1;break;case 9:hour1++;if(hour1==24){hour1=0;}jia=1;break;case 10:minute1++;if(minute1==60){minute1=0;}jia=1;break;case 11:c2=!c2;jia=1;break;case 12:hour2++;if(hour2==24){hour2=0;}jia=1;break;case 13:minute2++;if(minute2==60){minute2=0;}jia=1;break;}}}}/****按键减****/void jiankey(){key3=1;if(key3==0){delayms();if(key3==0)while(key3==0);{switch(count){case 1:second--;if(second==-1){second=59;}jian=1;break;case 2:minute--;if(minute==-1){minute=59;}jian=1;break;case 3:hour--;if(hour==-1){hour=23;}jian=1;break;case 4:day--;week--;if(week==0){week=7;}if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){if(day==32||day==0){day=31;}}if(month==4||month==6||month==9||month==11){if(day>=31||day==0){day=30;}}if(month==2&&year%4==0&&day==0){day=29;}if(month==2&&year%4!=0&&day==0){day=28;}if(month==13||month==0){month=12;}jian=1;break;case 5:month--;if(month==13||month==0){month=12;}jian=1;break;case 6:year--;if(year==1999){year=2099;}jian=1;break;case 7:if(d==1){week--;if(week==0){week=7;}jian=1;}break;case 8:c1=!c1;jian=1;break;case 9:hour1--;if(hour1==-1){hour1=23;}jian=1;break;case 10:minute1--;if(minute1==-1){minute1=59;}jian=1;break;case 11:c2=!c2;jian=1;break;case 12:hour2--;if(hour2==-1){hour2=23;}jian=1;break;case 13:minute2--;if(minute2==-1){minute2=59;}jian=1;break;}}}}/*****闹钟调节按键***********/void clock_key(){key4=1;if(key4==0){ delayms();if(key4==0)while(key4==0);{ d=~d;init_LCD();if(d==1)count=0;if(d==0)count=8;}}}/*****暂停调节并运行按键******/void zantingkey(){ key5=1;if(key5==0){delayms();if(key5==0);while(key5==0);{ s=0;count=0;}}}/***按键的设置*******/void keyset(){key1=1;if(key1==0){delayms();if(key1==0)while(key1==0);{s=1;count=count+1;}}}/****光标的移动显示****/void guangbiao(){if(s==1){write_LCD_com(string[count]);write_LCD_com(0x0f);delayms();write_LCD_com(0x0c);delayms();}}/****按键的运行****/void keyrun(){keyset();jiakey();jiankey();clock_key();zantingkey();if(d==1&&count>=8)count=1;if(d==0&&count==14)count=8; guangbiao();if(jia==1||jian==1){ time_date();jia=0;jian=0;}}/*****主函数*************/void main(){ if(d==1){init_LCD();write_LCD_com(0x80);show_LCD(str1);write_LCD_com(0xc0);show_LCD(str2);}if(d==0){ init_LCD();write_LCD_com(0x80);show_LCD(str3);write_LCD_com(0xc0);show_LCD(str4);}TMOD=0x01;TH0=0x3c;TL0=0xb0;EA=1;ET0=1;TR0=1;while(1){if(key1==0){TR0=0;}if(key5==0){TR0=1;}keyrun();time_date();speaker();if(d==1){zifushow1();}else{zifushow2();}read_temp();ds1820_show();}}void serve_0(void) interrupt 1 using 0 { TH0=0x3c;TL0=0xb0;m++;if(m==20){ second++;m=0;}}。
日历时钟单片机课程设计附汇编程序方案图模块图ddb模拟图样本
;山东科技大学信电通信07-1 lfj 作品方案一:方案二:采用方案二。
模块图; ------------------------- 按键说明-------------------------;--------------------------1键——进入可调状态-------------------------; -------------------------2键——结束返回-------------------------; -------------------------3键——秒加1/日加1 -------------------------; -------------------------4键——分加1/月加1 -------------------------; -------------------------5键——显示24小时制/时加1/年加1-------------------------; -------------------------6键——显示12小时制-------------------------; -------------------------7键——可调时间-------------------------; -------------------------8键——可调日期-------------------------CLK BIT P1.6 ;时钟信号端DISP BIT P1.7 ;串出锁存端DBUF EQU 30H ;秒的最低位地址LED BIT P1.1CHANGE2 BIT 21H ;加12的标志位AD1 EQU 40H ;秒AD2 EQU 41H ;分AD3 EQU 42H ;时AD4 EQU 43H ;天AD5 EQU 44H ;月AD6 EQU 45H ;年; 初始化存储单元结束ORG 0000HLJMP MAINORG 000BH ;T0中断入口LJMP INTORG 0030HMAIN: MOV R0,#AD1MOV R7,#06HLOOP0: MOV A,#00HMOV @R0,AINC R0DJNZ R7,LOOP0 ;R0~R7清零MOV AD1,#37HMOV AD2,#22HMOV AD3,#0CHMOV AD4,#08HMOV AD5,#08HMOV AD6,#08H ;初始化时间为12: 34: 56, 日期为 08月08日MOV IE,#82H ;允许T0中断MOV TMOD,#01H ;T0允许工作MOV TH0,#4CHMOV TL0,#00H ;送入计数初值0.05sMOV R5,#00H;初始化结束SETB TR0 ;T0使能LOOP: LCALL TEST ;扫描键盘 CJNE A,#0FEH,NEXTD ;0FEH为1键LCALL DY1MSLCALL KEYDONENEXTD: SJMP LOOP ;扫描键盘看是否需要调整日历DISPLAY: LCALL TEST ;扫描键盘 CJNE A,#0DFH,ERSHISI1 ;0DFH为6键SETB PSW.1 ;显示十二小时LJMP TIMEZHUANERSHISI1:CJNE A,#0EFH,ERSHISI2 ;0EFH为5键CLR PSW.1 ;显示二十四小时CLR CHANGE2LJMP TIMEZHUANERSHISI2:CJNE A,#0CFH,CHANGE ;0CFH为5+6键CLR PSW.1SETB CHANGE2 ;CHANGE2=1表示把十二表示法转换成二十四小时LJMP TIMEZHUANCHANGE: CLR CHANGE2TIMEZHUAN:LCALL TESTCJNE A,#7FH,NEXTL ;7FH为8键SETB PSW.5LJMP ZHUAN1NEXTL: CJNE A,#0BFH,ZHUAN1 ;0BFH为7键 CLR PSW.5ZHUAN1: JB PSW.5,DAY ;PSW.5=0 调整时间, 为1则调整日期MOV A,AD1 ;调整时间键码分离MOV B,#0AHDIV ABMOV R0,#DBUFMOV @R0,BINC R0MOV @R0,AMOV A,AD2MOV B,#0AHDIV ABINC R0MOV @R0,BINC R0MOV @R0,AJB PSW.1,TIMEZHUAN1LJMP TIMEZHUAN2TIMEZHUAN1: ;判断时间是否大于12MOV A,AD3MOV B,#0CHSUBB A,BJC NORMALTMOV AD3,ALJMP NORMALTTIMEZHUAN2:JNB CHANGE2,NORMALT ;判断是否加12MOV A,AD3ADD A,#MOV AD3,ACLR CHANGE2NORMALT: MOV A,AD3MOV B,#0AHDIV ABINC R0MOV @R0,BINC R0MOV @R0,ASJMP DDISPDAY: ;调整日期键码分离MOV A,AD4MOV B,#0AHDIV ABMOV R0,#DBUFMOV @R0,BINC R0MOV @R0,AMOV A,AD5MOV B,#0AHDIV ABINC R0MOV @R0,BINC R0MOV @R0,AMOV A,AD6MOV B,#0AHDIV ABINC R0MOV @R0,BINC R0MOV @R0,ADDISP: ;显示, 串入并处的方式, 上升沿写入MOV R0,#DBUFMOV R7,#06HLOOP2:MOV R6,#08HMOV A,@R0MOV DPTR,#TABMOVC A,@A+DPTR ;显示秒CLR CLOOP3:RRC ACLR CLKMOV DISP,CSETB CLKDJNZ R6,LOOP3INC R0DJNZ R7,LOOP2RETKEYDONE: ;人工手动调整日历AGAINB: LCALL DY250MS ;防抖250ms LCALL TESTCJNE A,#7FH,NEXTL1 ;7FH为8键SETB PSW.5LJMP ZHUAN12NEXTL1:CJNE A,#0BFH,ZHUAN12CLR PSW.5 ;以上为扫描键盘并设置PSW.5ZHUAN12:JB PSW.5,NEXT6B ;判断调整日期还是时间CJNE A,#0FDH,NEXTA ;0FDH为2键,如果按键值为FDH则结束LJMP BACKNEXTA: CJNE A,#0FBH,NEXTB ;0FBH为3键INC AD1 ;秒加1 MOV A,AD1CJNE A,#3CH,AGAINAMOV AD1,#00HSJMP AGAINANEXTB: CJNE A,#0F7H,NEXTC ;0F7H为4键INC AD2 ;分加1 MOV A,AD2CJNE A,#3CH,AGAINAMOV AD2,#00HSJMP AGAINANEXTC: CJNE A,#0EFH,AGAINA ;0EFH为5键INC AD3 ;时加1MOV A,AD3CJNE A,#18H,AGAINAMOV AD3,#00HNEXTT: SJMP AGAINANEXT6B:CJNE A,#0FDH,NEXTAB;JIESHUJIAN ;0FDH为2键LJMP BACKNEXTAB: CJNE A,#0FBH,NEXTBB ;0FBH为3键INC AD4 ;日加1MOV A,AD4CJNE A,#20H,AGAINAMOV AD4,#01HSJMP AGAINANEXTBB: CJNE A,#0F7H,NEXTCB ;0F7H为4键INC AD5 ;月加1MOV A,AD5CJNE A,#0DH,AGAINAMOV AD5,#01HSJMP AGAINANEXTCB: CJNE A,#0EFH,AGAINA ;0EFH为5键INC AD6 ;年加1MOV A,AD6CJNE A,#64H,AGAINAMOV AD6,#00HAGAINA: LCALL DISPLAYLJMP AGAINBBACK: RETINT: INC R5CJNE R5,#20,NEXTS1 ;循环20次, 每次循环为0.05秒, 共0.05*20=1秒MOV R5,#00HLCALL DISPLAY ;满一秒后的显示LJMP MENDNEXTS1: LJMP NEXTS ;满一秒后的显示MEND: MOV A,AD1CJNE A,#0AH,LAREMENDSETB LED ;满十秒关灯, 否则继续LAREMEND:INC AD1MOV A,AD1CJNE A,#3CH, NEXTS2LJMP MEND1NEXTS2: LJMP NEXTS ;以上为看是否修改秒, 满60, 分加一否则跳转继续MEND1: MOV AD1,#00HINC AD2MOV A,AD2CJNE A,#3CH,NEXTS3LJMP MEND2NEXTS3: LJMP NEXTS ;以上为看是否修改分, 满60, 时加一否则跳转继续MEND2: MOV AD2,#00HINC AD3MOV A,AD3CJNE A,#0Ah,ZAIJIANCHAAJMP BAOSHIZAIJIANCHA:CJNE A,#0Bh,ZHENGCHANGBAOSHI: CLR LED ;以上为两个报时开灯ZHENGCHANG:MOV A,AD3CJNE A,#18H,NEXTS4 ;不满二十四小时跳出LJMP MEND3 ;满二十四后跳到清零小时继续加天NEXTS4: LJMP NEXTSMEND3: MOV AD3,#00HINC AD4MOV A,AD5CJNE A,#02H,JIXUTIAN ;判断是否为二月份MOV A,AD6MOV B,#4HDIV ABMOV A,BJZ RUNNIAN ;判断是否为闰年PINGNIAN:MOV A,AD4 ;平年 CJNE A,#1DH,NEXTSMOV AD4,#01HAJMP JIXUYUERUNNIAN: MOV A,AD4 ; 闰年 CJNE A,#1EH,NEXTSMOV AD4,#01HAJMP JIXUYUEJIXUTIAN: ; 不为二月, 再查看是那个月MOV A,AD5CJNE A,#01H,PAN1LJMP SANSHIYIPAN1: CJNE A,#03H,PAN3LJMP SANSHIYIPAN3: CJNE A,#04H,PAN4LJMP SANSHIPAN4: CJNE A,#05H,PAN5LJMP SANSHIYIPAN5: CJNE A,#06H,PAN6LJMP SANSHIPAN6: CJNE A,#07H,PAN7LJMP SANSHIYIPAN7: CJNE A,#08H,PAN8LJMP SANSHIYIPAN8: CJNE A,#09H,PAN9LJMP SANSHIPAN9 : CJNE A,#10H,PAN10LJMP SANSHIYIPAN10: CJNE A,#11H,SANSHIYILJMP SANSHISANSHIYI:MOV A,AD4 ;月份: 1, 3, 5, 7, 8, 10, 12CJNE A,#20H,NEXTSMOV AD4,#01HAJMP JIXUYUESANSHI: MOV A,AD4 ; 月份:2, 4, 6, 8, 11CJNE A,#1FH,NEXTSMOV AD4,#01HJIXUYUE: INC AD5 ; 满月后加年CJNE A,#0DH,NEXTSMOV AD5,#01HINC AD6MOV A,AD6CJNE A,#64H,NEXTS ; 年满100后清零MOV AD6,#00HNEXTS: ;再赋初值MOV TH0,#4CHMOV TL0,#00HRETIDY250MS: ; 延迟防抖250msMOV R4,#0FAHLOOP8: LCALL DY1MSDJNZ R4,LOOP8RETDY1MS: ; 延迟防抖1msMOV R5,#0B0HLOOP7: MOV R7,#2AHDJNZ R7,$DJNZ R5,LOOP7RET;键盘扫描子程序TEST: MOV R7,#08HSETB P1.7CLR P1.7 ;低电平锁存NOPNOPSETB P1.7 ;高电平输出MOV A,#0FFHAGAIN3: CLR P2.3NOPNOPMOV C, P3.5 ;把p3.5的状态存入CSETB P2.3RLC A ;键盘状态存入ADJNZ R7,AGAIN3 ;扫描八个按键RETTAB:DB 88H,0EBH,4CH,49H,2BH,19H,18H,0CBH,08H,09H;子程序功能索引:;TEST——扫描键盘;DDISP——显示;NEXTS——重新赋初值;DY1MS——延迟防抖1msEND。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
CLK BIT P1.6 ;时钟信号端
DISP BIT P1.7 ;串出锁存端
DBUF EQU 30H ;秒的最低位地址
LED BIT P1.1
CHANGE2 BIT 21H ;加12的标志位
;山东科技大学 信电 通信07-1 lfj 作品
方案一:
方案二:
采用方案二。
模块图
;-------------------------按键说明-------------------------
;--------------------------1键——进入可调状态 -------------------------
MOV A,AD1 ;调整时间 键码分离
MOV B,#0AH
DIV AB
MOV R0,#DBUF
MOV @R0,B
INC R0
MOV @R0,A
MOV A,AD2
MOV B,#0AH
DIV AB
INC R0
MOV @R0,B
INC R0
MOV @R0,A
JB PSW.1,TIMEZHUAN1
LJMP TIMEZHUAN2
LCALL DY1MS
LCALL KEYDONE
NEXTD: SJMP LOOP ;扫描键盘看是否需要调整日历
DISPLAY: LCALL TEST ;扫描键盘
CJNE A,#0DFH,ERSHISI1 ;0DFH为6键
SETB PSW.1 ;显示十二小时
LJMP TIMEZHUAN
ERSHISI1:CJNE A,#0EFH,ERSHISI2 ;0EFH为5键
MOV A,AD5
MOV B,#0AH
DIV AB
INC R0
MOV @R0,B
INC R0
MOV @R0,A
MOV A,AD6
MOV B,#0AH
DIV AB
INC R0
MOV @R0,B
INC R0
MOV @R0,A
DDISP: ;显示, 串入并处的方式, 上升沿写入
MOV R0,#DBUF
MOV R7,#06H
NORMALT: MOV A,AD3
MOV B,#0AH
DIV AB
INC R0
MOV @R0,B
INC R0
MOV @R0,A
SJMP DDISP
DAY: ;调整日期 键码分离
MOV A,AD4
MOV B,#0AH
DIV AB
MOV R0,#DBUF
MOV @R0,B
INC R0
MOV @R0,A
MOV R7,#06H
LOOP0: MOV A,#00H
MOV @R0,A
INC R0
DJNZ R7,LOOP0 ;R0~R7清零
MOV AD1,#37H
MOV AD2,#22H
MOV AD3,#0CH
MOV AD4,#08H
MOV AD5,#08H
MOV AD6,#08H ;初始化时间为12: 34: 56, 日期为08月08日
AD1 EQU 40H ;秒
AD2 EQU 41H ;分
AD3 EQU 42H ;时
AD4 EQU 43H ;天
AD5 EQU 44H ;月
AD6 EQU 45H ;年
;初始化存储单元结束
ORG 0000H
LJMPMAIN
ORG 000BH ;T0中断入口
LJMP INT
ORG 0030H
MAIN: MOV R0,#AD1
CLR PSW.1 ;显示二十四小时
CLR CHANGE2
LJMP TIMEZHUAN
ERSHISI2:CJNE A,#0CFH,CHANGE ;0CFH为5+6键
CLR PSW.1
SETB CHANGE2 ;CHANGE2=1表示把十二表示法转换成二十四小时
LJMP TIMEZHUAN
CHANGE: CLR CHANGE2
MOV IE,#82H ;允许T0中断
MOV TMOD,#01H ;T0允许工作
MOV TH0,#4CH
MOV TL0,#00H ;送入计数初值0.05s
MOV R5,#00H
;初始化结束
SETB TR0 ;T0使能
LOOP: LCALL TEST ;扫描键盘
CJNE A,#0FEH,NEXTD ;0FEH为1键
;-------------------------2键——结束返回 -------------------------
;-------------------------3键——秒加1/日加1 -------------------------
;-------------------------4键——分加1/月加1 -------------------------
AGAINB: LCALL DY250MS ;防抖250ms
LCALL TEST
CJNE A,#7FH,NEXTL1 ;7FH为8键
TIMEZHUAN:
LCALL TEST
CJNE A,#7FH,NEXTL ;7FH为8键
SETB PSW.5
LJMP ZHUAN1
NEXTL: CJNE A,#0BFH,ZHUAN1 ;0BFH为7键
CLR PSW.5
ZHUAN1: JB PSW.5,DAY ;PSW.5=0 调整时间, 为1则调整日期
TIMEZHUAN1: ;判断时间是否大于12
MOV A,AD3
MOV B,#0CH
SUBB A,B
JC NORMALT
MOV AD3,A
LJMP NORMALT
TIMEZHUAN2:
JNB CHANGE2,NORMALT ;判断是否加12
MOV A,AD3
ADD A,#
MOV AD3,A
CLRCHANGE2
LOOP2:
MOV #08H
MOV A,@R0
MOV DPTR,#TAB
MOVC A,@A+DPTR ;显示秒
CLR C
LOOP3:
RRC A
CLR CLK
MOV DISP,C
SETB CLK
DJNZ R6,LOOP3
INC R0
DJNZ R7,LOOP2
RET
KEYDONE: ;人工手动调整日历
;-------------------------5键——显示24小时制/时加1/年加1-------------------------
;-------------------------6键——显示12小时制 -------------------------
;-------------------------7键——可调时间 -------------------------