电子日历时钟.doc_第1页
电子日历时钟.doc_第2页
电子日历时钟.doc_第3页
电子日历时钟.doc_第4页
电子日历时钟.doc_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一章:实验概要及相关器材摘要: 单片计算机即单片微型计算机(Single-Chip Microcomputer),是集CPU,RAM,ROM,定时,计数和多种接口于一体的微控制器。体积小,成本低,功能强,广泛应用于智能产品和工业自动化上。而51单片机是各单片机中最为典型和最有代表性的一种。这次课程设计可以提高我们的设计、开发软、硬的能力。前言: 本文通过用对一个能实现定时,时钟,日历显示功能的时间系统的设计学习,详细介绍了51单片机应用中的数据转换显示,数码管显示原理,动态扫描显示原理,单片机的定时中断原理、从而达到学习,了解单片机相关指令在各方面的应用。系统由AT89C52、LED数码管、按键、二极管等部分构成,能实现时钟日历的功能:能进行时、分、秒的显示。也具有日历计算、显示和时钟,日历的校准、定时时间的设定输出等功能。后附有电路图,程序清单,各数据存储单元的所在地址,输入输出口对应表。以供读者参考.因我们也是个初学者,水平有限,难免有疏落不足之处,敬请老师给与批评指正。说明书: 系统由AT89C52、LED数码管、按键、发光二极管等部分构成,能实现时间的调整、定时时间的设定,输出等功能。系统的功能选择由SB0、SB1、SB2、SB3、SB4完成。其中SB0为时间校对,定时器调整功能键,按SB 0进入调整状态。SB1为功能切换键。第一轮按动SB1依次进入一路、二路、三路定时时间设置提示程序,按SB3进入各路定时调整状态。定时时间到,二极管发亮。到了关断时间后灭掉。如果不进入继续按SB1键,依次进入时间?年?位校对、?月?位校对、?日?位校对、?时?位校对、?分?位校对、?秒?位校对状态。不管是进入那种状态,按动SB2皆可以使被调整位进行不进位增量加1变化。各预置量设置完成后,系统将所有的设置存入RAM中,按SB1退出调整状态。上电后,系统自动进入计时状态,起始于?00?时?00?分。SB4为年月日显示转换键,可使原来显示时分秒转换显示年月日。器材一览表: IC 89S52,IC 74LS244各一个,IC CD4511两个,IC座40脚三个,IC座20脚一个,IC座18脚两个,LED七段数码管6个,晶体振荡器12MHZ一个,小型蜂鸣器一个,晶体三极管PNP8550六个,微型按钮4脚3个,电阻10K4个,4.7K两个,3K9个,330欧姆17个,100欧姆8个,电解电容10UF一个,瓷片电容30P两个,万用表一个,焊锡及万能电路板一个.第二章:电路原理分析:1:显示原理:电原由6个共阴极的数码管组成时、分、秒的显示。P0口的8条数据线P0.0至P0.7分别与两个CD4511译码的ABCD口相接,P2口的P2.0至P2.2分别通过电阻R10至R13与VT1至VT3的基极相连接。这样通过P0口送出一个存储单元的高位、低位BCD显示代码,通过P2口送出扫描选通代码轮流点亮LED1至LED6,就会将要显示的数据在数码管中显示出来。从P0口输出的代码是BCD码,从P2口输出的就是位选码。这是扫描显示原理。2:数码管结构及代码显示:共阴LED数码管由8只发光二极管VD1至VD8共阴连接并按?8?字形结构排列而成。这样,我们将这些二极管的正极接高低不同的电位,把所有的负极接地,当正极为高电位时相应的二极管就会导通而发光,从而使数码管呈现不同的字符。而只有P2相应呈现高电位,VT个管导通,LED1的GND与地相接,LED位被选中才具备发光的使能条件;可见,在利用P2口送出位选码,使各位轮流得到发光使能条件的同时,通过P0口分别送出不同的段选码,就会在LED1至LED4中显示出不同的数字来。3:键盘及读数原理: 键盘是人与微机打交道的主要设备,按键的读取容易引起误动作。可采用件去动的方法处理,软件的触点在闭合和断开的时候会产生抖动,这时触点的逻辑电是不稳定的,如不采取妥善处理的话,将引起按键命令错误或重复执行,在这里用软件延时的方法来避开抖动,延时时间20ms.4:连击功能的实现:按下某键时,对应的功能键解释程序得到执行,如操作者没有释放按键,则对应的功能会反复执行,好象连续执行,在这里我们采用软件延时250ms,当按键没释放则执行下一条对应程序。利用连击功能,能实现快速调时操作。第三章 程序设计中的思想本系统的主程序主要完成时间显示和定时输出判断功能。而年月日显示和各时间单元进位,时间设定时,调定时间设定时等功能全部在中断服务程序中完成。1:数据与代码转换由前述可知,从P2口输出位选码,从P0口输出段选码,LED就会显示出数字来。但P0口的输出的数据是要BCD码,各存储单元存储的是二进制数,也就是和要显示出的字符表达的含义是不一致的。可见,将要显示的存储单元的数据直接送到P0口去驱动LED数码管显示是不能正确表达的,必须在系统内部将要显示的数据经过BCD码行转换后,将各个单元数据的段选代码送入P0口,给CD4511译码后去驱动数码管显示。具体转换过程如下: 我们先将要显示的数据装入累加器A中,再将A中的数据转换成高低两位的BCD码,再放回A中,然后将A中的值输出。如:有一个单元存储了45这样一位数,则需转换成四位的BCD码:(0100)(0101)然后放入A中。A中BCD码,高位四位代表?4?低四位代表?5?同时送给两个译码器中,译码后?45?字就在两个LED中显示出来。2:计时功能的实现与中断服务程序时间的运行依靠定时中断子程序对时钟单元数值进位调整来实现的。计数器T0打开后,进入计时,满100毫秒后,重装定时。中断一次,满一秒后秒进位,满60秒后即为1分钟,分钟单元进位,60分到了后,时单元进位,24小时满后,天单元进位。这样然后根据进率,得到年、月、日、时、分、秒存储单元的值,并经译码后,通过扫描程序送LED中显示出来,实现时钟计时功能。累加是用指令INC来实现的。进入中断服务程序以后,执行PUSH PSW和PUSH A将程序状态寄存器PSW的内容和累加器A中的数据保存起来,这便是所谓的?保护现场?.以保护现场和恢复现场时存取关键数据的存储区叫做堆栈。在软件的控制之下,堆栈可在片内RAM中的任一区间设定,而堆栈的数据存取与一般的RAM存取又有区别,对它的操作,要遵循?后进先出?的原则。 3:时钟误差分析 开启定时器/计数器0,使之开始计时,中断后进入中断程序。自停止计数到、计数又开始,中间执行了7条指令,也就是延迟了13个单周期共用时间26us,这样,每个中断的总时间应为为100.026sm,而原来定时是100ms,所以,也就是说每次中断定时多了26um.这样,可改变计数重装值,使每次中断定时时间为99.974sm,加上原来的7条指令所用的时间,正好100sm.计数10次得1s.这样就可得到较精确的计时秒数,然后根据进率,得到时.分的值。4:时间控制功能与比较指令系统的另一功能就是实现对执行设备的定时开关控制,其主要控制思想是这样的:先将执行设备开启的时间和关闭时间置入RAM某一单元,在计时主程序当中执行几条比较指令,如果当前计时时间与执行设备的设定开启时间相等,就执行一条CLR指令,将对应的那路P3置为高电位,开启;如果当前计时时间与执行设备设定的关闭时间相等,就执行SETB对应的P3置低电位,二极管截止,。实现此控制功能用到的比较指令为CJNE A,#direct,rel,其转移条件是累加器A中的值与立即数不等则转移。 第四章 程序流程图 第四章 电路原理图第五章 源程序及注释/*电子钟程序,功能:时钟,日期,定时,秒表。*/*按键功能:键1切换状态;键2调整;键3加调整;键4减调整。*/*操作:按键1切换显示页面,按以下顺序切换:时钟日期闹钟秒表 */*按键2进入调整状态,闪烁位为调整位,在调整状态按键2则进行调整位的移动,按键1则返回当前显示状态。*/*在调整状态时,按键3和4进行当前调整位的调整,按键3和4只在调整状态有效。按键3进行当前所在位的增加,按键4进行当前位的减少。特别的,在按按键2切换到秒表状态时,再按2开始计时,再按2,秒表暂停,再按3秒表清零。*/*程序开始*#include#define uchar unsigned charuchar data state=0; /设置状态变量 /*state=0时间;state=1日期;state=2闹钟;state=3秒表 */uchar data adjuststate=0; /设置调整位 /*adjuststate=0不调整;adjuststate=1调整*/ 用于决定是否开启计时器T1uchar data timedata3=0,0 ,12; /时间状态值uchar data datedata3=1,10,7; /日期状态值uchar data alarmdata3=0,0,7; /闹钟状态值uchar data watchdata3=0,0,0; /秒表状态值uchar data display6=0,0,0,0,0,0;uchar data shift=0; /设置当前调整位, 0表示不调整uchar data button = 0; /记录获得的按键,0表示没有按键uchar data temp=0; /判断闹钟是否启动uchar data counter1=0; /T0定时器中断次数计数器uchar data counter2=0; /T1定时器中断次数计数器uchar data flag=0; /0.4秒闪烁的标志sbit key0=P10; /定义P1.0,P1.1,P1.2,P1.3键为不同的按键的命令输入端sbit key1=P11;sbit key2=P12;sbit key3=P13;char code dis_711=0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff; /共阳极控制字/*共阳LED段码表 0 1 2 3 4 5 6 7 8 9 不亮 */uchar code scan_col6=0xfe,0xfd,0xfb,0xf7,0xef,0xdf; /列扫描控制字uchar code date_table13 = 29,31,28,31,30,31,30,31,31,30,31,30,31; /日期与月份关系表,闰年的二月的天数置于数组的第一位/*定义原函数*/void statedisplay(); /显示函数void getbutton(); /获取按键函数void statescan(); /扫描函数void increase(); /增加调整位函数void decrease(); /减少调整位函数void stopwatchstart(); /秒表启动函数void alarm(); /闹钟启动函数void delay10ms() /延时10ms函数void delay10ms(void) /*延时10ms*/ unsigned char i,j,k; for(i=5;i0;i-) for(j=4;j0;j-) for(k=248;k0;k-); /定时器T0的中断函数void time1_interrupt() interrupt 1 ET0=0;TR0=0;TH0=0xB1;TL0=0xE0;TR0=1; /重置计数器T0和关闭计数器T0中断 counter1+; if(counter1=49) counter1= 0; if (timedata0=59) timedata0 = 0; if (timedata1=59) timedata1 = 0; if (timedata2=23) timedata2 = 0; if (datedata1=2)&(datedata2%4=0) if(datedata0=date_table0) datedata0 = 1; datedata1+; else datedata0+; else if(datedata0=date_tabledatedata1) datedata0 = 1; if(datedata1=12) datedata1 = 1; if(datedata2=99) datedata2 = 0; else datedata2+; else datedata1+; else datedata0+; else timedata2+; else timedata1+; else timedata0+; counter1=0; ET0 = 1; /开启中断/定时器T1的中断函数void time2_interrupt(void) interrupt 3 ET1=0;TR1=0;TH1=0xB1;TL1=0xE0;TR1=1; /重置计数器T1和关闭计数器T1中断 counter2+; if(counter2=20) counter2=0; if(flag=0) flag= 1; else flag=0; ET1 = 1; /获取按键函数/void getbutton() button = 0; if(key0=0) delay10ms(); if(key0=0) while(key0=0) delay10ms(); statedisplay(); button = 1; if(key1=0) delay10ms(); if(key1=0) while(key1=0) delay10ms(); statedisplay(); button = 2; if(key2=0) delay10ms(); if(key2=0) while(key2=0) delay10ms(); statedisplay(); button = 3; if(key3=0) delay10ms(); if(key3=0) while(key3=0) delay10ms(); statedisplay(); button = 4; /扫描函数/void statescan() getbutton(); if(button!=0) if(adjuststate=0) /当前处于非调整状态 if(button=1) if(state3)state+; else state=0; if(button=2) if(state!=3) adjuststate=1;shift=1;TR1 = 1;flag = 1; /非秒表状态,开启计时器T1 else stopwatchstart(); if(button=3) if(state=3)watchdata0=0; watchdata1=0; watchdata2=0; /秒表状态下按键3,秒表复位 if(state=2)temp=1; /闹钟状态下按键3,启动闹钟 if(button=4&state=2)temp=0; /闹钟状态下按键4,关闭闹钟 else /当前处于调整状态 if(button=1)adjuststate=0;shift=0;TR1 = 0;flag = 0; /关闭计时器T1 if(button=2) if(state!=3) if(shift3)shift+; else shift=1; if(button=3) increase(); if(button=4) decrease(); else statedisplay();/显示函数/void statedisplay() uchar k; if(state=0) /显示时间 display0=timedata0%10; display1=timedata0/10; display2=timedata1%10; display3=timedata1/10; display4=timedata2%10; display5=timedata2/10; if(state=1) /显示日期 display0=datedata0%10; display1=datedata0/10; display2=datedata1%10; display3=datedata1/10; display4=datedata2%10; display5=datedata2/10; if(state=2) /显示闹钟 display0=alarmdata0%10; display1=alarmdata0/10; display2=alarmdata1%10; display3=alarmdata1/10; display4=alarmdata2%10; display5=alarmdata2/10; if(state=3) /显示秒表 display0= watchdata 0%10; display1= watchdata 0/10; display2= watchdata 1%10; display3= watchdata 1/10; display4= watchdata 2%10; display5= watchdata 2/10; for(k=0;k6;k+) if(shift =(k/2+1) /判断此位是否位闪烁位 if(flag=1) /显示闪烁位 P0 = dis_7displayk; P2 = scan_colk; delay10ms(); P2 = 0xFF; else /不显示闪烁位 P0 = dis_710; P2 = scan_colk; delay10ms(); P2 = 0xFF; else /显示非闪烁位 P0 = dis_7displayk; P2 = scan_colk; delay10ms(); P2 = 0xFF; /增加位调整函数void increase() /调整时间 if(state=0) if(shift=1|shift=2) if(timedatashift-159) timedatashift-1+; else timedatashift-1=0; if(shift=3) if(timedatashift-123) timedatashift-1+; else timedatashift-1=0; /调整日期 if(state=1) /调整日 if(shift=1) if(datedata2%4=0&datedata1=2) if(datedata0date_table0) datedata0+; else datedata0 =1; else if(datedata0date_tabledatedata1) datedata0+; else datedata0=1; if(shift=2) /调整月 if(datedata1date_table0) datedata0=date_table0; else if(datedata0date_tabledatedata1) datedata0=date_tabledatedata1; else datedata1=1; if(shift=3) /调整年 if(datedata20) timedatashift-1=timedatashift-1-1; else timedatashift-1=59; if(shift=3) if(timedata20) timedata2=timedata2-1; else timedata2=23; /调整日期 if(state=1) if(shift=1) if(datedata2%4=0&datedata1=2) if(datedata01)datedata0=datedata0-1; else datedata0 = date_table0; else if(datedata01) datedata0=datedata0-1; else datedata0= date_tabledatedata1; if(shift=2) if(datedata11) datedata1=datedata1-1; if(datedata0date_tabledatedata1) if(datedata1=2&datedata2%4=0) datedata0=date_table0; else datedata0=date_tabledatedata1; else datedata1=12; if(shift=3) if(datedata20) if(datedata2%4=0&datedata1=2) if(datedata0=date_table0) datedata0=date_table2; datedata2=datedata2-1; else if(datedata1=2&datedata0=date_table0) datedata0=date_table2; datedata2=99; /调整闹钟 if(state=2) if(shift=1|shift=2) if(alarmdatashift-10) alarmdatashift-1-; else alarmdatashift-1=59; if(shift=3) if(alarmdata20) alarmdatashift-1-; else alarmdata2=23; /秒表启动函数void stopwatchstart() while(1) getbutton(); if(button=2)break; /若按键2,则暂停秒表 if(button=0) /没有按键,秒表计时 watchdata0=watchdata0+1; if(watchdata0=100) watchdata 0 = 0; watchdata1=watchdata1+1; if(watchdata1=100) watchdata1 = 0; watchdata2=watchdata2+1; if(watchdata2=100) watchdata2 = 0; statedisplay(); /刷新显示页面 /闹钟函数void alarm() if(temp=1) if(timedata1=alarmdata1&timedata2=alarmdata2) P3=0x01; getbutton(); if(button=4) temp=0; else P3=0x03; else P3=0x02; /主函数void main(void) TH0=0xB1;TL0=0xE0; / 20ms定时初值(T0计时用) TH1=0xB1;TL1=0xE0; / 20ms定时初值(T1计时用) TMOD=0X11; ET0=1; TR0=1; EA=1; ET1=1; TR1=0; state = 0; /初态为时间状态 while(1) statescan(); statedisplay(); alarm(); 第六章 实验心得及体会1:原理图设计中要注意的问题原理图设计中要有“拿来主义”,现在的芯片厂家一般都可以提供参考设计的原理图,所以要尽量的借

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论