1、2 电子日历设计与实现2.1 任务分析一、功能本设计要求具有显示生肖、年、月、日、星期、时、分、秒等功能;阳 历与阴历能够自动关联;具有温度计功能; 具备年、月、日、星期、时、分、秒校准功能;设计最终达到效果如图 2-1。2010 年 28 度 牛农历已丑05月 05四月十三星期二 10:27:05图 2-1 设计效果图二、系统原理按照系统设计功能的要求,系统由单片机、 时钟模块 DS1302、显示模块12864、键盘以及温度采集模 块 DS18B20 共 5 部分 电路组成, 电路构成框图如图2-2 所示。A T 8 9 S 5 1 单片机绘图型 1 2 8 6 4显示器实时时钟D S 1
2、3 0 2按键数字温度传感器 D S 1 8 B 2 0图 2-2 系统设计原理框图三、系统硬件要求本设计电路采用 AT89S51 单片机为控制核心,AT89S51 具有在线编程功能,低功耗,能在 3V 超低压工作。时钟电路由 DS1302 提供,它是一种高性能、低功耗、带 RAM 的实时时钟电 路,它可以 对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为 2.5V5.5V。 DS1302 内部有一个用于临时性存放数据的 31*8RAM 寄存器。器件在加 电情况下,可自动生成年、月、日、周、时、分、秒时间数据,该器件具有使用寿命长,精度高和低功耗等特点,同 时具有掉电自动保存
3、功能。温度的采集采用数字式温度传感器 DS18B20,此 类传感器为数字式传感器而且仅需要一条数据线进行数据传输,易于与单片机连接,可以去除 A/D 模块,降低硬件成本,简化系统电 路。另外,温度传感器 DS18B20 还具有测量精度高、1测量范围广等优点。显示部分用 12864LED 液晶显 示屏,液晶显示屏的显示功能强大,可显示大量文字、图形,显示多样,清晰可见,能够达到较好的显示效果。2.2 电路设计一、单片机主控制模块的设计AT89S51 单片机为 40 引脚双列直插芯片,有四个 I/O 口 P0,P1,P2,P3, MCS-51 单片机共有 4 个 8 位的 I/O 口(P0 、P1
4、、P2、P3),每一条 I/O 线都能独立地作输出或输入。单片机的最小系统如图 3-1 所示,18 引脚和 19 引脚接时钟电路,XTAL1 接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2 接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出。第 9 引脚为复位输入端,接上电容,电阻及开关后够上电复位 电路, 20 引脚为接地端,40引脚为电源端,单片机电路如 图 2-3 所示。P 1 . 0P 1 . 1P 1 . 2P 1 . 3P 1 . 4P 1 . 5P 1 . 62345678P 0 . 0 / A D 0P 0 . 1 / A D 1P 0 .
5、 2 / A D 2P 0 . 3 / A D 3P 0 . 4 / A D 4P 0 . 5 / A D 5P 0 . 6 / A D 6P 0 . 7 / A D 7P 2 . 7 / A 1 5P 2 . 6 / A 1 4P 2 . 5 / A 1 3P 2 . 4 / A 1 2P 2 . 3 / A 1 1P 2 . 2 / A 1 0P 2 . 1 / A 9P 2 . 0 / A 8R E S E TX T A L 2X T A L 1E AA L EP S E N3 93 83 73 63 53 43 33 23 13 02 92 82 72 62 52 42 32 22 1
6、P 3 . 0 / R X DP 3 . 1 / T X DP 3 . 2 / I N T 0P 3 . 3 / I N T 1P 3 . 4 / T 0P 3 . 5 / T 1P 3 . 6 / W RP 3 . 7 / R D1 01 11 21 31 41 51 61 7P 1 . 711 91 89C 1 3 0 PC 2 3 0 PC Y 1 2 M H zR 1 1 KC 3 1 0I C A T 8 9 S 5 1V C C图 2-3 单片机电路 二、时钟电路模块的设计DSl302 数据操作原理 : DSl302 在任何数据传送时必须先初始化,把 RST 脚置为高电平,然后把
7、8 位地址和命令字装入移位寄存器,数据在 SCLK 的上升沿被输入。无 论是读周期还是写周期,开始 8 位指定 40 个寄存器中哪个将被访问到。在开始 8 个时钟周期,把命令字节装入移位寄存器之后,另外的 时钟周期在读操作时输出数据,在写操作 时写入数据。DS1302 的引脚连接如图 2-4 所示。其中 VCC1 为后备电源,VCC2 为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302 由 VCC1 或 VCC2两者中的较大者供电。当 VCC2 大于 VCC10.2V 时,VCC2 给 DS1302 供电。2当 VCC2 小于 VCC1 时,DS1302 由 VCC1 供电。
8、 X1 和 X2 是振荡源,外接32.768kHz 晶振。RST 是复位/片选线,通 过把 RST 输入驱动置高电平来启动所有的数据传送,与 AT89C51 的 P3.0 相连。RST 输入有两种功能:首先,RST 接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST 提供终止单字节或多字节数据的传送手段。当 RST 为高电平时,所有的数据传送被初始化,允许对DS1302 进行操作。如果在传送过程中 RST 置为低 电平, 则会终止此次数据传送,I/O 引脚 变为高阻态。上 电运行时,在 VCC2.5V 之前, RST 必须保持低电平。只有在 SCLK 为低电平时 ,才能将 RST 置
9、为高电平。I/O 为串行数据输入输出端(双向),与 AT89C51 的 P3.1 相连。 SCLK 始终是输入端。V C C 1V C C 2R E TS C L KI / OX 1X 2P 3 . 0P 3 . 1P 3 . 2+ V C C3 2 7 6 8 H zD S 1 3 0 2图 2-4 DS1302 的引脚连接 图如果在传送过程中置 RST 脚为低电平, 则会终止本次数据传送,并且 I/O 引脚变为高阻态。上电运行时 ,在 Vcc2.5 V 之前 ,RST 脚必须保持低电平。只有在 SCLK 为低 电平时,才能将 RCT 置为高电平。 三、温度采集模块设计如图 2-5 所示。采
10、用数字式温度传感器 DS18B20,它是数字式温度传感器,具有测量精度高,电路连接 简单特点,此 类传感器仅 需要一条数据线进行数据传输,使用0.7 与 DS18B20 的 I/O 口连接加一个上拉电阻,Vcc 接电源,Vss 接地。+ V C CG N DV C CI / O123P 0 . 7D S 1 8 B 2 04 . 7 k图 2-5 DS18B20 温度采集四、显示模块的设计3液晶显示模块 12864 是一种图形点阵液晶显示器,它主要是由 12864 个液晶显示点组成的一个 128 列64 行的阵列,可以显示 84 个(1616 点阵)汉字。每个显示点对应一位二进制数,1 表示亮
11、, 0 表示灭 。存 储这些点阵信息的 RAM称为显示数据存储器。要显 示某个图形或汉字就是将相应的点阵信息写入到相应的存储单元中。图形或汉 字的点阵信息当然由自己设计,问题的关键就是显示点在液晶屏上的位置(行和列)与其在存储器中的地址之间的关系。LCD12864 的主要技术参数和性能见表 2.1。表 2.1 12864 主要技术参数和性能参数 性能电 源电源功耗电流显示内容接口总线工作温度储存温度VDD:+5V;模块内自带-10V 负压,用于 LCD 的驱动电压电源功耗电流(Idd)2.8mA128(列)64( 行)点与 CPU 接口采用 8 位数据总线并行输入输出和 8 条控制线;-20+
12、60-30+70,当温度低于15时,不能做动画显示。液晶显示模块 12864 的 DB0-DB7 是用来传输数据的,与 AT89S51 的 P0.0-P0.7相连。片选线 和 与 AT89C51 的 P1.1、P1.0 相连。GND 是接地线,VCC 与2cs1AT89C51 的电源连接起来。由于设计结果仿真实现,因此 12864 的对比度调节控制和背光照明电源等引脚为系统默认,在设计中可以不予处理。12864 的电路连接方式见图 2-6 所示。图 2-6LCD12864 连接图2.3 系统的软件设计4一、软件设计平台与设计过程目前单片机程序的设计大多采用Keil设计平台,图2-7是该软件的操
13、作界面,本设计程序采用Keilc51v802 版本,利用 C语言编写,由于电子日历的数据处理和函数较多,因此程序模块设计 。在 设计过程中,首先编写主程序以外的子程序模块,如12864显示器驱动、DS1302驱动等,然后 编写主函数。为了程序结构简单化,各个子程序都经过条件编译形成头文件被主程序包含。被主程序包含的文件含有汉字与字符库、线条图形 库等。图 2-7 Keil 软件的使用界面二、程序流程框图在编程部分,首先要初始化 DS1302 模块,即从 DS1302 中读出日期和时间,还要从温度传感器 DS18B20 中读取温度。分离日期、时间、温度后送到显示模块。最后由农历更新子程序来实现与
14、阳历自动关联。程序流程框图见图 2-7。5图 2-7 主程序流程图主程序包含主函数和 12864.h、model.h、ds1302.h、one-wire.h、 lunar.h、input_080627.h 头文件,并且含有系统的硬件的预处理指令。主函数的作用是获取时间数据、显示温度、显示时间信息、对时间调整函数调 整等,主函数的部分程序如下:#include #include “12864.h“#include “model.h“#include “ds1302.h“#include “one-wire.h“#include “lunar.h“#include “input_080627.h“
15、#define uchar unsigned char#define uint unsigned int#define NoUpLine 1#define UpLine 0#define NoUnderLine 1#define UnderLine 0#define FALSE 0#define TRUE 1void main(void)开始初始化读写日期、时间 和温度分离日期时间温度显示值显示子程序日期、时间修改子程序农历自动更新子程序闰月子程返回6SFR_Init();CAL_Init();GUI_Init();TR0 = 1;TR1 = 1;while(1) GetTime( /获得时间
16、LCD_ShowTemp(); /显示温度LCD_ShowWNL(); /显示万年历Time_Set(); /时间设置三、阳历程序的设计时钟芯片 DSl302 本身能 够产生时间信息,阳历程序只需从 DSl302 各寄存器中读出年、月、日、星期、小时、分、秒等数据,然后再处理即可。在首次对 DSl302 进行操作之前,必须对它进行初始化, 图 2-8 阳历程序流程图从 DS1302 中读出年,月,日,时,分,秒,周读出的数据为码,将其高低位分离初始化 DS1302DS1302 开始振荡开始7然后从 DSl302 中读出数据,再经过处理后,送给显示缓冲单元。图 2-8 所示为阳历程序流程图,程序
17、如下:#include /#include “ds1302.h“#define uchar unsigned char#define uint unsigned int#define SECOND 0x80 /秒#define MINUTE 0x82 /分鍾#define HOUR 0x84 /小時#define DAY 0x86 /天#define MONTH 0x88 /月#define WEEK 0x8a /星期#define YEAR 0x8c /年sbit DS1302_RST=P30;sbit DS1302_SCLK=P31;sbit DS1302_IO=P32;typedef s
18、truct systimeuchar cYear;uchar cMon;uchar cDay;uchar cHour;uchar cMin;uchar cSec;uchar cWeek;SYSTIME;void DS1302_Write(uchar D)uchar i;for(i=0;i1;8uchar DS1302_Read()uchar TempDat=0,i;for(i=0;i=1; if(DS1302_IO) TempDat=TempDat|0x80;DS1302_SCLK=1;DS1302_SCLK=0;return TempDat;void WDS1302(uchar ucAddr
19、, uchar ucDat)DS1302_RST = 0;DS1302_SCLK = 0;DS1302_RST = 1;DS1302_Write(ucAddr); / 地址,命令 DS1302_Write(ucDat); / 写 1Byte 数据DS1302_SCLK = 1;DS1302_RST = 0; uchar RDS1302(uchar ucAddr)uchar ucDat;DS1302_RST = 0;DS1302_SCLK = 0;DS1302_RST = 1;DS1302_Write(ucAddr); / 地址,命令 ucDat=DS1302_Read(); DS1302_SC
20、LK = 1;DS1302_RST = 0;return ucDat;void SetTime(SYSTIME sys)9WDS1302(YEAR,sys.cYear); WDS1302(MONTH,sys.cMonWDS1302(DAY,sys.cDayWDS1302(HOUR,sys.cHourWDS1302(MINUTE,sys.cMinWDS1302(SECOND,sys.cSecWDS1302(WEEK,sys.cWeekvoid GetTime(SYSTIME *sys)uchar uiTempDat;uiTempDat=RDS1302(YEAR|0x01); (*sys).cYe
21、ar=(uiTempDat4)*10+(uiTempDat/ uiTempDat=RDS1302(0x88|0x01);/ (*sys).cMon=(uiTempDatuiTempDat=RDS1302(0x88|0x01);(*sys).cMon=(uiTempDatuiTempDat=RDS1302(DAY|0x01);(*sys).cDay=(uiTempDatuiTempDat=RDS1302(HOUR|0x01);(*sys).cHour=(uiTempDatuiTempDat=RDS1302(MINUTE|0x01);sys-cMin=(uiTempDatuiTempDat=RDS
22、1302(SECOND|0x01);sys-cSec=(uiTempDatuiTempDat=RDS1302(MONTH|0x01);(*sys).cMon=uiTempDatuiTempDat=RDS1302(WEEK|0x01);sys-cWeek=uiTempDat四、阴历程序设计由于 DS1302 没有阳历计时功能,因此阴 历的计时 与实现是要通过阳历日期来推导。根据阳历来推算阴 历日期,推算方法是,根据阳 历当前日期在一年中的天数来计算阴历日期。阳历 一个月不是 30 天就是 3l 天(2 月除外,闰年 2 月为 29天,平年 2 月为 28 天) 。阴 历一年有 12 个月或 13
23、 个月 (含闰月),一个月为 30 天10或 29 天。如果把一个只有 29 天的月称为小月,用 1 为标志,把 30 天的月称为大月,用 0 为标志,那么 12 位二进制就能表示一年 12 个月的大小。如果有 闰月,则把闰月的月份作为一个字节的高 4 位,低 4 位表示闰月大小,大月低四位为0,小月为 1。这样一个字节就包含了所有闰月的信息。阴历春节和阳历元旦相差的天数也用一个字节表示。总共用 1 字节就可以存储一年中任何一天阳历和阴历的对应关系的有关数据。按此方法,先要根据当前阳历的日期,算出阳 历为该年中的第几天。 计算出当前阳历日期为该年中的第几天后,再减去阳历该年春节和元旦的日差,如
24、果够减。则相减的结果就是阴历 在该年的总第几天了。根据该数据就可以推算出具体的当前阴历日期;如果不够减,则表示当的阴历年为阳历年的前一年。这种情况下,当前阴历日期会处于阴 历 11 月或 12 月,此 时春 节和元旦的日差减去前面计算出的当前阳历日期在阳历年为第几天的数据。其结果表示当的阴历日期离春节的天数。计算出的阳历天数 为该年的第几天,存放在寄存器 R2 和 R3 中。计算出天数后,如果大于FFH, 则把#FFH 存放在 R2 中,余值存放在 R3 中。也就是说在用寄存器 R2 和 R3 表示的天数信息中。R2 充当主寄存器,数据先存满 R2,再存 R3。整个转换程序中,这里面的数据不能
25、被覆盖。11R2 减 1 个月天数够减 ?下个月为闰月?减去闰月天数月加 1R3=0?R2=R2+R3R3=0R2=0?月份为当前正在减的月份的前一个月的最后一天月份为当前正在减的月份,号数为 R2的值YNYYNNY N程序入口图 2-9 推算阴历日期的程序流程图计算出阳历总天数后,就可以根据它来推算阴历日期。推算方法是,先用 总天数减去春节和元旦的日差,如果结果为 1,则该天正好是春节(因为春节在元旦之后,在计算春节和几旦的日差 0 时,假 设元旦为 0 天,春 节为 M 天,则日差为M。而前面 计算的阳历总天数是该天在该年中的第几天,是以元旦为 1 而得到的,与计算春节和元旦日差的这种方法
26、相比,其数值少了 1。所以要在原来本应该以0 作为该天就是春节的依据的基础上加 1,所以以 1 作为该天是春节的标志)。如果结果小于, 则阴历应该是阳历的前一年;如果结果大于 1,说明阳历和阴历为同一年。图 2-9 为由总天数推算出阴历日期的程序流程图。五、时间调整程序设计调整时间用 3 个调整按钮,1 个作为控制用,另外 2 个作为加和减用,分 别定义为设置按钮、加按钮和减按钮。在 调整时间过程中,要调整的位与别的位应该有区别,所以增加了闪烁 功能。 时间调整程序程序流程图如图 2-10 所示。程序见附录。12图 2-10 时间调整程序程序流程图2.4 系统仿真本设计仿真采用Proteus电
27、路仿真平台,该软件由Labcenter公司开发,是目前开始设 置键有效,进入时调整程序等待按键程序加键有效 减键有效小时加 1 小时减 1控制键有效,进入秒调整程序等待按键程序加键有效 减键有效秒加 1 秒减 1控制键有效,进入月调整程序等待按键程序加键有效 减键有效月加 1 月减 1控制键有效,进入分调整程序等待按键程序加键有效 减键有效分钟加 1 分钟减 1控制键有效,进入日调整程序 员等待按键程序加键有效 减键有效日加 1 日减 1控制键有效,进入年调整程序等待按键程序加键有效 减键有效年加 1 年减 1按键有效,跳出时间调整程序,进入主循环程序13世界上最先进、最完整的嵌入式系统设计与
28、仿真平台,可以实现数字电路、模 拟电路及微控制器系统与外设的混合电路系统的电路仿真、软件仿真、系统协同仿真和PCB设计等功能,是目前唯一能够对各种处理器进行实时仿真、调试与测试的EDA 工具。图2-11 电路仿真图Proteus7.4版本的电路仿真界面下搭建本设计电路,为了精简电路设计,电路器件之间的连接采用网路标号,电路见图2-11所示。然后加载程序的HEX 文件,然后点击仿真运行按钮进入电路仿真状态。仿真效果见图2-12所示,系统通过在Proteus软件仿真,模拟出了 实际电路的运行效果, 验证 了程序的正确性,达到了本设计的目的。图 2-12 电路仿真效果14总 结本系统电路较为简单,但
29、软件工作量较大。在系 统软件设计过程中,利用 C语言编程,模块化程序设计 ,由于程序率 为复杂,数据 处理指令较多,逻辑性强,对与软件设计工作提出了较高要求。参考文献1 刘勇. 数字 电路M. 电子工业出版社, 2006.156-169.2 陈正振. 电子电路设计与制作J. 广西交通职业技术学院信息工程系, 2007.3 杨子文. 单片机原理及应用M. 西安电子科技大学出版社, 2006.4 张毅刚. MCS-51 单片机原理及应用M. 北京:教育出版社, 2007.227-237.5 周润景,张丽 娜. 基于 PROTEUS 的电路及单片机系统设计与仿真M. 北京:北京航空航天大学出版社,
30、2006.96-125.6 杨将新,李 华军,刘东骏.单片机程序设计及应用从基础到实践M. 电子工业出版社, 2006. 4(3):93 一 95.7 林志琦,郎建军. 基于 PROTEUS 的单片机可视 化软硬件仿真M. 北京:北京航空航天大学出版社, 2006.9(5):45-51.8 白驹珩,雷晓平. 单片计算机及运用M. 电子科技大学出版社,2008.9 ATMEL.How to Calculate The Capacitor of The Reset Input of a C51 Microcontroller.2003(9).10 ATMEL.8-bit Microcontroll
31、er with 4K Bytes In-System Programmable Flash AT89S51.2002(12).15附 录程序清单#include #include “12864.h“#include “model.h“#include “ds1302.h“#include “one-wire.h“#include “lunar.h“#include “input_080627.h“#define uchar unsigned char#define uint unsigned int#define NoUpLine #define UpLine #define NoUnderL
32、ine 1#define UnderLine#define FALSE#define TRUE uchar bdata gTmp;sbit t0 = gTmp0;sbit t1 = gTmp1;sbit t2 = gTmp2;sbit t3 = gTmp3;sbit t4 = gTmp4;sbit t5 = gTmp5;sbit t6 = gTmp6;sbit t7 = gTmp7;uchar dispBuf7;uchar T0_Count=0,Tmp_Count=0;bit T0_Flag,Tmp_Flag,Flash_Flag;SYSTIME sys; /系统日期SPDATE SpDat;
33、 /农历日期/设置时间的标志bit Hour_Flag=TRUE,Min_Flag=TRUE,Sec_Flag=TRUE;bit Year_Flag=TRUE,Mon_Flag=TRUE,Day_Flag=TRUE;uchar State_Set=0; /设置状 态 (用来区分此时是在设置时,分 ,秒,日,月,年) bit State_Flag=FALSE,Inc_Flag=FALSE,Dec_Flag=FALSE;/用来标志三个按键是否按下。uchar code Mon2213=0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30
34、,31,31,30,31,30,31;/*cDat: 要显示的数X: 行数 07Y: 列数 0127show_flag: 是否反白显示,0 反白,1 不反白 16upline: 上划线, 0 表示带上划 线underline: 下划线, 0 表示带下划线返回: 无*/void LCD_ShowTime(char cDat,uchar X,uchar Y,bit show_flag,bit up,bit under)uchar s2;s0=cDat/10+0;s1=cDat%10+0;en_disp(X,Y,2,Asc,s,show_flag,up,under);/*/ 函数名: Show_YM
35、D()/ 入口参数: void / 出口参数: void / 功能: 显示公历与农历的年、月、日、星期/ 说明: 普通模式每天刷新一次/ 设置模式每次循环刷新一次*/void Show_YMD() /显示年月日星期uchar uiTempDat;uiTempDat=RDS1302(0x88|0x01);sys.cMon=(uiTempDatLCD_ShowTime(sys.cMon,2,5,Mon_Flag,NoUpLine,NoUnderLine); /月hz_disp(4,5,1,uMod1,1,NoUpLine,NoUnderLine);Show16X32(2,27,ucNum3216s
36、ys.cDay/10,Day_Flag);Show16X32(2,43,ucNum3216sys.cDay%10,Day_Flag); /年hz_disp(6,8,2,ucLunar13,1,UpLine,UnderLine);if(sys.cWeek=7)hz_disp(6,40,1,uMod2,1,UpLine,UnderLine); /星期日elsehz_disp(6,40,1,ucLunarsys.cWeek,1,UpLine,UnderLine); /星期LCD_ShowTime(20,0,9,1,UpLine,UnderLine);LCD_ShowTime(sys.cYear,0,
37、25,Year_Flag,UpLine,UnderLine);hz_disp(0,41,1,uMod0,1,UpLine,UnderLine); /年SpDat=GetSpringDay(sys.cYear,sys.cMon,sys.cDay); /得到 农历日期/显示农历日期if(SpDat.cMon=1) /农历月hz_disp(4,64,1,ucLunar15,1,UpLine,NoUnderLine); /“正“else if(SpDat.cMon=11)hz_disp(4,64,1,ucLunar16,1,UpLine,NoUnderLine); /“冬“else if(SpDat.
38、cMon=12)hz_disp(4,64,1,ucLunar17,1,UpLine,NoUnderLine); /“腊“17elsehz_disp(4,63,1,ucLunarSpDat.cMon,1,UpLine,NoUnderLine); /“二“十“if(SpDat.cDay/10=1 else if(SpDat.cDay/10=2 elsehz_disp(4,95,1,ucLunarSpDat.cDay/10,1,UpLine,NoUnderLine); /正常显示数字if(!(SpDat.cDay%10) / /“十“hz_disp(4,111,1,ucLunar10,1,UpLin
39、e,NoUnderLine);else/正常数字hz_disp(4,111,1,ucLunarSpDat.cDay%10,1,UpLine,NoUnderLine);/显示生肖hz_disp(0,104,1,SX(uint)(2000+SpDat.cYear)%12,1,UpLine,UnderLine); /生肖/显示天干地支hz_disp(2,95,1,TianGan(uint)(2000+SpDat.cYear)%10,1,NoUpLine,NoUnderLine); /天干hz_disp(2,111,1,DiZhi(uint)(2000+SpDat.cYear)%12,1,NoUpLi
40、ne,NoUnderLine); /地支/*/ 函数名: LCD_ShowTemp()/ 入口参数: void/ 出口参数: void/ 功能: 采集温度并显示/ 说明: 30 秒更新一次*/void LCD_ShowTemp()uchar datTm2;float temp;uchar buftmp;if(!Tmp_Flag) return;Tmp_Flag=FALSE;DS18B20_Init();DS18B20_RomCmd(0xcc); /Skip Rom command;Delay_Xms(20);DS18B20_MemCmd(0x44); /Convert T command;DS
41、18B20_Init();DS18B20_RomCmd(0xcc);DS18B20_MemCmd(0xbe);DS18B20_ReadDat(2,datTm);gTmp = datTm0;temp = (uchar)t0 * 0.0625 + (uchar)t1 * 0.125 + (uchar)(t2) * 0.25 + (uchar)(t3) * 0.5;18buftmp = (uchar)(temp*10);dispBuf2 = .;dispBuf3 = buftmp + 0;buftmp = (uchar)t4 + (uchar)t5*2 + (uchar)t6*4 + (uchar)
42、t7*8;gTmp = datTm1;gTmp buftmp += (gTmp * 16);dispBuf0 = (buftmp/10) + 0;dispBuf1 = (buftmp%10) + 0;dispBuf4 = 0xdf; /摄氏度;dispBuf2 = C;en_disp(0,65,2,Asc,dispBuf,1,UpLine,UnderLine);/*/ 函数名: LCD_ShowWNL()/ 入口参数: void/ 出口参数: void/ 功能: 显示万年历/ 说明:*/void LCD_ShowWNL()LCD_ShowTime(sys.cSec,6,111,Sec_Flag
43、,UpLine,UnderLine); /秒 每次循环钟刷新一次if(!sys.cSec | State_Set) /分 在普通模式时每分钟刷新一次LCD_ShowTime(sys.cMin,6,87,Min_Flag,UpLine,UnderLine); / 在设置模式时每次循环刷新一次if(!sys.cSec / 在设置模式时每次循环刷新一次if(!sys.cSec /设置模式每次循环刷新一次if(State_Set=7) State_Set=0;/*/ 函数名: CAL_Init()/ 入口参数: void/ 出口参数: void19/ 功能: 日期初始化/ 说明: 星期通过计算得到*/
44、void CAL_Init()sys.cYear=0x09;sys.cMon=0x05;sys.cDay=0x05;sys.cHour=0x10;sys.cMin=0x27;sys.cSec=0x00;sys.cWeek=GetWeekDay(sys.cYear,sys.cMon,sys.cDay);/*/ 函数名: SFR_Init()/ 入口参数: void/ 出口参数: void/ 功能: 寄存器初始化/ 说明: 定时器 0 控制温度采集,定时器 1 控制按键扫描*/void SFR_Init()T0_Flag=FALSE;Tmp_Flag=TRUE;Flash_Flag=FALSE;T
45、MOD=0x11;ET0=1;ET1=1;TH0= (-50000)/256;TL0= (-50000)%256;TH1= (-10000)/256;TL1= (-10000)%256;EA=1;/*/ 函数名: GUI_Init()/ 入口参数: void/ 出口参数: void/ 功能: 图形界面初始化/ 说明: 一些永远不耍更新的图形(如线条,“年“ 、“月“ 、“日“等)只是在初始化时写入,中间过程不再更新。*/20void GUI_Init()uint i,j;/进 入界面/LCD12864_init();ClearLCD();LCD_ShowTemp(); /在显示图片之前启动温度 转换img12864_disp(uBmp); /显示图片for(i=0;i10;i+)for(j=0;j32767;j+);ClearLCD();/描 绘框架 /Rect(0,0,127,63,1);Line(62,0,62,62,1);Line(0,48,127,48,1);Line(0,15,127,15,1);Line(24,15,24,48,1);Line(63,32,128,32,1);Line(97,0,97,15,1);/Line(24,