收藏 分享(赏)

基于LCD1602和DS1302的时间显示程序.doc

上传人:精品资料 文档编号:8665901 上传时间:2019-07-07 格式:DOC 页数:26 大小:27.17KB
下载 相关 举报
基于LCD1602和DS1302的时间显示程序.doc_第1页
第1页 / 共26页
基于LCD1602和DS1302的时间显示程序.doc_第2页
第2页 / 共26页
基于LCD1602和DS1302的时间显示程序.doc_第3页
第3页 / 共26页
基于LCD1602和DS1302的时间显示程序.doc_第4页
第4页 / 共26页
基于LCD1602和DS1302的时间显示程序.doc_第5页
第5页 / 共26页
点击查看更多>>
资源描述

1、/*=使用 1602 液晶显示 DS1302+S51 时钟+温度显示 zhaojun 2007/06/29= 声明:1. 1602 驱动程序照搬 明皓 的,非常好用2. DS1302 驱动程序是参考网友修改而来NS1602R(16*2)模拟口线接线方式连接线图: -| LCM-51 | LCM-51 | LCM-51 | - | DB0-P0.0 | DB4-P0.4 | RS-P2.0 | DB1-P0.1 | DB5-P0.5 | RW-P2.1 | DB2-P0.2 | DB6-P0.6 | E-P2.2 | DB3-P0.3 | DB7-P0.7 | VLCD 接 1K 电阻到 GND

2、 |-DS1302 接线图Vcc2 CLK I/O /RST | | | |-| 8 7 6 5 | DS1302 | | 1 2 3 4 |-| | | |VCC1 GND1. 脚接+5V 2,3. 脚 32768HZ 晶振 4. 脚接地 5. 脚接 S51 的 P1.2 6. 脚接S51 的 P1.1 7. 接 S51 的 P1.08. 脚接后备电源,可以接老计算机主板上的 3.6V 电池,也可以通过二级管隔离接一个大容量电解电容电压在 2.5V 以上即可维持按键说明:1. 共三个键,低电平有效2. P1.4 和 P1.5 同时按:初始化3. P1.6 端口按键:选择要调整的项目4. P1

3、.5 端口按键:增加;P1.4 端口按键:减少注:AT89S51 使用 12M 晶振源代码:=定义与申明=*/#include “regx51.h“#include “string.h“#include “intrins.h“#define uchar unsigned char#define uint unsigned inttypedef unsigned char byte;typedef unsigned int word;/* 1602 引脚定义引脚#define LCM_RS P2_0 / 数据/命令选择信号 #define LCM_RW P2_1 / 读/写选择信号#define

4、 LCM_E P2_2 / 使能信号/* DS1302 时间显示定义部分sbit T_CLK=P10; /串行时钟输入sbit T_IO =P11; /串行数据端口sbit T_RST=P12; /复位端口/* 18B20 温度显示定义部分 sbit DQ=P33; /18B20 接 P33 口sbit ACC0=ACC0;sbit ACC7=ACC7;#define LCM_Data P0 /显示数据端口#define Busy 0x80 /用于检测 LCM 状态字中的 Busy 标识uchar id,timecount; /全局变量bit flag,sflag; /flag 是时钟冒号闪烁

5、标志, sflag 是温度负号显示标志bit sec,min,hour,year,mon,day,weekk; /闪烁标志位/*函数申明void Disp_line1(void); / 显示屏幕第一行 void Disp_line2(void); / 显示屏幕第二行void id_case1_key(); / id 为 1 时的下一级选择void Set(uchar,uchar); / 根据选择调整相应项目void RTInputByte(uchar); /* 输入 1Byte */uchar RTOutputByte(void); /* 输出 1Byte */void W1302(uchar

6、, uchar); / 向 DS1302 写入一个字节uchar R1302(uchar); / 从 DS1302 读出一个字节void Set1302(uchar * ); / 设置时间/* 1602LCD 驱动 *void WriteDataLCM(uchar WDLCM); /写数据void WriteCommandLCM(uchar WCLCM,BuysC); /写指令uchar ReadStatusLCM(void); /读状态void LCMInit(void); /LCM 初始化void DisplayOneChar(uchar X, uchar Y, uchar DData);

7、 /按指定位置显示一个字符void DisplayListChar(uchar X, uchar Y, uchar code *DData); /按指定位置显示一串字符void Delay5Ms(void); /5ms 延时void Delay400Ms(void); /400ms 延时Read_Temperature(char,char);/温度显示void mychar(void); /显示自定义字符void adjust_res(char res); /res 分别等于 0x1f, 0x3f, 0x5f 温度读数分辨率分别对应/ 0.5, 0.25, 0.125 /初始化后设置为:07

8、年 07 月 04 日 星期 3 12 点 00 分 00 秒/ 12:00:00 XX. C/ 07/07/04 Week.3unsigned char inittime7=0x00,0x00,0x12,0x04,0x07,0x03,0x07;/ 秒 分钟 小时 日 月 星期 年uchar code week=“Week.“;/星期显示/= 主函数 =/* 函 数 名:main()功 能:主函数说 明:入口参数:无返 回 值:无 */void main(void) Delay400Ms(); /启动等待,等 LCM 讲入工作状态LCMInit(); /LCM 初始化Delay5Ms(); /

9、延时片刻(可不要 )mychar(); /显示自定义字符TMOD=0x01; /选择定时模式TH0=(65535-50000)/256;/取定时初值TL0=(65535-50000)%256;EA=1; /开中断TR0=1;ET0=1; W1302(0x90,0xa5); /打开充电二级管 一个二级管串联一个 2K 电阻 W1302(0x8e,0x80); /写保护,禁止写操作 adjust_res(0x5f); /调整 18B20 的分辨率 0x1f:0.5; 0x3f:0.25; 0x5f:0.125while(1) if (P1_4|P1_5)=0) / 初始化 同时按下 P1_4、P1

10、_5Delay5Ms(); / 适当延时 ,消除抖动if (P1_4|P1_5)=0) Set1302(inittime); / 显示初始值if (P1_6=0) / 设置和选择项目键Delay5Ms(); / 适当延时 ,消除抖动if(P1_6=0)id+;if(id7) id=0; / 7 个可调节项目循环调节while(P1_6=0); switch(id) / 跳转到对应的项目进行设置case 0:sec=0;Disp_line1(); Disp_line2();break;case 1: /调节年year=1;/设置年闪烁标志位Disp_line1(); Disp_line2();

11、id_case1_key();break;case 2: /调节月year=0;mon=1;/设置月闪烁标志位Disp_line1(); Disp_line2(); id_case1_key();break;case 3: /调节日mon=0;day=1;/设置日闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break; case 4: /调节星期day=0;weekk=1;/设置星期闪烁标志位Disp_line1(); Disp_line2(); id_case1_key();break;case 5: /调节小时weekk=0;hour=1;

12、/设置小时闪烁标志位Disp_line1(); Disp_line2(); id_case1_key(); break; case 6: /调节分钟hour=0;min=1;/设置分钟闪烁标志位Disp_line1(); Disp_line2(); id_case1_key();break;case 7: /调节秒min=0;sec=1;/设置秒钟闪烁标志位Disp_line1(); Disp_line2(); id_case1_key();break; /= 定时中断 =/* 函 数 名:void t0()功 能:时间工作时,冒号闪烁说 明:T0 中断入口,方式 1入口参数:无返 回 值:无

13、 */void t0(void) interrupt 1 using 0TH0=(65535-50000)/256; /取 50ms 定时初值TL0=(65535-50000)%256; timecount+;if(timecount9)timecount=0; /计时到,从先开始flag=flag; /标志位取反 /= 项目设置 =/* 函 数 名:void id_case1_key()功 能:项目设置加减控制说 明:P1.5 和 P1.4 +和-入口参数:无 返 回 值:无 */id 为 1 时的下一级选择void id_case1_key()if (P1_5=0) /P1_5 有按下,则

14、数值增加(+)Delay5Ms(); /适当延时,消除抖动if(P1_5=0) Set(id,0); /根据选择调整相应项目if(id!=7) while(P1_5=0); if (P1_4=0) /P1_4 有按下,则数值减少(-)Delay5Ms(); /适当延时,消除抖动if(P1_4=0) Set(id,1); /根据选择调整相应项目 if(id!=7) while(P1_4=0); /* 函 数 名:void Set()功 能:项目设置说 明:sel_1=0 时,数值加;sel_1=1 时,数值减入口参数:sel 和 sel_1返 回 值:无 */根据选择调整相应项目并写入 DS13

15、02void Set(uchar sel,uchar sel_1) signed char address,item;signed char max,mini;/偶数指令是写,奇数指令是读/最大值与最小值限定if(sel=7) address=0x80; max=00;mini=0; /秒if(sel=6) address=0x82; max=59;mini=0; /分钟if(sel=5) address=0x84; max=23;mini=0; /小时if(sel=3) address=0x86; max=31;mini=1; /日if(sel=2) address=0x88; max=12

16、;mini=1; /月if(sel=1) address=0x8c; max=99;mini=0; /年if(sel=4) address=0x8a; max=07;mini=1; /星期/先从 1302 中读出数据,把数据转换成十进制进行加减设置;后从先转换回来写入 1302 中item=R1302(address+1)/16*10+R1302(address+1)%16;/从 1302 中读出 1 字节,再转换成十进制if (sel_1=0) item+; else item-; /sel_1=0 则加,sel_1=1 则减if(itemmax) item=mini; /大于最大值,则赋最

17、小值(循环)if(item0; i-)T_IO = ACC0; /*相当于汇编中的 RRC */T_CLK = 1;T_CLK = 0;ACC = ACC 1; /* 函 数 名:RTOutputByte()功 能:实时时钟读取一字节说 明:从 DS1302 读取 1Byte 数据 (内部函数)入口参数:无 返 回 值:ACC设 计:zhaojun 日 期:2007-06-29修 改: 日 期: */uchar RTOutputByte(void) uchar i;for(i=8; i0; i-)ACC = ACC 1; /*相当于汇编中的 RRC */ACC7 = T_IO;T_CLK =

18、1;T_CLK = 0; return(ACC); /返回读取值/* 函 数 名:W1302()功 能:往 DS1302 写入数据说 明:先写地址,后写命令/数据 (内部函数)调 用:RTInputByte() , RTOutputByte()入口参数:ucAddr: DS1302 地址, ucData: 要写的数据返 回 值:无*/void W1302(uchar ucAddr, uchar ucDa)T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(ucAddr); /* 地址,命令 */RTInputByte(ucDa); /* 写 1Byte 数据*/

19、T_CLK = 1;T_RST = 0;/* 函 数 名:R1302()功 能:读取 DS1302 某地址的数据说 明:先写地址,后读命令/数据 (内部函数)调 用:RTInputByte() , RTOutputByte()入口参数:ucAddr: DS1302 地址返 回 值:ucData :读取的数据*/uchar R1302(uchar ucAddr)uchar ucData;T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(ucAddr); /* 地址,命令 */ucData = RTOutputByte(); /* 读 1Byte 数据 */T_C

20、LK = 1;T_RST = 0;return(ucData);/* 函 数 名:Set1302()功 能:设置初始时间说 明:先写地址,后读命令/数据(寄存器多字节方式 )调 用:W1302()入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年7Byte (BCD 码)1B 1B 1B 1B 1B 1B 1B返 回 值:无*/void Set1302(uchar *pClock) uchar i;uchar ucAddr = 0x80; W1302(0x8e,0x00); /* 控制命令,WP=0, 写操作?*/for(i =7; i0; i-) W1302(

21、ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */ pClock+;ucAddr +=2;W1302(0x8e,0x80); /* 控制命令,WP=1, 写保护?*/= 温度显示控制部分 =/* 函 数 名:void delay()功 能:DS18B20 延时说 明:DS18B20 时序延时入口参数:useconds 返 回 值:无 */* 18B20 驱动 */延时void delay(word useconds)for(;useconds0;useconds-);/* 函 数 名:byte ow_reset()功 能:DS18B20 复位说 明:DS18B20 使用

22、时先要复位入口参数:无 返 回 值:presence */复位byte ow_reset(void)byte presence;DQ = 0; /拉低总线delay(29); / 保持 480usDQ = 1; / 释放总线delay(3); / 等待回复presence = DQ; / 读取信号delay(25); / 等待结束信号return(presence); / 返回 0:正常 1:不存在 /* 函 数 名:byte read_byte()功 能:从 1-wire 总线上读取一个字节说 明:读总线上的数据有严格的时序入口参数: 返 回 值:value */byte read_byte

23、(void)byte i;byte value = 0;for (i=8;i0;i-)value=1;DQ = 0; DQ = 1;delay(1); if(DQ)value|=0x80;delay(6); return(value);/* 函 数 名:void write_byte()功 能:向 1-WIRE 总线上写一个字节说 明:写总线上的数据有严格的时序入口参数:val 返 回 值:无 */void write_byte(char val)byte i;for (i=8; i0; i-) / 一次写一位DQ = 0; / DQ = valdelay(5); / DQ = 1;val=v

24、al/2;delay(5);/* 函 数 名:Read_Temperature()功 能:读取和显示温度说 明:入口参数:xx,yy 返 回 值:无 */Read_Temperature(char xx,char yy)uchar i,tl_temp;uint x;uchar ct8;union /共用体byte c2;int x;temp; ow_reset(); / DS18B20 复位write_byte(0xCC); / Skip ROMwrite_byte(0x44); / 转换温度ow_reset();write_byte(0xCC); / Skip ROMwrite_byte(0

25、xbe); / 读取寄存器temp.c1=read_byte(); / 读出温度低 8 位temp.c0=read_byte(); / 读出温度高 8 位/ 零下温度判断sflag=0; /温度零下标志 0:零上,1:零下if(temp.c0 / 零下标志位置 1temp.c1=temp.c1; / 低 8 位取反temp.c0=temp.c0; / 高 8 位取反tl_temp=temp.c1+1; / 低 8 位加 1 temp.c1=tl_temp; / 计算后重新存入数组if(tl_temp255) temp.c0+; / 如果低 8 位大于 255,向高 8 位进 1x=(temp.

26、c0for(i=0;i8;i+)cti=0;i=0;while(x/10)cti=x%10;x=x/10;i+;cti=x;if(sflag=1) DisplayOneChar(xx-1,yy,0x2d);else DisplayOneChar(xx-1,yy,0x20);DisplayOneChar(xx, yy,ct2+0x30); / 显示温度十位数DisplayOneChar(xx+1,yy,ct1+0x30); / 显示温度个位数DisplayOneChar(xx+2,yy,0x2e); / 显示小数点DisplayOneChar(xx+3,yy,ct0+0x30); / 显示温度小

27、数位DisplayOneChar(xx+4,yy,0x01); / 显示自定义字符DisplayOneChar(xx+5,yy,0x43); / 显示字符“C“ /* 函 数 名:void adjust_res()功 能:温度分辨率调整说 明:此函数可以对温度的显示进行精度调节.入口参数:res 返 回 值:无 */void adjust_res(char res) / res 分别等于 0x1f, 0x3f, 0x5f 温度读数分辨率分别对应/ 0.5, 0.25, 0.125 ow_reset(); / 复位write_byte(0xcc); / 跳过 Romwrite_byte(0x4e); / 写暂存器write_byte(0x02); / 写 TH write_byte(0x01); / 写 TLwrite_byte(res); / 温度转换分辨率设置ow_reset(); / 复位write_byte(0xcc); / 跳过 Rom write_byte(0x48); / 把暂存器内容写到 EPRam 中/=程序结束=

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报