/****************************************************************
程序名称: LCD1602显示时间 显示当前温度
*****************************************************************/
/*
| 0 | 1 | 2 | 3 | |
---------------------
| 4 | 5 | 6 | 7 | |
---------------------
| 8 | 9 | U | E | |
---------------------
| S | < | D | > | |
按键说明: 0-9为数字0-9输入
S为 设置时间键,初次按下为设置时间,第二次按下为退出时间,时间不保存
E为 时间保存键,按下后时间执行当前时间
< 或 > 键为可以调节设置的状态
U 或 D 键为数据加1或减1
*/
/*头文件*/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define nop() _nop_()
sbit DQ =P3^5; //定义DS18B20通信端口
sbit system_led_port = P3^0;
#define scan_key_port P1 /*定义矩阵按键端口*/
sbit lcd_rs_port = P1^7; /*定义LCD控制端口*/
sbit lcd_rw_port = P1^6;
sbit lcd_en_port = P2^4;
#define lcd_data_port P0
sbit led_latch_port = P2^5; /*发光二极管寄存器LE引脚*/
sbit sled_latch_port = P3^6; /*数码管寄存器LE引脚*/
sbit T_CLK = P1^4; /*实时时钟时钟线引脚 */
sbit T_IO = P1^5; /*实时时钟数据线引脚 */
sbit T_RST = P2^2; /*实时时钟复位线引脚 */
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
uchar code mun_to_char[] = {"0123456789ABCDEF"}; /*定义数字跟ASCII码的关系*/
uchar data time_data_buff[7];/*格式为: 秒 分 时 日 月 星期 年 */
uchar time_temp[13]; /*格式为: 年 月 日 星期 时 分 秒*/
uchar code time_reset_buff[7]={0x00,0x00,0x09,0x01,0x01,0x04,0x09};/*格式为: 秒 分 时 日 月 星期 年 */
uchar data lcd1602_line1[]={" 2000/00/00 000 "};
uchar data lcd1602_line2[]={" 00:00:00 00.0C"};
uchar code Weeks[][3]={{"SUN"},{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}};
uchar data menu_bit=0; /*时间设置位 0退出设置时间 1十年 2年 3十月 4月 5十日 6日 7星期 8十时 9时 10十分 11分 12十秒 13秒*/
uchar data menu_count=0,menu_lighten_bit=0;
uint temp; /*温度值*/
uchar data system_count=0;
/*定义按键对应的按键值*/
#define mun0_key 0x18
#define mun1_key 0x28
#define mun2_key 0x48
#define mun3_key 0x88
#define mun4_key 0x14
#define mun5_key 0x24
#define mun6_key 0x44
#define mun7_key 0x84
#define mun8_key 0x12
#define mun9_key 0x22
#define up_key 0x42
#define enter_key 0x82
#define set_time_key 0x11
#define left_key 0x21
#define down_key 0x41
#define right_key 0x81
uchar code month_table[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; /*一年12月对应的天数*/
/********************************************************************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void RTInputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
T_IO = ACC0; /*相当于汇编中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:ACC
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
RTInputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函 数 名:Set1302()
功 能:设置初始时间
说 明:先写地址,后读命令/数据(寄存器多字节方式)
调 用:W1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void Set1302(uchar *pClock)
{
uchar i;
uchar ucAddr = 0x80;
EA = 0;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
for(i =7; i>0; i--)
{
W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */
pClock++;
ucAddr +=2;
}
W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
EA = 1;
}
/********************************************************************
函 数 名:Get1302()
功 能:读取DS1302当前时间
说 明:
调 用:R1302()
入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
EA = 0;
for (i=0; i<7; i++)
{
ucCurtime[i] = R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
ucAddr += 2;
}
EA = 1;
}
void DS1302_Enables_Charger(){
/*打开DS1302内部充电电路给法拉电容充电*/
W1302(0x8e,0x00); /*允许写操作*/
W1302(0x90,0xa5); /*单二极管2K电阻充电*/
W1302(0x8e,0x10); /*置位写保护*/
}
//DS18B20延时函数
void delay(unsigned int i)
{
while(i--);
}
//DS18B20初始化函数
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
//DS18B20读一个字节
uchar ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--){
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ) dat|=0x80;
delay(4);
}
return(dat);
}
//DS18B20写一个字节
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--){
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
}
//DS18B20读取温度
uint ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;