1、南昌航空大学科技学院毕业设计(论文)题目: 基于单片机的多功能万年历 专业名称 电气自动化班级学号 088202140学生姓名 叶庆指导教师 李军华二O一二年 五 月 目 录1 设计任务与要求2 方案设计与论证2.1方案一 3 2.2 方案二 4 2.3 方案三 42.4 方案论证 53 硬件单元电路设计与参数计算3.1 主控制系统6 3.2时钟振荡电路 73.3复位电路 8 3.4 DS1302时钟电路9 3.5按键电路10 3.6 显示电路10 3.7蜂鸣器电路 114 流程图与各模块的程序4.1 流程图124.2 部分子程序135 电路仿真调试 5.1 总原理图18 5.2 整体电路仿真
2、图以及仿真结果分析195.3 调试20参考文献21致谢22附录23毕 业设计(论文)工作内容及完成时间: 工作安排如下: 1、查阅文献,翻译英文资料,书写开题报告 第1-4周 2、相关资料的获取和必要知识的学习 第5-9周 3、设计系统的硬件和软件模块并调试 第10-14周 4、撰写论文 第15-16周 5、总结,准备答辩 第17周参考文献1朱月秀 冷祖祁,单片机基础(第3版):北京航航天大学出版社2 华成英 童诗白, 模拟电子技术基础(第四版):高等教育出版社3赵建领 薛园园 ,零基础学单片机C语言程序设计:机械工业出版社4楼然苗 李光飞. 单片机课程设计指导:北京航航天大学出版社5李凤霞.
3、 C语言程序设计教程(第二版):北京理工大学出版社6赵亮 侯国锐. 单片机C语言编程与实例:人民邮电出版社7张义和 王敏男 许宏昌 余春长 . 例说5单片机(C语言版):人民邮电出版社8郭天祥编.新概念51单片机C语言教程.北京:电子工业出版社,2009.9周兴华编.手把手教你学单片机C程序设计.北京:北京航空航天大学出版社,2008.6. 10 谭浩强编.C程序设计:清华大学出版社,2008.7. 信息工程 系 自动化 专业类 0882021班学生(签名): 填写日期: 2012 年 5 月 20日指导教师(签名): 助理指导教师(并指出所负责的部分):信息工程 系主任(签名):附注:任务书
4、应该附在已完成的毕业设计说明书首页。 美国DALLAS公司推出的具有涓细电流充电能的低功耗实时时钟电路DS1302。它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用35V电压供电。 综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。本设计是基于51系列的单片机进行的电
5、子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。在硬件与软件设计时,没有良好的基础知识和实践经验会受到很大限制,每项功能实现时需要那种硬件,程序该如何编写,算法如何实现等,没有一定的基础就不可能很好的实现。关键词:单片机;实时时钟;DS1302 AT89C52学士学位论文原创性声明本人声明,所呈交的论文是本人在导师的指导下独立完成的研究成果。除了文中特别加以标注引用的内容外,本论文不包含法律意义上已属于他人的任何形式的研究成果,也不包含本人已用于其他学位申请的论文或成果。对本文的研究作出重要贡献的个人和集体,
6、均已在文中以明确方式表明。本人完全意识到本声明的法律后果由本人承担。作者签名: 日期:2012年5月20日学位论文版权使用授权书本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权南昌航空大学科技学院可以将本论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。 作者签名: 日期:导师签名: 日期1 设计任务与要求1、 能够显示年、月、日、时、分 秒 。2、 可以人为校正年、月、日、时、分、秒。3、 具有闹钟功能。4、 能够进行整点的提醒。5、 按键显示温
7、度。2、方案设计与论证2.1方案一按照系统设计的功能的要求,初步确定系统由主控模块、时钟模块、显示模块各键盘接口模块共4个模块组成,电路系统构成框图如图1所示。主控芯片使用52系列AT89S52单片机,时钟芯片使用美国DALLAS公司推出的一款高性能、低功耗、带RAM的实时时钟DS1302。采用DS1302作为计时芯片,可以做到计时准确。更重要的是,DS1302可以在很小电流的后备电源(2.5V-5.5V电源,在2。5V时耗电小于300nA)下继续计时,而且DS1302可以编程选择多种充电电流来对后备电源进行慢速充电,可以 保证后备电源基本功不耗电。显示模块采用普通的共阳LED数码管,键输入采
8、用查询法实现功能调整。单片机AT89C52键盘扫描电路LED显示电路 时钟电路 (DS1302)图1 电子万年历电路系统构成框图2.2方案二按照系统设计的要求和功能,将系统分为主控模块、时钟电路模块、按键扫描模块,LCD显示模块,电源电路、复位电路、晶振电路几个模块,系统框图如图2所示。主控模块采用AT89S52单片机,按键模块用四个按键,用于调整时间和设定闹钟,显示模块采用LCD1602,时钟电路模块采用DS1302实时时钟实现对时间,日期的操作。单片机AT89C52LCD液晶显示蜂鸣器电路按键模块复位电路晶振电路图2基于AT89C52单片机的电子万年历系统框图2.3方案三按照系统设计的要求
9、和功能,将系统分为主控制器模块、显示模块、按键开关模块、蜂鸣器电路模块。系统框图如图3所示,主控制模块采用AT89S52单片机为控制中心,显示模块采用液晶LCD1602显示,计时使用AT89S52单片机自带的定时器功能,实现对时间、日期的操作,通过按键盘开关实现对时间、日期的调整。 单片机AT89C52LCD液晶显示DS1302时钟模块按键模块复位电路晶振电路蜂鸣器电路图3基于AT89C52单片机的电子万年历总体设计框图2.4方案论证上面提到的三个方案中,在电路原理方面大致相同,都能够达到设计任务与要求,在方案一款方案三中使用外部的时钟芯片DS1302来实现日期和时间的操作,方案二中则利用了单
10、片机自身的定时器功能;在方案二和方案三在显示模块上都使用液晶显示屏LCD1602作为显示,方案一则使用LED数码管作为显示,采用LED数码管动态扫描,数码管的价格适中,对于显示数字较好,而且使用单片机的端口也较少;采用LCD1602液晶显示屏,液晶显示屏的显示功能强大,可以显示大量文字、图形,清晰可见,价格相对LED数码管来说要昂贵些,但是基于本设计显示的东西较多,若采用LED数码管的话,所需数码管较多,价格也相应的会提高,而且不利于控制,对于LCD1602,它所使用的端口也不很多,能够清晰的显示,比较适合显示大量的数字,因此选择LCD1602作为显示模块。DS1302是一款高性能的实时时钟芯
11、片,以计时准确、接口简单、使用方便、工作电压范围宽和低功耗等优点,得到广泛的应用,而且在掉电时能够在外部纽扣电池的供电下继续工作,不会因为掉电后,其时间就要重新设置,方案二中使用定时器的功能,当在掉电的时候就会使时间和日期回到原来设定的初始值,同时直接采用单片机定时计数提供秒信号,使用程序实现年时间和日期,采用此种方案,节约成本,但是实现的时间误差较大,所以不采用这种方案。通过对上述方案的论证分析,本次设计选择方案三,采用AT89C52作为主控制系统,DS1302提供时钟,LCD1602液晶作为显示模块3硬件单元电路设计与参数计算3.1主控制系统单片机中央处理系统的方案设计,我们选用具有ATM
12、EL公司的AT89C52单片机作为中央处理器,如图4所示。该单片机除了拥有MCS-51系列单片机的所有优点外,内部还具有8K的在系统可编程FLASH存储器,低功耗的空闲和掉电模式,极大的降低了电路的功耗,还包含了定时器、程序存储器、数据存储器等硬件,其硬件能符合整个控制系统的要求,不需要外接其他存储器芯片和定时器件,方便地构成一个最小系统。整个系统结构紧凑,抗干扰能力强,性价比高。是比较合适的方案。图4AT89C52主控制系统3.2时钟振荡电路时钟振荡电路图5所示,时钟振荡电路用于产生单片机正常工作时所需要的时钟信号,电路由两个22pF的瓷片电容和一个12MHz的晶振组成,并接入到单片机的XT
13、AL1和XTAL2引脚处,使单片机工作于内部振荡模式。此电路在加电后延迟大约10ms振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率决定。电路中两个电容C1、C2的作用使电路快速起振,提高电路的运行速度,对于AT89C52其工作频率为0至33MHz,在这个范围内单片机能够正常的工作。图5AT89S52时钟振荡电路3.3复位电路复位电路由电阻和极性电容组成,如图6所示,通过高电平使单片机复位,在时钟电路开始工作后,当高电平的时间超过大约2us时,即可实现复位。此复位电路同时具备了上电复位和手动复位的功能,上电复位发生在开机加电时,由系统自动完成,手动
14、复位通过一个按键来实现,在程序运行时,若遇到死机,死循环或程序“跑飞”等情况,通过手动复位就可以实现重新启动的操作。手动按钮复位需要人为在复位输入端RST上加入高电平。一般采用的办法是在RST端和正电源Vcc之间接一个按钮和一个电阻,如图所示,当人为按下按钮时,则Vcc 的+5V电平就会直接加到RST端,由于人的动作再快也会使按钮保持接通达数十毫秒,所以,完全能够满足复位的时间要求。上电复位的工作过程是在加电时,复位电路通过电容加给RST端一个短暂的高电平信号,此高电平信号随着Vcc对电容的充电过程而逐渐回落,即RST端的高电平持续时间取决于电容的充电时间,由图可知充电时间为:T=2.3RC=
15、2.3*10*10-6*5.1*103=0.1173s ,保证系统能够可靠地复位。图6AT89C52复位电路3.4、DS1302时钟电路时钟电路主要由时钟芯片DS1302、备用电池、晶振等几部分组成,如图7所示。DS1302采用3线串行接口,占用引脚少,内部集成了可编程日历时钟,用户可以根据需要通过单片机的控制来自行设置,支持双电源供电,可以使用外部主电源和备用电源,备份电源能够使时钟芯片继续工作。图7DS1302时钟电路3.5、按键电路按键电路由四个轻触开关组成,如图8所示。按键用来调整时间和设定闹钟,其一端直接接到单片机的端口,另一端接地,当按下按键时,相应的端口变为低电平,通过检测这一低
16、电平就可以判断是哪个键按下,从而作相应的操作。图8按键电路3.6、显示电路显示电路采用LCD1602液晶显示,图中只画出了其相应的接口,如图9所示。3脚用于调节LCD1602的背光,4、5、6为LCD1602的控制口,用于控制其写入或是读出指令,7至14脚为LCD1602的数据口,将数传送到LCD1602中。图9LCD1602接口电路3.7、蜂鸣器电路蜂鸣器电路由一个220欧的电阻,三极管8550,及蜂鸣器组成,如图10所示。通过控制三极管的导通和截止来实现蜂鸣器的响与不响。图10蜂鸣器电路4软件设计与流程图4.1序流程图主程序首先初始化定时器、LCD1602及DS1302,然后就开始查询按键
17、,有键按下则开始调整时间和设置闹钟,若没有按下,则执行下面的时间、日期及闹钟时间的显示,最后依次循环这些相同的操作,相应流程图如图11所示: 开始初始化按键是否按下显示时间、日期时间、日期、闹钟设定显示温度结束是否图11程序主流程图4.2 部分序DS1302子程序:void DS1302InputByte(unsigned char d) /实时时钟写入一字节(内部函数) unsigned char i; ACC = d; for(i=8; i0; i-) DS1302_IO = ACC0; /相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC =
18、ACC 1; unsigned char DS1302OutputByte(void) /实时时钟读取一字节(内部函数) unsigned char i; for(i=8; i0; i-) ACC = ACC 1; /相当于汇编中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; return(ACC); void Write1302(unsigned char ucAddr, unsigned char ucDa)/ucAddr: DS1302地址, ucData: 要写的数据 DS1302_RST = 0; DS1302_CLK
19、= 0; DS1302_RST = 1; DS1302InputByte(ucAddr); / 地址,命令 DS1302InputByte(ucDa); / 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; unsigned char Read1302(unsigned char ucAddr)/读取DS1302某地址的数据 unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); / 地址,命令 ucData = DS1
20、302OutputByte(); / 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);void DS1302_GetTime(SYSTEMTIME *Time) /获取时钟芯片的时钟数据到自定义的结构型数组unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time-Second = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MINUTE);Time-Minute =
21、(ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_HOUR);Time-Hour = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_DAY);Time-Day = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_WEEK);Time-Week = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);
22、ReadValue = Read1302(DS1302_MONTH);Time-Month = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time-Year = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);DS18B20子程序void delay_18B20(unsigned int i)while(i-);/*ds18b20初始化函数*/void Init_DS18B20(void) unsigned char x=0; DQ = 1; /DQ复位
23、 delay_18B20(8); /稍做延时 DQ = 0; /单片机将DQ拉低 delay_18B20(80); /精确延时 大于 480us DQ = 1; /拉高总线 delay_18B20(14); x=DQ; /稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(20);/*ds18b20读一个字节*/ unsigned char ReadOneChar(void)uchar i=0;uchar dat = 0;for (i=8;i0;i-) DQ = 0; / 给脉冲信号 dat=1; DQ = 1; / 给脉冲信号 if(DQ) dat|=0x80;
24、delay_18B20(4); return(dat);/*ds18b20写一个字节*/ void WriteOneChar(uchar dat) unsigned char i=0; for (i=8; i0; i-) DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat=1; /*读取ds18b20当前温度*/void ReadTemp(void)unsigned char a=0;unsigned char b=0;unsigned char t=0;Init_DS18B20();WriteOneChar(0xCC); / 跳过读序号列号的
25、操作WriteOneChar(0x44); / 启动温度转换delay_18B20(100); / this message is wery importantInit_DS18B20();WriteOneChar(0xCC); /跳过读序号列号的操作WriteOneChar(0xBE); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度delay_18B20(100);a=ReadOneChar(); /读取温度值低位b=ReadOneChar(); /读取温度值高位temp_value=b4; void temp_to_str() /温度数据转换成液晶字符显示 TempBuffer0
26、=temp_value/10+0; /十位 TempBuffer1=temp_value%10+0; /个位 TempBuffer2=0xdf; /温度符号 TempBuffer3=C; TempBuffer4=0;void Delay1ms(unsigned int count)unsigned int i,j;for(i=0;icount;i+)for(j=0;j120;j+);5 电路仿真调试5.1总原理图基于AT89S52单片机的电子万年历硬件电路图如图13所示,系统由AT89S52单片机,按键扫描电路、显示电路、时钟电路、晶振电路、复位电路、电源指示电路及蜂鸣器输出电路。 图13 基
27、于AT89S52的电子万年历电路原理图5.2 整体电路仿真图以及仿真结果分析图15 电子万年历仿真图仿真结果分析仿真正确显示了时间,在LCD1602中正确显示了当前日期、时间并可以显示闹钟时间,通过按按键K2就可以开始设置时间,依次按K2次在年、月、日、时、分之间切换,并且相应的调整的位会闪烁,按K3用于加1操作,K4用于减1操作。按K3则可以设置闹钟时间,依次按K2以在时和分之间切换,按K3,可以增加值,按K4,可以减小值。闹钟开启设置:先按住K2然后再按K3可以开启闹钟功能,当设置好闹钟后并开启闹钟功能后,就可以有闹钟功能,按k1可以显示温度。要达到的要求,符合了我们设计的要求。5.3 调
28、试在软件调试过程中,当按下按键调节时间和日期后,时间不能继续在加,后来分析了程序才发现,是在设置好时间和日期时我们暂停了时钟,在设置完后没有启动时钟,所以时间和日期就不能够继续走,在那里停止了,发现这个原因后,我在设置完时间后就开启时钟,时间和日期就能够正确显示了。上电测试,LCD1602能够正确显示时间和日期,第一次K2钮,开始设置秒,再按K4秒减1,按K3秒加1,按二次K2设置分,按K4分减1 按K3分加1,按三次K2,设置时,按K4减1,按K3加1,按四次K2设置星期,按K4减1 ,按K3分加1,按五次K2.设置天,按K4减1 ,按K3加1,按六次K2,设置月,按K4减1 ,按K3分加1
29、,按七次K2,设置年,按K4减1 ,按K3分加1,在对电路测试后,电路达到了所需的功能。通过对电路的多次的反复测试与分析,可以对电路的原理及功能更加熟悉,同时提高了设计能力及对电路的分析能力,同时在软件的编程方面得到了更高的提高,对编程能力得到加强,同时对所学的知识得到了大的提高与巩固。附录#include #include /#include LCD1602.h/#include DS1302.h#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P17; /实时时钟时钟线引脚 sbit DS1302_I
30、O = P16; /实时时钟数据线引脚 sbit DS1302_RST = P15; /实时时钟复位线引脚sbit ACC0 = ACC0;sbit ACC7 = ACC7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year,set_menu,a,flag_1=1; /秒,分,时到日,月,年位闪的计数sbit Set =P14; /模式切换键sbit Up = P13; /加法按钮sbit Down = P12; /减法按钮sbit out = P11; /立刻跳出调整模式按钮sbit DQ = P1
31、0; /温度传送数据IO口sbit BEEP=P32; /蜂鸣器输出口sbit led=P20; sbit xs=P21;char done,count,temp,flag,up_flag,down_flag ,flag_led;uchar temp_value,j; /温度值uint b;uchar TempBuffer5,week_value2,Alarmtime9,alarm3,Alarm_time3;unsigned char code SONG = /祝你平安0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x2
32、6,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x100x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26
33、,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x1c,0x20,0x1c
34、,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,0x39
35、,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00 ; void Time_Init()TMOD = 0x11;IE = 0x8a;TH0 = 0xDC;TL0 = 0x00;TH1 = 0xDC;TL1 = 0x00;void Time0_Int() interrupt 1TH0 = 0xDC;TL0 = 0x00;a+;/长度加1void Time1_Int() interrupt 3TH1 = 0xD
36、C;TL1 = 0x00;b+;/长度加1if(b=255) TR1=0; b=0;flag_led=1; void Delay_xMs(uint x) uint i,j; for(i=0; ix; i+) for(j=0; j3; j+); void Play_Song(uchar i)uchar Temp1,Temp2;uint Addr;a = 0;/中断计数器清0Addr = i * 217;while(flag_1) if(out=0) flag_1=0; Temp1 = SONGAddr+; if (Temp1 = 0xFF) /休止符 TR0 = 0; Delay_xMs(100
37、); else if (Temp1 = 0x00) /歌曲结束符 return; else Temp2 = SONGAddr+; TR0 = 1; while(1) BEEP = BEEP; Delay_xMs(Temp1); if(Temp2 =a) a = 0; break; void show_time(); /液晶显示程序/*1602液晶显示部分子程序*/Port Definitions*sbit LcdRs= P25;sbit LcdRw= P26;sbit LcdEn = P27;sfr DBPort = 0x80;/P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口/内部等待函数*unsigned char LCD_Wait(void)LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_(); LcdEn=0;return DBPort;/向LCD写入命令或数据*#define LCD_COMMAND0 / Command#define LCD_D