基于AT89C52单片机的电子万年历设计.doc_第1页
基于AT89C52单片机的电子万年历设计.doc_第2页
基于AT89C52单片机的电子万年历设计.doc_第3页
基于AT89C52单片机的电子万年历设计.doc_第4页
基于AT89C52单片机的电子万年历设计.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

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

文档简介

目 录1绪论21.1课题开发背景21.2设计目标21.3设计意义22 硬件设计22.1硬件设计框图22.2 系统硬件概述32.3 主要单元电路的设计3(1)主控制模块的设计3(2)时钟电路模块的设计3(3)显示模块的设计43系统软件设计43.1程序流程框图43.2程序设计6(1)主程序6(2)键盘控制模块7(3)DS1302时钟芯片模块11(4)LCD驱动显示模块164 调试及性能分析184.1程序编译184.2软件仿真184.3测试结果分析与结论195 总结196 致谢词19参考文献:19附录1 系统原理图20附录2 实物图21基于AT89C52单片机的电子万年历设计摘要:本设计拟用单片机作控制,利用液晶屏幕进行显示的电子万年历。本文首先描述系统硬件工作原理,并附以系统结构框图加以说明,介绍了本设计所应用的各硬件接口技术和各个接口模块的功能及工作过程,论证了设计方案理论的可行性。然后通过软件仿真,硬件调试,证实了方案的论证。本系统以单片机C语言进行软件设计,增加了程序的可读性和可移植性,为了便于扩展和更改,软件的设计采用模块化结构,使程序设计的逻辑关系更加简洁明了。系统通过点阵式液晶为载体显示数据,所以具有人性化的操作和美观的页面效果。可以显示时间、公历日期、星期。关键词:单片机;万年历;键盘;液晶技术 1绪论1.1课题开发背景单片机从20世纪70年代末出现后,以其卓越的性能,得到了广泛的应用,已经深入到各个领域。单片机芯片本身是按工业测控环境要求设计的,分为民用、工业品、军品、其中工业品和军品具有较强的适应恶劣环境的能力。由于单片机本身就是一个计算机系统,因此,只要在单片机的外围适当加一些必要的扩展电路及通道接口,就可以构成各种应用系统,如工业控制系统、数据采集系统、自动控制系统、自动测试系统、检测监视系统、智能仪表、功能模块等。单片机的应用领域十分广泛,自20世纪80年代以来,单片机的应用已经深入到工业、农业、国防、科研、机关、教育、商业以及家电、生活、娱乐、玩具等各个领域中。单片机应用在检测、控制领域中,具有以下特点:1)小巧灵活、成本低、易于产品化。2)可靠性好,适用范围宽。1.2设计目标本设计采用AT89C52单片机控制12864LCD液晶屏幕显示年、月、日、星期、时、分、秒,利用按钮实现对时间的调整。其中液晶屏幕显示部分利用单片机的P0口控制;用单片机P1.5、P1.6、P1.7口对时钟芯片DS1302的RST、SCLK、I/O引脚输入数据;用单片机P2.0、P2.4、P2.5、P2.6口连接按钮实现调整时间的功能;用P3.7口对喇叭进行控制,使按钮在调整时间时喇叭能发出提示声音。1.3设计意义本设计能对时,分,秒以数字显示并精确计时的装置,能广泛用于个人家庭,车站, 码头办公室等公共场所。由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表, 钟数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等,但是所有这些,都是以钟表数字化为基础的。因此,研究万年历及扩大其应用,有着非常现实的意义。2 硬件设计2.1硬件设计框图AT89C52主控制模 块LED数码管动态扫描显示模块键盘模块DS1302时钟模块声音模块 图1(硬件设计框图)2.2 系统硬件概述本电路是由AT89C52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由DS1302提供,可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V5.5V。采用三线接口与CPU进行同步通信。 DS1302内部有一个31*8的用于临时性存放数据的RAM寄存器。可产生年、月、日、周日、时、分、秒,具有使用寿命长,精度高和低功耗等特点,同时具有掉电自动保存功能;显示部份由12864LCD液晶显示屏进行显示。2.3 主要单元电路的设计(1)主控制模块的设计图2(主控模块)单片机的最小系统如图2所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出.第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路。(2)时钟电路模块的设计图3(时钟电路模块)图3示出DS1302的引脚排列,Vc1与Vc2同为电源。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RSTS置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电动行时,在Vcc大于等于2.5V之前,RST必须保持低电平。中有在SCLK 为低电平时,才能将RST置为高电平,I/O为串行数据输入端(双向)。SCLK始终是输入端。DS1302 有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0HFDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。 (3)显示模块的设计图4(液晶显示模块)如图4所示,本系统采用AMPIRE128X64液晶屏幕进行显示,管脚一共18个。CS1左半屏片选端,CS2右半屏片选端;VCC、GND是电源和接地;V0液晶显示驱动电压;RS是数据指令选择信号,H为数据,L为指令;R/W读写选择信号,H为读,L为写。E为LCD使能端,R/W为L时,E信号下降沿锁存DB7-DB0;R/W为H时,E为H,DDRAM数据读到DB7-DB0,如果只写不读的话可以接地处理。DB0-DB7数据传输端口。RST复位信号。-VOUT是液晶显示驱动电压。3系统软件设计3.1程序流程框图开始初始化读、写日期、时间分离日期时间显示程序日期、时间修改子程序立即返回图5(程序流程图框图)如图5所示,程序运行开始后对AMPIRE128X64LCD液晶屏幕和DS1302时钟芯片进行初始化,之后读出DS1302时钟芯片中的数据送入显示程序。当按钮按下后,立即调用键盘程序,当键盘程序运行完成后,立即返回。图6是键盘处理流程图。等待按键程序减键有效秒减1控制键有效,进入秒调整程序员加键有效秒加1等待按键程序减键有效时减1控制键有效,进入时调整程序员加键有效时加1等待按键程序减键有效月减1控制键有效,进入月调整程序员加键有效月加1等待按键程序减键有效分减1控制键有效,进入分调整程序员加键有效分加1等待按键程序减键有效日减1控制键有效,进入日调整程序员加键有效日加1等待按键程序减键有效星期减1控制键有效,进入星期调整程序员加键有效星期加1跳出时间调整程序,进入主循环程序按键有效,进入年调整程序等待按键程序加键有效减键有效年加1年减1按键有效图6(键盘处理流程图)3.2程序设计(1)主程序main()unsigned int i=0;lcd_init();/设置液晶显示器/在预定的位置上写入汉字write_chinese(64,6,fang);write_chinese(80,6,yuan1);write_chinese(96,6,zhi);write_chinese(112,6,zuo);write_chinese(0,2,xing);write_chinese(16,2,qi);write_chinese(32,0,nian);write_chinese(80,0,yue);write_chinese(112,0,ri);write_chinese(0,4,An);write_chinese(16,4,Hui);write_chinese(32,4,Shang); write_chinese(48,4,Mao);write_chinese(64,4,Zhi1); write_chinese(80,4,Ye); write_chinese(96,4,Ji); write_chinese(112,4,Shu); write_chinese(0,6,Xue);write_chinese(16,6,Yuan); write_chinese(32,6,xx);time_data6=0x09;/年time_data4=0x06;/月time_data3=0x06;/日time_data2=0x08;/时time_data1=0x00;/分 time_data0=0x00;/秒time_data5=0x06;/星期v_Set1302(time_data);/初始化时钟芯片while(1)/主循环 m=!m;Keyscan();if(keyval=0xff & df=0)GetTime();Keyproc();displaytime();(2)键盘控制模块#define keyboardCode P2/键盘控制端口uchar keyval=0xff; /键值uchar code initialKeyboardCode = 0xfe, 0xfd, 0xfb, 0xf7 ; /键盘扫描码uchar code getKeyboardCode = 0xee, 0xde, 0xbe, 0x7e, 0xed, 0xdd, 0xbd, 0x7d, /键值 0xeb, 0xdb, 0xbb, 0x7b, 0xe7, 0xd7, 0xb7, 0x77 ; uchar code theActionCode = 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15; / 键盘序号void Keyscan(void)/键盘扫描uchar sender = 0x00;uchar counterOne = 0x00;uchar counterTwo = 0x00;uchar keyvals=0xff;for(counterOne=0x00; counterOne4; counterOne+)keyboardCode = initialKeyboardCodecounterOne; /选择扫描码sender = keyboardCode; /得到键值delay10ms(1); for(counterTwo=0x00; counterTwo0x59) time_datakeyi=0; if(keyi=2) /时 if(time_datakeyi0x23) time_datakeyi=0;if(keyi=3) /日 if(time_datakeyi0x31) time_datakeyi=1;if(keyi=4) /月 if(time_datakeyi0x12) time_datakeyi=1;if(keyi=5) /星期 if(time_datakeyi0x07) time_datakeyi=1;if(keyi=6) /年 if(time_datakeyi0x99) time_datakeyi=0;Convert();void subtime(uchar keyi) /*控制时间量的减*/ if(keyi=0|keyi=1) /分,秒if(time_datakeyi=0x00) time_datakeyi=0x59;else time_datakeyi-=1; if(keyi=2) /时if(time_datakeyi=0x00) time_datakeyi=0x23;else time_datakeyi-=1; if(keyi=3) /日if(time_datakeyi=0x01) time_datakeyi=0x31;else time_datakeyi-=1; if(keyi=4) /月if(time_datakeyi=0x01) time_datakeyi=0x12;else time_datakeyi-=1; if(keyi=5) /星期if(time_datakeyi=0x01) time_datakeyi=0x07;else time_datakeyi-=1; if(keyi=6) /年if(time_datakeyi=0x00) time_datakeyi=0x99;else time_datakeyi-=1; if(time_datakeyi=0x0f | time_datakeyi=0x1f | time_datakeyi=0x2f | time_datakeyi=0x3f | time_datakeyi=0x4f | time_datakeyi=0x5f| time_datakeyi=0x6f | time_datakeyi=0x7f | time_datakeyi=0x8f | time_datakeyi=0x9f) time_datakeyi-=6; Convert();void Keyproc() /*选择需要控制的时间变量*/ if(keyval!=0xff)beep(); if(keyval=0)df+=1;if(df=8)v_Set1302(time_data);df=0;delay10ms(50); if(df=1)if(keyval=1)addtime(0);if(keyval=2)subtime(0);if(df=2)if(keyval=1)addtime(1);if(keyval=2)subtime(1);if(df=3)if(keyval=1)addtime(2);if(keyval=2)subtime(2);if(df=4)if(keyval=1)addtime(3);if(keyval=2)subtime(3);if(df=5)if(keyval=1)addtime(4);if(keyval=2)subtime(4);if(df=6)if(keyval=1)addtime(5);if(keyval=2)subtime(5);if(df=7)if(keyval=1)addtime(6);if(keyval=2)subtime(6);keyval=0xff;(3)DS1302时钟芯片模块sbit T_CLK = P17; /*实时时钟时钟线引脚 */sbit T_IO = P16; /*实时时钟数据线引脚 */sbit T_RST = P15; /*实时时钟复位线引脚 */void v_RTInputByte(uchar ucDa) /*功能: 往DS1302写入1Byte数据*/ uchar i;ACC = ucDa;for(i=8; i0; i-)T_IO = a0;T_CLK = 1;T_CLK = 0;ACC = ACC 1; uchar uc_RTOutputByte(void) /*从DS1302读取1Byte数据*/ uchar i;for(i=8; i0; i-)ACC = ACC 1;a7 = T_IO;T_CLK = 1;T_CLK = 0; return(ACC); void v_W1302(uchar ucAddr, uchar ucDa) /*往DS1302写入数据*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令 */v_RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0; uchar uc_R1302(uchar ucAddr) /*读取DS1302某地址的数据*/uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令 */ucDa = uc_RTOutputByte(); /* 读1Byte数据 */T_CLK = 1;T_RST =0;return(ucDa);void v_BurstW1302T(uchar *pSecDa) /*往DS1302写入时钟数据(多字节方式)*/uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbe); /* 0xbe:时钟多字节写命令 */for (i=8;i0;i-) /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/v_RTInputByte(*pSecDa);/* 写1Byte数据*/pSecDa+;T_CLK = 1;T_RST =0; void v_BurstR1302T(uchar *pSecDa) /*读取DS1302时钟数据*/uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbf); /* 0xbf:时钟多字节读命令 */for (i=8; i0; i-) *pSecDa = uc_RTOutputByte(); /* 读1Byte数据 */pSecDa+;T_CLK = 1;T_RST =0;void v_BurstW1302R(uchar *pReDa) /*往DS1302寄存器数写入数据(多字节方式)*/uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xfe); /* 0xbe:时钟多字节写命令 */for (i=31;i0;i-) /*31Byte 寄存器数据 */v_RTInputByte(*pReDa); /* 写1Byte数据*/pReDa+;T_CLK = 1;T_RST =0; void v_BurstR1302R(uchar *pReDa) /*读取DS1302寄存器数据*/uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xff); /* 0xbf:时钟多字节读命令 */for (i=31; i0; i-) /*31Byte 寄存器数据 */*pReDa = uc_RTOutputByte(); /* 读1Byte数据 */pReDa+;T_CLK = 1;T_RST =0;void v_Set1302(uchar *pSecDa) /*设置初始时间*/uchar i;uchar ucAddr = 0x80; v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/for(i =7;i0;i-) v_W1302(ucAddr,*pSecDa); /* 秒 分 时 日 月 星期 年 */pSecDa+;ucAddr +=2;v_W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/void v_Get1302(uchar ucCurtime) /*读取DS1302当前时间*/uchar i;uchar ucAddr = 0x81;for (i=0;i7;i+)ucCurtimei = uc_R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */ucAddr += 2;void Convert()/时间格式转换 BCD码-十进制数dis_time0=time_data0&0x0f; /秒个dis_time1=time_data0/16; /秒十dis_time2=time_data1&0x0f; /分个dis_time3=time_data1/16; /分十dis_time4=time_data2&0x0f; /时个dis_time5=time_data2/16; /时十dis_time6=time_data3&0x0f; /日个dis_time7=time_data3/16; /日十dis_time8=time_data4&0x0f; /月个dis_time9=time_data4/16; /月十dis_time10=time_data6&0x0f;/年个dis_time11=time_data6/16; /年十dis_time12=time_data5&0x0f;/星期void GetTime() /获取时间v_Get1302(time_data);Convert();void displaytime() /显示时间write_digit(0,0,two); /年份 2write_digit(8,0,zero); /年份 0write_digit(16,0,zero+dis_time11*16); /年份 十位write_digit(24,0,zero+dis_time10*16); /年份 个位write_digit(64,0,zero+dis_time9*16); /月份 十位write_digit(72,0,zero+dis_time8*16); /月份 个位write_digit(96,0,zero+dis_time7*16); /日 十位write_digit(104,0,zero+dis_time6*16); /日 个位 write_digit(64,2,zero+dis_time5*16); /时 十位write_digit(72,2,zero+dis_time4*16); /时 个位write_digit(80,2,maohao);write_digit(88,2,zero+dis_time3*16); /分 十位write_digit(96,2,zero+dis_time2*16); /分 个位write_digit(104,2,maohao);write_digit(112,2,zero+dis_time1*16); /秒 十位write_digit(120,2,zero+dis_time0*16); /秒 个位write_chinese(32,2,cone+(dis_time12-1)*32);/星期(4)LCD驱动显示模块/lcd控制口#define LCDPORT P0sbit di = P10; /rssbit rw = P11;sbit e = P12;sbit cs1 = P13;sbit cs2 = P14;void lcd_init(void) /*LCD的初始化*/unsigned char x,y;rst=0;rst=1;e=di=rw=0;cs1=cs2=1;cs1=0;cs2=1;di=rw=0;LCDPORT=0x3f;e=1;delay(2);e=0;delay(2);cs1=0;cs2=1;di=rw=0;LCDPORT=0xc0;e=1;delay(2);e=0;delay(2);cs1=cs2=0;cs1=1;cs2=0;di=rw=0;LCDPORT=0x3f;e=1;delay(2);e=0;delay(2);cs1=1;cs2=0;di=rw=0;LCDPORT=0xc0;e=1;delay(2);e=0;delay(2);cs1=cs2=0; for (y=0;y8;y+) for (x=0;x128;x+) lw(x,y,0); void write_chinese(unsigned char x,unsigned char y,unsigned char array) /*向x,y处写入一个汉字*/unsigned char j,dd;for(j=0;j32;j+)dd=arrayj;if(j16) lw(x+j,y,dd); else lw(x+j-16,y+1,dd);void write_flashcn(unsigned char x,unsigned char y,unsigned char array) /*向x,y处写入一个汉字,再次写入时取反,需要与变量m配合,构成闪烁效果*/unsigned char j,dd;for(j=0;j32;j+)if(m=1)dd=arrayj;elsedd=arrayj;if(j16) lw(x+j,y,dd);elselw(x+j-16,y+1,dd);void write_flashcn1(unsigned char x,unsigned char y,unsigned char array) /*向x,y处写入一个字符*/unsigned char j,dd;for(j=0;j16;j+)if(m=1)dd=arrayj;elsedd=arrayj;if(j8) lw(x+j,y,dd);elselw(x+j-8,y+1,dd);void write_digit(unsigned char x,unsigned char y,unsigned char array) /*向x,y处写入一个阿拉伯数字*/unsigned char j,dd;for(j=0;j16;j+)dd=arrayj;if(j8)lw

温馨提示

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

评论

0/150

提交评论