1、1目 录一、温度万年历设计的目的和意义.1二、电路设计方案 .1三、原理设计 .1四、方案结构图 .3五、温度万年历 1602 驱 动 及 显 示 的详细设计 6六、心得与总结 14- 0 -一、温度万年历设计的目的和意义随着社会的发展,信息量的不断提升以前对信息交换的要求提高,温度万年历的发展以及投入市场变得非常有必要。本设计是基于 51 单片机并模拟日常所用的日历,而 51 系列单片机是各单片机中最为典型和最有代表性的一种。通过本次设计,学习和巩固了单片机指令编程的相关知识,熟悉单片机各部件的组成及其功能。 本设计将制作一种基于单片机控制的带实时温度显示、具有定时功能的电子万年历。传统的电
2、子日历大都体积大,功耗大,显示不准确等特点。为了缩小体积,减小功耗,使其变得小巧灵敏,本设计加入了时钟芯片 DS1302,可对时间进行准确记时,同时可设置定时时间,实现定时功能。另外本设计具有显示实时温度的功能。传统的温度传感器系统大都采用放大、调理、A/D 转换,转换后的数字信号送入计算机处理,处理电路复杂、可靠性相对较差,占用计算机的资源比较多。本设计将采用 DS18B20 一线制数字温度传感器,可将温度信号直接转换成数字信号送给微处理器,电路简单,成本低,实现了时间温度同时显示的效果。最后,温度和时间都将通过 LCD1602 液晶显示器进行显示。测试表明系统达到了设计要求的各项功能,各部
3、分工作正常。二、电路设计方案采用 AT89S52 作为主控制系统; 直接采用单片机定时计数器提供秒信号;LCD 液晶显示屏作为显示。三、原理设计1. 基本原理:本电路是由 AT89S52 单片机为控制核心,具有在线编程功能,低功耗,能在 3V 超低压工作;时钟电路直接采用单片机定时计数器提供秒信号;温度的采集由 DS18B20 构成;显示部份由 LCD 液晶显示屏显示。同时还添加了提醒功能,通过蜂鸣器实现。2. 总体框图- 1 -图 13. 单元电路设计 单片机主控制模块的设计AT89S52 单片机为 40 引脚双列直插芯片,有四个 I/O 口 P0,P1,P2,P3, MCS-51 单片机共
4、有 4 个 8 位的 I/O 口(P0、P1、P2、P3) ,每一条 I/O 线都能独立地作输出或输入。单片机的最小系统如下图 2 所示,18 引脚和 19 引脚接时钟电路,XTAL1 接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2 接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出。第 9 引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20 引脚为接地端,40 引脚为电源端。DS18B20 性能 独特的单线接口仅需一个端口引脚进行通信 简单的多点分布应用 无需外部器件 可通过数据线供电 零待机功耗 测温范围-55+125,以 0.5递增 可编程
5、的分辨率为 912 位,对应的可分辨温度分别为 0.5、0.25、0.125和 0.0625 温度数字量转换时间 200ms,12 位分辨率时最多在 750ms 内把温度转换为数字 应用包括温度控制、工业系统、消费品、温度计和任何热感测系统 负压特性:电源极性接反时,传感器不会因发热而烧毁,但不能正常工作 GND:地 DQ:单线运用的数据输入/输出引脚STC89C52主控制模块Lcd1602 液晶屏显示模块晶振振荡模块键盘模块- 2 - VD:可选的电源引脚4. 元件列表四、 方案结构图此方案由于只用到 51 单片机芯片,因此各个功能都是由编程来实现。大体程序流程框图如下元件列表器件 数量光汇
6、 51 单片机开发板 1杜邦线 若干DS18B20 1LCD1602 液晶屏 1- 3 -按键调整结构图:时钟调整一时钟调整二- 4 -Protues 电路图(部分):温度万年历整体电路图时钟调整按键图时钟调整 LCM 显示图- 5 -五、温度万年历 1602 驱 动 及 显 示 的详细设计驱动部分的代码:头文件如下:#ifndef _1602_H_#define _1602_H_void RdBusy(void);void WrCommand(char command);void WrData(char wrdata);#endif1602 驱动源代码如下:/*LCM1602 驱动程序8 线
7、间接控制方式晶体频率 12MHz*/*1602LCD 各引脚接口说明VSS 电源地VDD 电源正极VL 液晶显示偏压RS 数据/命令选择R/W RW 读写选择/*LCM1602 驱动程序8 线间接控制方式- 6 -晶体频率 12MHz*/#include #include /*1602LCD 各引脚接口说明VSS 电源地VDD 电源正极VL 液晶显示偏压RS 数据/命令选择R/W RW 读写选择E 使能信号D0 数据 背光源正极D1 数据 背光源负极*/*1602 接口定义*/#define LCM P0 sbit RS = P25; /0,command; 1,datajkhjholkhkk
8、sbit RW = P26; /0,write; 1,readsbit E = P27; /下降沿有效/*常数定义*/#define CMD 0 /RS=0,命令#define DAT 1 /RS=1,数据- 7 -/模块忙闲判断void RdBusy(void)char flag=0xff; doLCM=0xff;RS=CMD;RW=1;E=1;_nop_();_nop_();_nop_(); /这三句很重要flag=LCM;E=0;flagwhile(flag);/写命令void WrCommand(char command)LCM=command;RS=CMD;RW=0;E=1;E=0;
9、RW=1;RdBusy(); /等待 LCM 完成本次操作- 8 -/写数据void WrData(char wrdata)LCM=wrdata;RS=DAT;RW=0;E=1;E=0;RW=1;RdBusy(); /等待 LCM 完成本次操作/*E 使能信号D0 数据 背光源正极D1 数据 背光源负极*/显示头文件:#ifndef _DISPLAY_H_#define _DISPLAY_H_#define uchar unsigned charvoid delayx5ms(int dcnt);void LcmInit(void);void ClrLine(uchar line );void
10、Write1Line(uchar line,uchar* buf);void WrData2Addr(uchar addr,uchar dat);- 9 -void disall();void offall();#endif显示 C 源代码:#include #include “1602.h“#define LCM P0#define uchar unsigned charextern uchar flag;extern uchar year,month,date,day,hour,minu,sec;extern uchar Dispbuf016;extern uchar Dispbuf116
11、;extern code uchar Num2Asc16;extern code uchar WEEK21;extern uchar s1num;/延迟子程序,基数 5msvoid delayx5ms(int dcnt) int tmp;for(; dcnt0; dcnt-)tmp=0x230;while(tmp-)continue;/模块初始化void LcmInit(void)- 10 -LCM=0;delayx5ms(40); /延迟 200msWrCommand(0x38); /8bit 接口,两行显示,57 点阵delayx5ms(2); /延迟 10msWrCommand(0x38
12、); /同上,该指令要写两次delayx5ms(1); /延迟 5msWrCommand(0x06); /地址加一,字符不移动WrCommand(0x0c); /开显示,光标不显示,光标不闪烁WrCommand(0x01); /清屏/指定行清屏子程序void ClrLine(uchar line )unsigned char i=0;WrCommand(0x80+line); /指向擦除行的首字符位for(;i16;i+)WrData( );void Write1Line(uchar line,uchar* buf)uchar addr=0,i;if(line=0)addr=0x80;else
13、addr=0xc0;WrCommand(addr);for(i=0;i16;i+)- 11 -WrData(*buf+);void WrData2Addr(uchar addr,uchar dat)WrCommand(addr);WrData(dat);void disall()Dispbuf03=Num2Ascyear/10;Dispbuf04=Num2Ascyear%10;Dispbuf06=Num2Ascmonth/10;Dispbuf07=Num2Ascmonth%10;Dispbuf09=Num2Ascdate/10;Dispbuf010=Num2Ascdate%10;Dispbuf
14、012=WEEKday*3;Dispbuf013=WEEKday*3+1;Dispbuf014=WEEKday*3+2;Dispbuf11=Num2Aschour/10;Dispbuf12=Num2Aschour%10;Dispbuf14=Num2Ascminu/10;Dispbuf15=Num2Ascminu%10;Dispbuf17=Num2Ascsec/10;- 12 -Dispbuf18=Num2Ascsec%10;Write1Line(0,Write1Line(1,void offall()switch(s1num)case 1:Dispbuf17= ;Dispbuf18= ;bre
15、ak;case 2:Dispbuf14= ;Dispbuf15= ;break;case 3:Dispbuf11= ;Dispbuf12= ;break;case 4:Dispbuf012= ;Dispbuf013= ;Dispbuf014= ;break;case 5:Dispbuf09= ;Dispbuf010= ;- 13 -break;case 6:Dispbuf06= ;Dispbuf07= ;break;case 7:Dispbuf03= ;Dispbuf04= ;break;default : *Dispbuf0 = “ “;*Dispbuf1 = “ “;Write1Line(
16、0,Write1Line(1,六、心得与总结经过万年历的设计,让我学到了很多,让我认识到了学习基础知识的重要性,当设计完整的系统时,要考虑到硬件和软件两者的结合,有时硬件的不足,我们可以用软件程序来弥补,从而节约硬件成本,在设计软件程序时要模块化,可以提高程序的可读性。有一些灵活的技巧就需要我们认真的阅读元件的数据手册,从中索取对自己有用的信息。在这短暂的一个星期课程序设计中,收获知识的同时,还收获了阅历,收获了成熟,通过查找大量资料,请教老师,以及不懈的努力,不仅培养了独立思考、 动手制作的能力,在各种其它能力上也都有了提高。更重要的是,在课程序设计里,我们学会了很多学习的方法,知道了理论和实践的巨大差别。而这是以后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。同时在与老师和同学的交流过程中,互动学习,将知- 14 -识融会贯通。通过自己的努力,做出了一个万年历,对以后的学习是一个莫大的鼓舞,激起了我的学习兴趣和开发创新思维。