单片机万年历电子钟设计报告含电路图和源程序
单片机制作数字钟(含万年历、秒表功能)
数字钟、万年历制作(基于单片机)电路原理图:程序://********************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("简洁界面");}。
单片机万年历电子钟设计报告含电路图和源程序
万年历设计报告学院:武夷学院班级:09电信1班组员:林巧文一、设计要求与方案论证21.1 设计要求:21.1.1根本要求21.1.2发挥局部21.2 系统根本方案选择和论证21.2.1单片机芯片的选择方案和论证:21.2.2 显示模块选择方案和论证:21.2.3时钟芯片的选择方案和论证:31.3 电路设计最终方案决定3二、理论分析与计算32.1,秒数的产生由定时器T0产生:3三.系统的硬件设计与实现43.1 电路设计框图:43.2 系统硬件概述:43.3 主要单元电路的设计53.3.1单片机主控制模块的设计53.3.2显示模块的设计53.3.3闹钟模块的设计73.3.4电源稳压模块7四、系统的软件设计74.1程序流程框图74.2闹钟模块流程图:74.3按键调整模块流程图:7五、测试方案与测试结果分析75.1 测试仪器 (7)5.2软件测试平台 Keil C5185.3 模块测试85.3.1显示模块测试85.4测试结果分析与结论85.4.1测试结果分析85.4.2 测试结论 (8)六、作品总结9参考文献9附录一:系统电路图9附录三:系统C程序10一、设计要求与方案论证1.1 设计要求:根本要求〔1〕准确显示:时、分、秒〔24小时制〕〔2〕显示星期〔3〕显示公历〔4〕时间、日期、星期可调节〔5〕断电记忆功能发挥局部〔1〕闹钟功能〔2〕显示阴历〔3〕显示24节气〔4〕其他1.2 系统根本方案选择和论证单片机芯片的选择方案和论证:方案一:采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术, 当在对电路进展调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的屡次拔插会对芯片造成一定的损坏。
方案二:采用AT89S52,片内ROM全都采用Flash ROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进展调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片屡次拔插,所以不会对芯片造成损坏。
基于单片机的万年历设计
嵌入式系统概述题目:基于单片机的万年历设计班级:自动化1304班一、系统功能概述此设计以AT89C51为控制芯片,用RTC定时器实现万年历的控制与设计。
所进行控制的语句是通过C语言实现的,并且用串口助手显示能动态地显示当前时间信息,包括年、月、日、时、分、秒。
二、硬件设计原理图:1.万年历电路图设计如下:三、软件设计:1.设计思路:本设计主要由3大部分电路组成:单片机最小系统电路、时钟显示电路和参数修改电路。
其中单片机最小系统主要由复位电路和时钟电路组成。
设计中,当接收到修改参数的指令,将停止时钟的继续,转而进行指令程序,在指令结束后转回断点处继续进行计时。
2.流程图:四、基于单片机万年历的源代码:#include <reg52.h>#include <intrins.h>#include <string.h>#define uint unsigned int#define uchar unsigned charsbit IO = P1^0;sbit SCLK = P1^1;sbit RST = P1^2;sbit RS = P2^0;sbit RW = P2^1;sbit EN = P2^2;sbit KEY1=P3^4;sbit KEY2=P3^5;sbit KEY3=P3^6;uchar*WEEK[]={"SUN","***","MON","TUS","WEN"," THU","FRI","SAT"};uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00 "};uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "};uchar DateTime[7]; //秒,分,时,日,月,周,年ucharflag,flag_1,i,miao,fen,shi,ri,yue,zhou,nian; void DelayMS(uint ms){uchar i;while(ms--){for(i=0;i<120;i++);}}/*********************************************** ******/ //函数名称:Write_A_Byte_TO_DS1302(uchar x)//函数功能: 向1302写入一个字节//入口参数: x//出口参数: 无//调用子程序: 无/*********************************************** ******/void Write_A_Byte_TO_DS1302(uchar x){uchar i;for(i=0;i<8;i++){IO=x&0x01;SCLK=1;SCLK=0;x>>=1;}}void Write_DS1302(uchar add,uchar num) {SCLK=0;RST=0;RST=1;Write_A_Byte_TO_DS1302(add);Write_A_Byte_TO_DS1302(num);RST=0;SCLK=1;}/*********************************************** ******///函数名称:Get_A_Byte_FROM_DS1302()//函数功能: 从1302读一个字节//入口参数: 无//出口参数: b/16*10+b%16 //调用子程序: 无/*********************************************** ******/uchar Get_A_Byte_FROM_DS1302(){uchar i,b=0x00;for(i=0;i<8;i++){b |= _crol_((uchar)IO,i);SCLK=1;SCLK=0;}return b/16*10+b%16;}/*********************************************** ******///函数名称: Read_Data(uchar addr)//函数功能: 指定位置读数据//入口参数: addr//出口参数: dat//调用子程序: Write_Abyte_1302(addr) /*********************************************** ******/uchar Read_Data(uchar addr){uchar dat;RST = 0;SCLK=0;RST=1;Write_A_Byte_TO_DS1302(addr);dat = Get_A_Byte_FROM_DS1302();SCLK=1;RST=0;return dat;}/*********************************************** ******///函数名称: GetTime()//函数功能: 读取时间//入口参数: 无//出口参数: 无//调用子程序: 无/*********************************************** ******/void GetTime(){uchar i,addr = 0x81;for(i=0;i<7;i++){DateTime[i]=Read_Data(addr);addr+=2; }}uchar Read_LCD_State(){uchar state;RS=0;RW=1;EN=1;DelayMS(1);state=P0;EN = 0;DelayMS(1);return state;}void LCD_Busy_Wait(){while((Read_LCD_State()&0x80)==0x80); DelayMS(5);}void Write_LCD_Data(uchar dat) //写数据到1602{LCD_Busy_Wait();RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1); EN=0;}void Write_LCD_Command(uchar cmd) //写命令{LCD_Busy_Wait();RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(1); EN=0;}void Init_LCD() //1602 初始化{Write_LCD_Command(0x38);DelayMS(1);Write_LCD_Command(0x01);DelayMS(1);Write_LCD_Command(0x06);DelayMS(1);Write_LCD_Command(0x0c);DelayMS(1);}void Set_LCD_POS(uchar p){Write_LCD_Command(p|0x80);}void Display_LCD_String(uchar p,uchar *s) //1602显示{uchar i;Set_LCD_POS(p);for(i=0;i<16;i++){Write_LCD_Data(s[i]);DelayMS(1);}}void write_com(uchar com){RS=0;P0=com;DelayMS(5);EN=1;DelayMS(5);EN=0;}void write_date(uchar date){RS=1;P0=date;DelayMS(5);EN=1;DelayMS(5);EN=0;}void display(uchar add,uchar date){uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void display1(uchar add,uchar date) {uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}void Format_DateTime(uchar d,uchar *a) {a[0]=d/10+'0';a[1]=d%10+'0';}uchar ZH(uchar dat){uchar tmp;tmp=dat/10;dat=dat%10;dat=dat+tmp*16;return dat;}void Keyscan(){flag_1=1;while(flag_1){if(KEY1==0){DelayMS(5);while(!KEY1);flag=(flag+1)%8;switch(flag){case(1): Write_LCD_Command(0x0f);Write_LCD_Command(0x80+0x40+11);break;case(2):Write_LCD_Command(0x80+0x40+8);break;case(3):Write_LCD_Command(0x80+0x40+5);break;case(4):Write_LCD_Command(0x80+13);break;case(5):Write_LCD_Command(0x80+11);break;case(6):Write_LCD_Command(0x80+8);break;case(7):Write_LCD_Command(0x80+5);break;case(0): flag_1=0;Write_LCD_Command(0x0c);//miaoWrite_DS1302(0x8e,0x00);Write_DS1302(0x80,ZH(DateTime[0]));Write_DS1302(0x8e,0x80);//fenWrite_DS1302(0x8e,0x00);Write_DS1302(0x82,ZH(DateTime[1]));Write_DS1302(0x8e,0x80);//shiWrite_DS1302(0x8e,0x00);Write_DS1302(0x84,ZH(DateTime[2]));Write_DS1302(0x8e,0x80);//riWrite_DS1302(0x8e,0x00);Write_DS1302(0x86,ZH(DateTime[3]));Write_DS1302(0x8e,0x80);// yueWrite_DS1302(0x8e,0x00);Write_DS1302(0x88,ZH(DateTime[4]));Write_DS1302(0x8e,0x80);//nianWrite_DS1302(0x8e,0x00);Write_DS1302(0x8c,ZH(DateTime[6]));Write_DS1302(0x8e,0x80);break;}}if(flag!=0){if(KEY2==0){DelayMS(5);if(KEY2==0)while(!KEY2);if(flag==1) //miao{DateTime[0]++;if(DateTime[0]==60)DateTime[0]=0;write_com(0x80+0x40+11);display(11,DateTime[0]);}if(flag==2) //fen{DateTime[1]++;if(DateTime[1]==60)DateTime[1]=0;write_com(0x80+0x40+8);display(8,DateTime[1]);}if(flag==3) //shi{DateTime[2]++;if(DateTime[2]==24)DateTime[2]=0;write_com(0x80+0x40+5);display(5,DateTime[2]);}/* if(flag==4) //zhou {DateTime[0]++;if(DateTime[0]==60)DateTime[0]=0;write_com(0x80+0x40+11);display(11,DateTime[0]);} */if(flag==5) // ri{DateTime[3]++;if(DateTime[3]==30)DateTime[3]=0;write_com(0x80+11);display1(11,DateTime[3]); }if(flag==6) //yue{DateTime[4]++;if(DateTime[4]==13)DateTime[4]=0;write_com(0x80+8);display1(8,DateTime[4]);}if(flag==7) //nian{DateTime[6]++;if(DateTime[6]==100)DateTime[6]=0;write_com(0x80+5);display1(5,DateTime[6]);}}}if(flag!=0){if(KEY3==0){DelayMS(5);if(KEY3==0)while(!KEY3);if(flag==1) //miao{DateTime[0]--;if(DateTime[0]==-1)DateTime[0]=0;write_com(0x80+0x40+11);display(11,DateTime[0]);}if(flag==2) //fen{DateTime[1]--;if(DateTime[1]==-1)DateTime[1]=0;write_com(0x80+0x40+8);display(8,DateTime[1]);}if(flag==3) //shi{DateTime[2]--;if(DateTime[2]==-1)DateTime[2]=0;write_com(0x80+0x40+5);display(5,DateTime[2]);}/* if(flag==4) //zhou {DateTime[0]++;if(DateTime[0]==60)DateTime[0]=0;write_com(0x80+0x40+11);display(11,DateTime[0]);} */if(flag==5) // ri{DateTime[3]--;if(DateTime[3]==-1)DateTime[3]=0;write_com(0x80+11);display1(11,DateTime[3]); }if(flag==6) //yue{DateTime[4]--;if(DateTime[4]==-1)DateTime[4]=0;write_com(0x80+8);display1(8,DateTime[4]);}if(flag==7) //nian{DateTime[6]--;if(DateTime[6]==-1)DateTime[6]=0;write_com(0x80+5);display1(5,DateTime[6]);}}}}}void main() {Init_LCD(); while(1) {EA=1;EX0=1;GetTime();Format_DateTime(DateTime[6],LCD_DSY_BUF FER1+5); //年Format_DateTime(DateTime[4],LCD_DSY_BUF FER1+8); //月Format_DateTime(DateTime[3],LCD_DSY_BUF FER1+11); //日strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTim e[5]]); //周Format_DateTime(DateTime[2],LCD_DSY_BUF FER2+5); //时Format_DateTime(DateTime[1],LCD_DSY_BUF FER2+8); //分Format_DateTime(DateTime[0],LCD_DSY_BUF FER2+11); //秒Display_LCD_String(0x00,LCD_DSY_BUFFER1);Display_LCD_String(0x40,LCD_DSY_BUFFER2); }}void int0() interrupt 0{Keyscan();}五、运行结果:。
万年历单片机课程设计报告
1 任务和设计要求首先要学会安装软件,要熟悉会使用.2 系统设计系统框图3 硬件设计3。
1 电路原理图3.2 主要单元电路3。
3 元件清单4 软件设计4.1 程序流程图4.2程序清单TIME_WEEK DATA 52H TIME_YEAR DATA 5DH TIME_MONTH DATA 5EH TIME_DATA DATA 5FH YEARH DATA 36HYEAR DATA 35H MONTH DATA 34HDAY DATA 33HHOUR DATA 32H MINUTE DATA 31HSEC DATA 30HAAA BIT P3.0BBB BIT P3.1AA BIT P3.3BB BIT P3.4CC BIT P3。
5BL BIT P3.2BZ1 BIT 21H.0 TIMES DATA 20H COM DATA P1 ORG 0000HLJMP START ORG 0003H RETIORG 000BH LJMP INTT0ORG 0013H RETIORG 001BH RETIORG 0023H RETISTART:MOV R0,#30HMOV R7,#9 CLEETE:MOV @R0,#00HINC R0DJNZ R7,CLEETEMOV TIMES,#00H MOV TMOD,#01H MOV TL0,#0C0H MOV TH0,#63H MOV SEC,#0MOV MINUTE,#0H MOV HOUR,#0H MOV DAY,#01H MOV MONTH,#01H MOV YEAR,#01H MOV YEARH,#20H SETB EASETB ET0SETB TR0MOV R4,#19 START1:CALL DISPJNB AA,SETMM1 JMP START1 SETMM1:CALL SETMMJMP START1SETMM:CALL DISPCALL DISPJB AA,SETMM0SETMM2:JNB AA,SETMM3CLR ET0CLR TR0MOV SEC,#0MOV TIMES,#01H MOV R0,#MINUTE SETMM4:NOPINC22:CALL OFFLCALL INC11CALL DISPJB AA,INC22CALL DISPJB AA,INC22INC R0MOV A,TIMESRL AMOV TIMES,AJNB TIMES. 5, SETMM4 SETMM12:JNB AA ,SETMM11 SETMM0:SETB TR0SETB ET0RETSETMM11:CALL DISPJMP SETMM12 SETMM3:CALL DISPJMP SETMM2INC11:MOV R3,#40INC111:MOV A,@R0JB BB,INC17 ADD A,#1DA ACALL INC000INC13:JNB BB ,INC14 INC17:MOV @R0,A CALL DISP DJNZ R3,INC111 RETINC14:CALL DISP JMP INC13 OFFL:MOV 22H,@R0 MOV R6,#10 OFF1:MOV R7,#10OFF2:MOV @ R0, #0AAH CALL DISPDJNZ R7 , OFF2DJNZ R6 , OFF1MOV @R0 , 22HRETINC000:JB TIMES。
自己制作的单片机万年历程序+原理图
自己制作的单片机万年历程序+原理图单片机万年历仿真原理图如下仿真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) 可通过按键切换年、月、日、星期的显示状态。
(3) 可随时调校年、月、日及星期。
(4) 可每次增减一进行时间调节。
(5) 可动态完整显示年份,实现真正的万年历显示。
二、方案设计与论证:1.方案一:通过一段时间对专业书籍及多种设计方案的研究及分析,在计数电路芯片的选择上可以采用74LS160或74LS90,在实现的电路中有两种方案来实现清零(异步置数和同步清零);对于实现年、月、日、星期的显示,可采用LED液晶显示屏、点阵式数码管、LED数码管中的一种;在实现年、月、日、星期的校时方面,可设置K3 、K2、K1三个开关分别作为年、月、日的校时控制开关,由于“日”与“星期”同步,因而控制“日”的同时也控制了“星期”。
另外通过按钮开关可以在日期与时间间切换和对时钟进行调整。
该方案的系统原理框图如下:图中各单元电路的工作原理如下:(1)计数器电路:包括年计数器、月计数器、日计数器、星期计数器四部分。
各部分分别完成对“年”、“月”、“日”、“星期”的计数。
(2)译码显示电路:译码显示电路的功能是将年、月、日、星期计数器输出的4位二进制码进行翻译后显示出相应的十进制数字。
(3)校时电路:当数字钟计时出现误差时,必须对时间进行校正,通常称为“校时”,校时是数字钟应该具备的基本功能,一般要求能对年、月、日分别进行校正。
2.方案二:对于本题目的设计,我们不仅可以运用以前学过的课程——《数字电路逻辑设计》里边的知识来完成,也可以运用我们所学过的单片机知识来完成本设计,我们可以直接用叫简单的单片机芯片AT89C51再加上其周围的外设电路结构来完成。
该方案的系统原理框图如下:图中各单元电路的工作原理如下:(1)晶体电路:晶体振荡器电路给数字钟提供一个频率稳定准确的32768Hz的方波信号,可保证数字钟的走时准确及稳定。
不管是指针式的电子钟还是数字显示的电子钟都使用了晶体荡器电路。
单片机课程设计报告 电子万年历
题目:电子万年历设计报告课程名称单片机课程设计学院物理与光电工程学院专业班级 09级电子科学与技术5班学号姓名王周英联系方式任课教师陈国鼎2011年12月12日电子万年历设计报告1)设计题目题目:电子万年历设计2)设计任务和要求1、显示年月日时分秒及星期信息。
2、具有可调整日期和时间功能3、增加闰年计算功能4、实现语音报时3)原理电路和程序设计:(1)方案比较;一:控制MCU方案一:STM8,STM公司推出的新款MCU,性能高,外设资源丰富,带有12位AD、12位DA、脉宽调制PWM、最高机器周期16MHz等。
且其功耗非常小,价格便宜,性价比非常高。
缺点是只能用官方开发的S-Link下载器进行下载,其价格比较高,一般学习者手上都没有。
方案二:AT89S52,AT公司的51单片机。
优点是支持ISP在线下载;缺点是价格比较高。
方案三:STC89C52,宏晶公司的51系列单片机,价格便宜,在国内使用者非常多。
支持串口下载,使用非常方便,且具有很大的价格优势。
缺点是仅支持串口下载,不支持在线下载,使用中会有些不方便。
由于本设计对控制芯片的要求不高,因此选用方案三。
二:时钟模块方案一:用单片机的定时器产生1S的时基信号,然后用程序来实现时钟的时、分、秒计时,同时用程序来产生年、月、日。
该方案优点是减少使用外设芯片;缺点是用单片机模拟时钟,使编程量增大,且用定时器产生时基信号,精度不高。
方案二:使用时钟芯片DS12C887。
优点是8位数据线并行控制,控制简单;自带有锂电池,外部掉电时,其内部时间信息还能够保持 10年之久。
缺点是并行控制,占用太多的IO口,且价格很高,不适合一般的电子制作。
方案三:使用时钟芯片DS1302。
优点是同步串行通信,仅使用3个IO口,占用最少的单片机资源;其内部功能强大。
更重要的是其价格便宜,具有非常高的性价比。
缺点是串行通信,控制比较复杂。
综上,本设计选择方案三。
三:语音报时模块方案一:使用语音芯片BLA902。
(完整版)基于51单片机的万年历的设计
单片机课程实训SCM PRACTICAL TRAINING目录第一部分课程设计任务书 (1)一、课程设计题目 (1)二、课程设计时间 (1)三、实训提交方式 (1)四、设计要求 (1)第二部分课程设计报告 (2)一、单片机发展概况 (2)二、MCS-51单片机系统简介 (2)三、设计思想 (3)四、硬件电路设计 (3)1. 总体设计 (3)2. 晶振电路 (4)3. 复位电路 (4)4. DS1302时钟电路 (5)5. 温度采集系统电路 (5)6. 按键调整电路 (6)7. 闹钟提示电路 (6)五、软件设计框图 (7)六、程序源代码 (8)1. 主程序 (8)2. 温度控制程序 (11)3. 日历设置程序 (13)4. 时钟控制程序 (18)5. 显示设置程序 (20)七、结束语 (23)八、课程设计小组分工 (23)九、参考文献 (23)第一部分课程设计任务书一、课程设计题目用中小规模集成芯片设计制作万年历。
二、课程设计时间五天三、实训提交方式提交实训设计报告电子版与纸质版四、设计要求(1)显示年、月、日、时、分、秒和星期,并有相应的农历显示。
(2)可通过键盘自动调整时间。
(3)具有闹钟功能。
(4)能够显示环境温度,误差小于±1℃(5)计时精度:月误差小于20秒。
第二部分课程设计报告一、单片机发展概况单片机诞生于20世纪70年代末,它的发展史大致可分为三个阶段:第一阶段(1976-1978):初级单片机微处理阶段。
该时期的单片机具有 8 位CPU,并行 I/O 端口、8 位时序同步计数器,寻址范围 4KB,但是没有串行口。
第二阶段(1978-1982):高性能单片机微机处理阶段,该时期的单片机具有I/O 串行端口,有多级中断处理系统,15 位时序同步技术器,RAM、ROM 容量加大,寻址范围可达 64KB。
第三阶段(1982-至今)位单片机微处理改良型及 16 位单片机微处理阶段民用电子产品、计算机系统中的部件控制器、智能仪器仪表、工业测控、网络与通信的职能接口、军工领域、办公自动化、集散控制系统、并行多机处理系统和局域网络系统。
基于单片机的万年历设计报告
单片机电子时钟设计姓名:***班级:电子一班学号:**********指导老师:***一、设计背景数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。
由于数字集成电路技术的发展和采用了先进的石英技术,使数字钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。
尽管目前市场上已有现成的数字钟集成电路芯片出售,价格便宜、使用也方便,但鉴于单片机的定时器功能也可以完成数字钟电路的设计,因此进行数字钟的设计是必要的。
在这里我们将已学过的比较零散的数字电路的知识有机的、系统的联系起来用于实际,来培养我们的综合分析和设计电路,写程序、调试电路的能力。
单片机具有体积小、功能强可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。
二、设计目的及意义(1)巩固、加深和扩大51系列单片机应用的知识面,提高综合及灵活运用所学知识解决工业控制的能力;(2)培养针对课题需要,选择和查阅有关手册、图表及文献资料的自学能力,提高组成系统、编程、调试的动手能力;(3)对课题设计方案的分析、选择、比较、熟悉用51单片机做系统开发、研制的过程,软硬件设计的方法、内容及步骤。
三、作品介绍本作品是个性化电子数字钟设计,技术上主要用单片机(AT89S52)主控,LCD1602显示,分别显示“年、月、日、星期、时、分、秒、温度”。
该作品主要用于万年历显示,能整时报时,能定时闹铃10秒,按键可调和遥控可调时钟,温度显示。
使用方法:开机后电子时钟在2014-12-23 Tur 00:00:00起开始计时,温度值为当前所处环境的实时温度。
当用按键来调时钟时:按一下调时功能键,秒单元闪烁,按+键加1,按-键减1;按两下调时功能键,分单元闪烁,按+键加1,按-键减1;按三下调时功能键,小时单元闪烁,按+键加1,按-键减1;按四下调时功能键,天单元闪烁,按+键加1,按-键减1;按五下调时功能键,月单元闪烁,按+键加1,按-键减1;按六下调时功能键,年单元闪烁,按+键加1,按-键减1;按七下调时功能键,结束闪烁,时钟正常显示。
基于单片机设计的万年历显示电路
基于单片机设计的万年历显示电路电路原理图:程序:#include<reg51.h>#include"lcd1602.h"#include"ds1302.h"#include"ds18b20.h"#define uint unsigned int#define uchar unsigned charuint b[6];//年、月、日、时、分、秒uchar code row1[]={"2009-01-01"};uchar code row2[]={"00:00:00"};uchar year1[12]={31,28,31,30,31,30,31,31,30,31,30,31};//平年uchar year2[12]={31,29,31,30,31,30,31,31,30,31,30,31};//润年uchar j[6]={0x85,0x88,0x8b,0x84+0x40,0x87+0x40,0x8a+0x40};//LCD地址uchar i,k,jj=0,w,clock=0,bigclock=0,c=0,num;//i循环数,k温度缓存,jj地址位uint temp;sbit b1=P3^0;//设置sbit b2=P3^1;//上调sbit b3=P3^2;//下调sbit b4=P3^3;//转换sbit b5=P3^4;//闹钟sbit speaker=P3^5;lcdscan(){for(i=0;i<6;i++){ lcdwrite(j[i]);lcdshuju(a[11-i*2]+0x30);lcdwrite(j[i]+0x01);lcdshuju(a[10-i*2]+0x30);}}void key(){ if(b1==0){ dsaddshuju(0x80,(a[1]<<4)+a[0]+0x80);while(b1==0){for(i=0;i<6;i++){b[i]=a[11-i*2+clock]*10+a[10-i*2+clock];}if(b4==0){ delay(3);jj++;if(jj==6){jj=0;}}if(b2==0){ delay(3);b[jj]++;if(b[5]==60)b[5]=0;if(b[4]==60)b[4]=0;if(b[3]==24)b[3]=0;if((b[0]%4==0&&b[0]%100!=0)||b[0]%400==0){if(b[2]>year2[b[1]-1])b[2]=1;} else {if(b[2]>year1[b[1]-1])b[2]=1;}if(b[1]==13)b[1]=1;if(b[0]==100)b[0]=0;}if(b3==0){ delay(3);b[jj]--;if(b[5]==-1)b[5]=59;if(b[4]==-1)b[4]=59;if(b[3]==-1)b[3]=23;if((b[0]%4==0&&b[0]%100!=0) || b[0]%400==0){if(b[2]<=0)b[2]=year2[b[1]-1];}else {if(b[2]<=0)b[2]=year1[b[1]-1];}if(b[1]==0)b[1]=12;if(b[0]==-1)b[0]=99;}for(i=0;i<6;i++){ a[11-i*2+clock]=b[i]/10;a[10-i*2+clock]=b[i]%10;}lcdwrite(j[jj]);lcdshuju(0);lcdwrite(j[jj]+1);lcdshuju(0);delay(200);lcdwrite(j[jj]);lcdshuju(a[11-2*jj+clock]+0x30);lcdwrite(j[jj]+1);lcdshuju(a[10-2*jj+clock]+0x30);delay(200);if(b1==1){ dsaddshuju(0x80,(a[1]<<4)+a[0]);dson();}if(b5==0)clock=12;} }}void main(){ speaker=0;lcdrw=0;dson();lcdon();lcdwrite(0x83);for(i=0;i<10;i++){ lcdshuju(row1[i]);delay(1);}lcdwrite(0x84+0x40);for(i=0;i<8;i++){lcdshuju(row2[i]);delay(1);}dsrst=0;dssclk=0;while(1){for(i=0;i<5;i++){ dsrst=1;dswrite(0x81+i*2);k=dsread();dsrst=0;a[i*2]=k&0x0f;a[i*2+1]=(k>>4)&0x0f;}dsrst=1;dswrite(0x8d);k=dsread();dsrst=0;a[10]=k&0x0f;a[11]=(k>>4)&0x0f;delay(100);lcdscan();key();if(b5==0){ for(i=0;i<12;i++){if(a[i+12]==a[i])num++; }if(num==12)bigclock=1;else num=0;lcdwrite(0x8e);lcdshuju('&');}else{lcdwrite(0x8e);lcdshuju(0x00);}if(bigclock==1){ speaker=1;c++;if(c==100){bigclock=0;speaker=0;}}temp=readtemperature();//temp是uint型的。
51单片机课程设计——电子万年历
电子万年历的设计学院计算机与控制工程学院专业班级自动化学生姓名指导教师2010年6月25日引言随着社会、科技的发展,人类得知时间,从观太阳、摆钟到现在电子钟,不断研究、创新。
为了在观测时间的同时,能够了解其它与人类密切相关的信息,比如温度、星期、日期等,电子万年历诞生了,它集时间、日期、星期和温度功能于一身,具有读取方便、显示直观、功能多样、电路简洁等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
二十一世纪的今天,最具代表性的计时产品就是电子万年历,它是近代世界钟表业界的第三次革命。
第一次是摆和摆轮游丝的发明,相对稳定的机械振荡频率源使钟表的走时差从分级缩小到秒级,代表性的产品就是带有摆或摆轮游丝的机械钟或表。
第二次革命是石英晶体振荡器的应用,发明了走时精度更高的石英电子钟表,使钟表的走时月差从分级缩小到秒级。
第三次革命就是单片机数码计时技术的应用(电子万年历),使计时产品的走时日差从分级缩小到1/600万秒,从原有传统指针计时的方式发展为人们日常更为熟悉的夜光数字显示方式,直观明了,并增加了全自动日期、星期、温度以及其他日常附属信息的显示功能,它更符合消费者的生活需求!因此,电子万年历的出现带来了钟表计时业界跨跃性的进步……我国生产的电子万年历有很多种,总体上来说以研究多功能电子万年历为主,使万年历除了原有的显示时间,日期等基本功能外,还具有闹铃,报警等功能。
商家生产的电子万年历更从质量,价格,实用上考虑,不断的改进电子万年历的设计,使其更加的具有市场。
本设计主要采用AT89C51单片机作为主控核心,由DS1302时钟芯片提供时钟、LED 动态扫描显示屏显示。
AT89C51单片机是由Atmel公司推出的,功耗小,电压可选用4~6V电压供电;DS1302时钟芯片是美国DALLAS公司推出的具有涓细电流充电功能的低功耗实时时钟芯片,它可以对年、月、日、星期、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小;数字显示是采用的LED液晶显示屏来显示,可以同时显示年、月、日、星期、时、分、秒和温度等信息。
基于单片机的电子万年历设计报告
基于单片机的万年历设计报告一、研究意义随着当今世界经济的快速发展和信息化时代的来临,各种各样的小型智能家电产品陆续出现在我们的生活当中。
日历是人们不可或缺的日常用品。
但一般日历都为纸制用品,使用不便,寿命不长。
电子万年历采用智能电子控制和显示技术,改善了纸制日历的缺陷。
本设计以AT89S52单片机为核心,构成单片机控制电路,AT89C52是一种带8K字节闪速可编程可擦除只读存储器(PEROM)的低电压、高性能CMOS 8位为控制器。
该器件采用ATMEL 非易失存储器制造技术制造,与工业标准的80C51和80C52指令集和输出管脚相兼容。
结合DS1302时钟芯片和24C02 FLASH存储器,完成时间的自动调整和掉电保护,全部信息用液晶显示。
时间、日期调整由三个按键来实现,并可对闹铃开关进行设置。
日历能显示阳历和阴历年、月、日以及星期、时、分、秒。
在显示阴历月份时,能标明是否闰月。
二、总体方案设计本设计以AT89S52单片机为核心,构成单片机控制电路,结合DS1302时钟芯片和24C02 FLASH存储器,显示阳历的年、月、日、星期、时、分、秒和阴历的年、月、日,在显示阴历时间时,能标明是否闰月,同时完成对它们的自动调整和掉电保护,全部信息用液晶显示出来。
输入接口由三个按键来实现,用这三个按键可以对日期和时间进行调整,并可以对闹铃的开关和闹铃的时间进行设置。
闹铃功能通过蜂鸣器来实现。
软件控制程序实现所有的功能。
整机电路使用+5V稳压电源,可稳定工作。
系统框图如图2-1所示,其软硬件设计简单,时间记录准确,可广泛应用于长时间连续显示的系统中。
三、系统硬件设计按照系统设计功能的要求,初步确定设计系统由主控模块、时钟模块、存储模块、键盘接口模块、显示模块和闹铃模块共6个模块组成,电路系统构成框图如图3-1所示。
主控芯片使用52系列AT89S52单片机,时钟芯片使用美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟芯片DS1302,存储模块采用美国ATMEL公司生产的低功耗CMOS串行EEPROM存储芯片AT24C02。
毕业设计---基于单片机的多功能电子万年历的设计
基于单片机的多功能电子万年历的设计摘要随着科技的快速发展,自从观太阳、摆钟到现在电子钟,人类不断研究,不断创新纪录。
本文主要介绍了基于单片机的智能电子万年历的研制,该万年历能够实时显示公历年、月、日、时、分、秒,以及对应的农历日期、24节气、天干地支、闹铃功能,同时还能够实时测取环境温度。
本系统的硬件部分主要由A VR单片机、时钟芯片、温度传感器等部件组成,文中给出了详细的硬件设计实现及相关电路图;软件部分主要包含公历转农历的算法设计模块、显示模块、时间的读取、温度的检测模块,按键的扫描输入模块等,文中给出了系统的软件程序流程图及各功能模块的软件程序清单,最后介绍了整体系统的设计实现、仿真及调试过程,给出了下一步的改进方案等。
关键词:单片机;液晶技术;万年历;时钟芯片Design of Multifunctional digital Perpetual Calendar Based on MCUAbstractWith the development of technology,Since the concept of the sun, Baizhong, andnow the electronic bell,human beings continue to study and constant innovation record。
This paper-based Microcontroller Development of Intelligent electronic calendar, The calendar can display real-time in the calendar year, month, day, hours, minutes and seconds,a nd the correspond ing date of the Lunar New Year, 24 Solar Terms,at the same time also to real-time measurement from the ambient temperature,In addition to the user through the keyboard input years of history,for the correspond ing period of the Lunar.The system hardware from some of the major A VR microcontroller, a number of digital control, decoder, the clock chip,temperature sensors and other components,the paper gives a detailed design and implementation of hardware and related circuit;Software contains some of the major Lunar calendar to the algorithm design module,dynamic digital display modules,time to read,temperature detection module,Press enter the scanning module.In this paper, the system software modules and flow chart of the list of software programs,Finally, the realization of the overall system design, simulation and debugging process, the next step is the improvement programmes.Keywords:MCU;crystal technology;Calendar;Clock chip目录引言 (1)第1章绪论 (2)1.1课题的背景与意义 (2)1.2 数字万年历的现状与发展 (2)1.3 论文的主要工作及章节安排 (3)1.4 本章小结 (3)第2章方案论证比较.............................................................................. (4)2.1 多功能数字万年历系统概述 (4)2.2计时方案 (4)2.3温度检测方案 (5)2.4显示方案 (5)2.5本章小结 (5)第3章系统硬件设计 (6)3.1 主控制器ATmega16 单片机介绍 (6)3.2 时钟电路DS1302 (6)3.3 温度检测DS18B20 (7)3.4 动态显示 (8)3.5 键盘接口 (8)3.6 语音闹铃模块 (8)3.7 电源设计 (9)3.8本章小结 (11)第4章系统软件设计 (12)4.1 公历计算显示程序设计 (13)4.1.1 DS1302 内部寄存器 (13)4.1.2 时间读取程序设计 (15)4.2 农历转换程序设计 (16)4.2.1 公历转农历算法研究 (16)4.2.2 干支纪年简介 (18)4.2.3 公历转农历程序 (18)4.3 温度测量程序设计 (20)4.3.1 DS18B20 的测温原理 (20)4.3.2 温度程序 (21)4.4 二十四节气算法研究 (23)4.5系统仿真 (24)4.6本章小结 (25)结论与展望 (26)致谢 (27)参考文献 (28)附录 A 电子万年历原理图 (29)附录 B 外文文献与译文 (30)英文原文: (30)中文译文: (33)附录 C 参考文献题录及摘要 (35)附录 D 电子万年历源程序 (37)插图清单图2-1 数字万年历系统框图 (4)图3-1 DS1302与ATmega16连接图 (7)图3-2 DS18B20与AtMEGA16连接图 (8)图3-3 报时电路 (9)图3-4 稳压电源原理图 (10)图3-5 电源电路 (10)图4-1 系统程序流程图 (13)图4-2 公历程序流程图 (14)图4-3 DS18B20测温原理 (21)表格清单表3-1 LCD12864显示内容 (8)表4-1 DS1302的寄存器及其控制字 (14)表4-2 RS位配置 (15)引言人类的日常生活离不开时间,任何具有周期性变化的自然现象都可以用来测量时间。
单片机课程设计报告(万年历)
目录一、摘要 (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单片机电子万年历设计
基于51单片机电子万年历设计大连民族学院机电信息工程学院自动化系单片机系统课程设计报告题目:电子万年历专业:自动化班级:106学生姓名:指导教师:设计完成日期:2012年11月30日1任务分析和性能指标1.1任务分析设计一个具有报时功能、停电正常运行(来电无需校时)、闹钟功能、带有年月日、时分秒及星期显示的电子日历。
电子万年历是日常生活中常见的小型电子产品,其形式多种多样,小到带有日期的电子腕表,大到公共场所悬挂的大型电子日历,此外,眼下我们还常能在宾馆、饭店等场所见到一种带有年、月、日、时、分、秒、星期甚至节气等信息的电子日历牌。
电子日历的主要功能是给人们提供时间和日期信息,无论其形式如何,从外部都可分为显示和校准两部分。
为使电子日历协调工作,整个系统从功能上可分为实时时钟、显示和键盘三个模块,分别完成时间和日期的计算以及人机交互的管理等。
1.2性能指标实时时钟(RTC:Real Time Clock)是系统的核心,其运行精度直接影响产品质量。
实时时钟的实现有两种方案可选,一是利用单片机系统时钟和中断完成时间和日期的计算;二是利用专用时钟芯片。
前者不用附加芯片,系统简单,但是累计误差较大,只有短时计时才可使用。
长时间计时一般都采用后者。
后者采用32.768KHz晶体振荡器振作为脉冲源,内部的15位计数器刚好产生标准秒脉冲。
该类芯片除时钟计时外,还有年月日和星期的计算功能,并且还可计算闰年。
芯片初始化后可脱离CPU自动运行,有些芯片内部带有电池,出厂时芯片即开始运行。
专用时钟芯片的种类很多,与CPU的通信方式有并行,也有串行。
常见的芯片有DALLAS 公司生产的DS1302和DS12C887,前者为串行,需要外加后备电池;后者为并行,芯片内置锂电池和晶体振荡器,无外加电源的情况下可运行10年。
此外,还有许多时钟芯片,如Epson、Holtek、深圳兴威帆等公司都推出自己的时钟芯片。
这次我们选用的芯片是DS12C887。
单片机课程设计-电子万年历
单片机及接口技术综合实验——————电子万年日历系统一、题目:电子实时时钟/万年日历系统二、功能要求:1.基本要求:⑴显示准确的北京时间(时、分、秒),可用24小时制式;⑵随时可以调校时间。
2.发挥要求:⑴增加公历日期显示功能(年、月、日),年号只显示最后两位;⑵随时可以调校年、月、日;⑶允许通过转换功能键转换显示时间或日期。
三、方案考虑:1、硬件方案:⑴显示器采用6位LED数码管(共阳),可分别显示时间或日期;(通过KB键可切换)⑵显示器的驱动采用动态扫描电路形式,以达到简化电路的目的。
但要注意所需的驱动电流比静态驱动时要大,因此要增加驱动电路。
可采用74LS244或者晶体管;其中74ls244是用来驱动段选码,晶体管是驱动位选码!⑶采用“一键多用方案”,以减少按键数目。
本方案只采用了两个按键⑷整体上要考虑:结构简单、布局美观、操作方便、成本低廉。
2、设计电路图如下:3、元件清单:⑴89C51 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μF 1个(用于系统复位电路)。
⑵30 pF 2个(用于系统振荡电路)。
(11)其它:⑴万能电路板(10×15):1块⑵焊锡条:2米⑶带插头、座的电源端子:1条⑷各种颜色外皮的导线:各1米(12)工具:1.电烙铁:1把2.剪钳:1把3.镊子:1把4.万用表:1个(13)设备:编程器(MEP300或TOP851)6个4、软件方案:只使用第一组工作寄存器,功能分布如下:⑴“时钟”基准时间由单片机内部定时中断来提供,定时时间应该乘以一个整数得到“秒”,且不宜太长或太短,最长不能超过16位定时器的最长定时时间,最短不能少于定时中断服务程序的执行时间。
数字万年历实验报告
一、实验目的1. 掌握数字万年历的基本原理和设计方法。
2. 熟悉单片机编程和硬件电路设计。
3. 提高动手能力和问题解决能力。
二、实验原理数字万年历是一种能够显示年、月、日、星期、时、分、秒等信息的电子设备。
它主要由单片机、时钟芯片、显示模块、按键模块等组成。
本实验采用MSP430F149单片机作为核心控制单元,通过编程实现对万年历功能的实现。
三、实验设备1. MSP430F149单片机实验板2. 1602液晶显示屏3. DS1302时钟芯片4. 按键模块5. 电源模块6. 连接线四、实验步骤1. 设计硬件电路根据实验要求,设计万年历的硬件电路。
主要包括以下部分:(1)单片机模块:使用MSP430F149单片机作为核心控制单元。
(2)时钟芯片模块:使用DS1302时钟芯片提供时间基准。
(3)显示模块:使用1602液晶显示屏显示年、月、日、星期、时、分、秒等信息。
(4)按键模块:使用按键模块实现时间调整、功能选择等操作。
2. 编写程序根据硬件电路设计,编写万年历的程序。
主要步骤如下:(1)初始化硬件设备,包括单片机、液晶显示屏、时钟芯片等。
(2)从时钟芯片读取当前时间,并显示在液晶显示屏上。
(3)编写按键处理程序,实现时间调整、功能选择等功能。
(4)编写显示程序,实现年、月、日、星期、时、分、秒等信息的显示。
(5)编写时钟芯片校准程序,实现时间的精确控制。
3. 调试程序将编写好的程序烧录到MSP430F149单片机中,通过调试工具进行调试。
主要调试内容包括:(1)检查液晶显示屏显示是否正常。
(2)检查按键功能是否正常。
(3)检查时间调整、功能选择等功能是否正常。
(4)检查时钟芯片校准是否准确。
五、实验结果与分析1. 实验结果经过调试,万年历实验板能够正常显示年、月、日、星期、时、分、秒等信息,并且可以通过按键进行时间调整、功能选择等操作。
2. 实验分析(1)万年历的硬件电路设计较为简单,主要涉及单片机、时钟芯片、液晶显示屏、按键模块等。
十五位数码管电子钟万年历设计 c编写
十五位数码管电子钟万年历设计c编写后带原理设计图供参考(本人已验证可正常工作)我们以一个实际的时钟电路来说明定时器的软件编程方法,时钟就是我们最为常见的显示时、分、秒为单位的计时工具,它是典型的应用代表。
时钟的最小计时单位是秒,但使用单片机定时器来进行计时,若使用 6.0MHz的晶振,即使按工作方式1工作,最大的计时时间也只能到131ms,所以我们可把每个定时时间取125ms,这样定时器溢出8次(125ms╳8=1000ms)就得到最小的计时单位秒。
而要实现8次计数用软件方法实现是轻而易举的。
我们使用定时器1,以工作方式1工作,定时器进行125ms定时。
采用中断方法进行溢出次数的累计,当计满8次即得到1秒的计时。
一个时钟的计时累加,要实现分、时的进位,要用到多种进制,秒、分、时中的进位是十进制,秒向分进位和分想时进位却是六十进制,而每天又有十二小时制或二十四小时制,它们分别又是十二进制和二十四进制。
从秒到分和从分到小时可以通过软件累加和数值比较方法实现。
在单片机的内部RAM中,需要设置显示缓冲区,显示的时、分、秒值是从显示缓冲区中取出的,在RAM中设置四个单元作为显示缓冲区,分别是7AH、7BH、7CH。
为使电路和原理叙述方便,我们这里不显示秒值,秒的进位我们通过闪烁分值实现。
这样我们一共有四位LED分别显示时和分值。
同时时钟都需要校准的。
在程序中还需设置显示码表,要显示的数值通过查表指令将显示用的真正码值送到LED上。
我们用单片机AT89C2051的PP3.4和P3.5两个I/O口外接微动开关来实现时和分的校正,每按一次小时或分值加1,连续按下数值累计下去,实现时钟的校准。
在电路中我们还设置了一个蜂鸣器,用作简单报时用,如可设早上7:30分起床,中午1点30分再有起床报时,每次响时1分钟,响1秒,停2秒的方式,而不是连续响铃。
这个程序我们采用12小时制,为此,要在程序中设置相应的标志,以利于主程序识别。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电子时钟万年历设计报告学院:武夷学院班级:09电信1班组员:***一、设计要求与方案论证 (3)1.1设计要求 (3)1.1.1基本要求 (3)1.1.2拓展部分 (3)1.2 系统基本方案选择和论证 (3)1.2.1单片机芯片的选择方案和论证: (3)1.2.2 显示模块选择方案和论证: (4)1.2.3时钟芯片的选择方案和论证: (4)1.3 电路设计最终方案 (4)二、理论分析与计算 (4)2.1,秒数的产生由定时器T0产生: (4)2.2. 总天数的算法 (5)三.系统的硬件设计与实现 (5)3.1 电路设计框图: (5)3.2 系统硬件概述: (6)3.3 主要单元电路的设计 (6)3.3.1单片机主控制模块的设计 (6)3.3.2显示模块的设计 (7)3.3.3闹钟模块的设计 (9)3.3.4电源稳压模块 (10)四、系统的软件设计 (11)4.1程序流程框图 (11)4.2闹钟模块流程图: (11)4.3按键调整模块流程图: (12)五、测试方案与测试结果分析 (14)5.1 测试仪器 (14)5.2软件测试平台Keil C51 (14)5.3 模块测试 (14)5.3.1显示模块测试 (14)5.4测试结果分析与结论 (15)5.4.1测试结果分析 (15)5.4.2 测试结论 (15)六、作品总结 (15)参考文献 (15)附录一:系统电路图 (16)附录三:系统C程序 (17)一、设计要求与方案论证1.1设计要求1.1.1基本要求(1)准确显示:时、分、秒(24小时制)(2)显示星期(3)显示公历年月日(4)时间、日期、星期可调节(5)断电记忆功能1.1.2拓展部分(1)闹钟功能(2)显示阴历(3)显示24节气(4)其他1.2 系统基本方案选择和论证1.2.1单片机芯片的选择方案和论证方案一:采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V 的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP 在线编程技术, 当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。
方案二:采用AT89S52,片内ROM全都采用Flash ROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全兼容,该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。
所以选择采用AT89S52作为主控制系统。
1.2.2 显示模块选择方案和论证方案一:采用点阵式数码管显示,点阵式数码管是由8行8列的发光二极管组成,对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以不用此种作为显示.方案二:采用LED数码管动态扫描,LED数码管价格适中,对于显示数字最合适,但无法显示图形文字,在显示星期是也只能用数字表示,而且采用动态扫描法与单片机连接时,在编程时比较复杂。
所以也不采用了LED数码管作为显示。
方案三:采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示文字,图形,显示多样,清晰可见,所以在此设计中采用LCD液晶显示屏.1.2.3时钟芯片的选择方案和论证方案一:采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年以及闰年补偿的年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA.但在,题目中明确规定不能选用不可以使用任何专用的时钟芯片和模块,因此不采用此方案。
方案二:直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。
采用此种方案可以减少芯片的使用,也可以节约成本,所以采用此方案。
1.3 电路设计最终方案综上各方案所述,对此次作品的方案选定: 采用AT89S52作为主控制系统;采用单片机定时器提供时钟; 液晶显示屏作为显示。
二、理论分析与计算2.1,秒数的产生由定时器T0产生T0置10ms定时初值dc00H(2^16=65536D,dc00H=56320D)定时时间=(65536-56320)*(1/11.0592)*12=10ms (单片机晶振f0=11.0592Mhz)用累加的方法让定时时间累加一百次即可产生一秒时间:100*10ms=1000ms=1s2.2. 总天数的算法首先用if语句判断定义年到输入年之间每一年是否为闰年,是闰年,该年的总天数为366,否则,为355。
然后判断输入的年是否为定义年,若是,令总天数S=1,否则,用累加法计算出定义年到输入年之间的总天数,再把输入年的一月到要输出的月份之间的天数累加起来,若该月是闰年中的月份并且该月还大于二月,再使总天数加1,否则,不加,既算出从定义年1月1日到输出年的该月1日的总天数。
2.3 输出月份第一天为星期几的算法使总天数除以7取余加2得几既为星期几,若是7,则为星期日。
2.4. 算出输出月份的完整日历算法算出输出月份第一天为星期几后,把该日期以前的位置用空格补上,并从该日起一次输出天数直到月底,该月中的天数加上该月一日为星期几的数字再除以7得0换行,即可完整的输出该月的日历。
2.5 计算某一天是星期几的算法:蔡勒(Zeller)公式历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和一些分段计算公式),其中最著名的是蔡勒(Zeller)公式。
即:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1公式中的符号含义如下,w:星期;c:世纪-1;y:年(两位数);m:月(m大于等于5,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算);d:日;[ ]代表取整,即只要整数部分。
(C 是世纪数减一,y是年份后两位,M是月份,d是日数。
1月和2月要按上一年的13月和14月来算,这时C和y均按上一年取值。
)算出来的W除以7,余数是几就是星期几。
如果余数是0,则为星期日。
以2049年10月1日(100周年国庆)为例,用蔡勒(Zeller)公式进行计算,过程如下:蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1=49+[49/4]+[20/4]-2×20+[26× (10+1)/10]+1-1=49+[12.25]+5-40+[28.6]=49+12+5-40+28=54 (除以7余5)即2049年10月1日(100周年国庆)是星期五。
三.系统的硬件设计与实现3.1 电路设计框图3.2 系统硬件概述本电路是由AT89S52单片机为控制核心,具有在线编程功能,低功耗,能在3V 超低压工作;显示部份LCD1602实现,能够同时显示16x2即32个字符;闹钟部分由蜂鸣器构成,蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。
3.3 主要单元电路的设计 3.3.1单片机主控制模块的设计AT89S52单片机为40引脚双列直插芯片,有四个I/O 口P0,P1,P2,P3, MCS-51单片机共有4个8位的I/O 口(P0、P1、P2、P3),每一条I/O 线都能独立地作输出或输入。
单片机的最小系统如下图所示,18脚和19脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出.第9脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20脚为接地端,40脚为电源端.如图-1 所示。
图-1 主控制系统3.3.2显示模块的设计LCD1602液晶显示屏工业字符型液晶,能够同时显示16x2即32个字符。
(16列2行),有16个引脚,通过D0~D7的8位数据端传输数据和指令,引脚图如图6-5。
图6-5LCD1602引脚示意图LCD1602液晶显示屏引脚功能如表6-5所示:表6-5 LCD1602引脚功能管脚1V ss一般接地管脚2V dd接电源(+5V)管脚3 V0液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高管脚4 RS RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器1602液晶模块内部的控制器共有11条控制指令,如表10-14所示:9 读忙标志或地址0 1 BF 计数器地址10 写数到CGRAM或DDRAM)1 0要写的数据内容11 从CGRAM或DDRAM读数 1 1 读出的数据内容表10-14:控制命令表1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(说明:1为高电平、0为低电平)指令1:清显示,指令码01H,光标复位到地址00H位置。
指令2:光标复位,光标返回到地址00H。
指令3:光标和显示模式设置I/D:光标移动方向,高电平右移,低电平左移S:屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效。
指令4:显示开关控制。
D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:控制光标的开与关,高电平表示有光标,低电平表示无光标B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:光标或显示移位S/C:高电平时移动显示的文字,低电平时移动光标。
指令6:功能设置命令DL:高电平时为4位总线,低电平时为8位总线N:低电平时为单行显示,高电平时双行显示F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:字符发生器RAM地址设置。
指令8:DDRAM地址设置。
指令9:读忙信号和光标地址BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:写数据。
指令11:读数据。
将lcd的引脚与单片机连接,通过单片机实现对显示的输出,电路图实现如下:3.3.3闹钟模块的设计闹钟模块采用蜂鸣器实现,蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电。
通过单片机的p3.7引脚输出的电平变化来控制蜂鸣器的导通与否,设计如下:3.3.4电源稳压模块方案一:LM7805稳压方案二:USB接口+5V供电四、系统的软件设计4.1程序流程框图4.2闹钟模块流程图4.3按键调整模块流程图五、测试方案与测试结果分析5.1 测试仪器5.2软件测试平台Keil C51Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。