时钟可调+温度+LCD1602显示.docx
《时钟可调+温度+LCD1602显示.docx》由会员分享,可在线阅读,更多相关《时钟可调+温度+LCD1602显示.docx(24页珍藏版)》请在冰豆网上搜索。
![时钟可调+温度+LCD1602显示.docx](https://file1.bdocx.com/fileroot1/2023-3/31/219eef86-1980-47d2-a807-80ec20959fc5/219eef86-1980-47d2-a807-80ec20959fc51.gif)
时钟可调+温度+LCD1602显示
/**************************************************************
河南工业大学电气工程学院
测控1001刘欣
如有错误欢迎致电hellohaut@共同学习共同进步
***************************************************************/
/****************************************************************
程序名称:
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
#include
#defineuintunsignedint
#defineucharunsignedchar
#definenop()_nop_()
sbitsystem_led_port=P3^0;
#definescan_key_portP1/*定义矩阵按键端口*/
sbitDQ=P3^6;//定义DS18B20通信端口
sbitlcd_rs_port=P2^7;/*定义LCD控制端口*/
sbitlcd_rw_port=P2^6;/*定义LCD控制端口*/
sbitlcd_en_port=P2^5;/*定义LCD控制端口*/
#definelcd_data_portP0/*定义LCD控制端口*/
sbitT_CLK=P1^2;/*实时时钟时钟线引脚*/
sbitT_IO=P1^3;/*实时时钟数据线引脚*/
sbitT_RST=P3^5;/*实时时钟复位线引脚*/
sbitACC0=ACC^0;
sbitACC7=ACC^7;
ucharcodemun_to_char[]={"0123456789ABCDEF"};/*定义数字跟ASCII码的关系*/
uchardatatime_data_buff[7];/*格式为:
秒分时日月星期年*/
uchartime_temp[13];/*格式为:
年月日星期时分秒*/
ucharcodetime_reset_buff[7]={0x00,0x00,0x09,0x01,0x01,0x04,0x09};/*格式为:
秒分时日月星期年*/
uchardatalcd1602_line1[]={"2000/00/00000"};
uchardatalcd1602_line2[]={"00:
00:
0000.0C"};
ucharcodeWeeks[][3]={{"SUN"},{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}};
uchardatamenu_bit=0;/*时间设置位0退出设置时间1十年2年3十月4月5十日6日7星期8十时9时10十分11分12十秒13秒*/
uchardatamenu_count=0,menu_lighten_bit=0;
uinttemp;/*温度值*/
uchardatasystem_count=0;
/*定义按键对应的按键值*/
#definemun0_key0x18
#definemun1_key0x28
#definemun2_key0x48
#definemun3_key0x88
#definemun4_key0x14
#definemun5_key0x24
#definemun6_key0x44
#definemun7_key0x84
#definemun8_key0x12
#definemun9_key0x22
#defineup_key0x42
#defineenter_key0x82
#defineset_time_key0x11
#defineleft_key0x21
#definedown_key0x41
#defineright_key0x81
ucharcodemonth_table[]={0,31,28,31,30,31,30,31,31,30,31,30,31};/*一年12月对应的天数*/
/********************************************************************
函数名:
W1302()
功能:
往DS1302写入数据
说明:
先写地址,后写命令/数据(内部函数)
入口参数:
ucAddr:
DS1302地址,ucData:
要写的数据
返回值:
无
***********************************************************************/
voidW1302(ucharucAddr,ucharucDa)
{
uchari;
//写地址
T_RST=0;
T_CLK=0;//增加
T_RST=1;
ACC=ucAddr;
for(i=8;i>0;i--)//修改了
{
T_IO=ACC0;//修改了,这里不能用ACC^0,要在前面定义
T_CLK=1;
T_CLK=0;
ACC=ACC>>1;
}
//写数据
ACC=ucDa;
for(i=8;i>0;i--)//修改了
{
T_IO=ACC0;//修改了,这里不能用ACC^0,要在前面定义
T_CLK=1;
T_CLK=0;
ACC=ACC>>1;
}
T_CLK=1;
T_RST=0;
}
/********************************************************************
函数名:
R1302()
功能:
读取DS1302某地址的数据
说明:
先写地址,后读命令/数据(内部函数)
入口参数:
ucAddr:
DS1302地址
返回值:
ACC:
读取的数据
***********************************************************************/
ucharR1302(ucharucAddr)
{
uchari;
ACC=ucAddr;
T_RST=0;
T_CLK=0;
T_RST=1;
for(i=8;i>0;i--)//修改了
{
T_IO=ACC0;//修改了,这里不能用ACC^0,要在前面定义
T_CLK=1;
T_CLK=0;
ACC=ACC>>1;
}
for(i=8;i>0;i--)//修改了
{
ACC=ACC>>1;
ACC7=T_IO;
T_CLK=1;
T_CLK=0;//修改了
}
T_CLK=1;
T_RST=0;
return(ACC);
}
/********************************************************************
函数名:
Set1302()
功能:
设置初始时间
说明:
先写地址,后读命令/数据(寄存器多字节方式)
调用:
W1302()
入口参数:
pClock:
设置时钟数据地址格式为:
秒分时日月星期年
7Byte(BCD码)1B1B1B1B1B1B1B
返回值:
无
***********************************************************************/
voidSet1302(uchar*pClock)
{
uchari;
ucharucAddr=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码)1B1B1B1B1B1B1B
返回值:
无
***********************************************************************/
voidGet1302(ucharucCurtime[])
{
uchari;
ucharucAddr=0x81;
EA=0;
for(i=0;i<7;i++)
{
ucCurtime[i]=R1302(ucAddr);/*格式为:
秒分时日月星期年*/
ucAddr+=2;
}
EA=1;
}
voidDS1302_Enables_Charger(){
/*打开DS1302内部充电电路给电容充电*/
W1302(0x8e,0x00);/*允许写操作*/
W1302(0x90,0xa5);/*单二极管2K电阻充电*/
W1302(0x8e,0x10);/*置位写保护*/
}
//DS18B20延时函数
voiddelay(unsignedinti)
{
while(i--);
}
//DS18B20初始化函数
voidInit_DS18B20(void)
{
unsignedcharx=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读一个字节
ucharReadOneChar(void)
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--){
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)dat|=0x80;
delay(4);
}
return(dat);
}
//DS18B20写一个字节
voidWriteOneChar(unsignedchardat)
{
unsignedchari=0;
for(i=8;i>0;i--){
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
}
//DS18B20读取温度
uintReadTemperature(void)
{
unsignedchara=0;
unsignedcharb=0;
unsignedintt=0;
floattt=0;
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
a=ReadOneChar();
b=ReadOneChar();
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;//将温度的高位与低位合并
t=tt*10+0.5;//对结果进行4舍5入
return(t);
}
//---------------------------------------------
voidlcd_delay(ucharms)/*LCD1602延时*/
{
ucharj;
while(ms--){
for(j=0;j<250;j++)
{;}
}
}
voidlcd_busy_wait()/*LCD1602忙等待*/
{
lcd_rs_port=0;
lcd_rw_port=1;
lcd_en_port=1;
lcd_data_port=0xff;
while(lcd_data_port&0x80);
lcd_en_port=0;
}
voidlcd_command_write(ucharcommand)/*LCD1602命令字写入*/
{
lcd_busy_wait();
lcd_rs_port=0;
lcd_rw_port=0;
lcd_en_port=0;
lcd_data_port=command;
lcd_en_port=1;
lcd_en_port=0;
}
voidlcd_system_reset()/*LCD1602初始化*/
{
lcd_delay(20);
lcd_command_write(0x38);
lcd_delay(100);
lcd_command_write(0x38);
lcd_delay(50);
lcd_command_write(0x38);
lcd_delay(10);
lcd_command_write(0x08);
lcd_command_write(0x01);
lcd_command_write(0x06);
lcd_command_write(0x0c);
lcd_data_port=0xff;/*释放数据端口*/
}
voidlcd_char_write(ucharx_pos,y_pos,lcd_dat)/*LCD1602字符写入*/
{
x_pos&=0x0f;/*X位置范围0~15*/
y_pos&=0x01;/*Y位置范围0~1*/
if(y_pos==1)x_pos+=0x40;
x_pos+=0x80;
lcd_command_write(x_pos);
lcd_busy_wait();
lcd_rs_port=1;
lcd_rw_port=0;
lcd_en_port=0;
lcd_data_port=lcd_dat;
lcd_en_port=1;
lcd_en_port=0;
lcd_data_port=0xff;/*释放数据端口*/
}
/*1MS为单位的延时程序*/
voiddelay_1ms(ucharx)
{
ucharj;
while(x--){
for(j=0;j<125;j++)
{;}
}
}
ucharkey_scan()
{
ucharsccode,recode;
scan_key_port=0xf0;/*发全"0"的行扫描码,列线输入*/
if((scan_key_port&0xf0)!
=0xf0)/*若有键按下*/
{
delay_1ms
(2);/*延时去抖动*/
if((scan_key_port&0xf0)!
=0xf0)/*若有键按下*/
{
sccode=0xfe;/*逐行扫描初值*/
while((sccode&0x10)!
=0)
{
scan_key_port=sccode;/*输出行扫描码*/
if((scan_key_port&0xf0)!
=0xf0)/*本行有键按下*/
{
recode=(scan_key_port&0xf0)|0x0f;
scan_key_port=0xf0;
//while(((scan_key_port&0xf0)!
=0xf0));
scan_key_port=0xff;/*释放按键扫描端口*/
return((~sccode)+(~recode));/*返回特征码*/
}
elsesccode=(sccode<<1)|0x01;/*行扫描左移一位*/
}
}
}
scan_key_port=0xff;/*释放按键扫描端口*/
return(0);/*无键按下,返回值为0*/
}
voidMENU_Disp()interrupt1using3
{
uchari,k;
TH0=(65536-50000)/256;
TL0=(65536-50000)/256;
k=scan_key_port;/*将按键端口当前状态保存*/
scan_key_port=0xff;/*释放按键端口,避免跟LCD显示有冲突*/
/*刷新显示*/
lcd1602_line1[3]=mun_to_char[time_temp[0]/10];
lcd1602_line1[4]=mun_to_char[time_temp[0]%10];/*年*/
lcd1602_line1[6]=mun_to_char[time_temp[1]/10];
lcd1602_line1[7]=mun_to_char[time_temp[1]%10];/*月*/
lcd1602_line1[9]=mun_to_char[time_temp[2]/10];
lcd1602_line1[10]=mun_to_char[time_temp[2]%10];/*日*/
for(i=0;i<3;i++)lcd1602_line1[i+12]=Weeks[time_temp[3]][i];/*星期*/
lcd1602_line2[2]=mun_to_char[time_temp[4]/10];
lcd1602_line2[3]=mun_to_char[time_temp[4]%10];/*时*/
lcd1602_line2[5]=mun_to_char[time_temp[5]/10];
lcd1602_line2[6]=mun_to_char[time_temp[5]%10];/*分*/
lcd1602_line2[8]=mun_to_char[time_temp[6]/10];
lcd1602_line2[9]=mun_to_char[time_temp[6]%10];/*秒*/
//------
lcd1602_line2[11]=mun_to_char[temp/100];
lcd1602_line2[12]=mun_to_char[temp%100/10];
lcd1602_line2[14]=mun_to_char[temp%10];/*温度*/
//--根据情况是否要闪烁显示设置的时间----
if(menu_lighten_bit==1){/*闪烁显示*/
switch(menu_bit){
case1:
lcd1602_line1[3]='_';break;/*年*/
case2:
lcd1602_line1[4]='_';break;
case3:
lcd1602_line1[6]='_';break;/*月*/
case4:
lcd1602_line1[7]='_';break;
case5:
lcd1602_line1[9]='_';break;/*日*/
case6:
lcd1602_line1[10]='_';break;
case7:
lcd1602_line1[12]='';lcd1602_line1[13]=mun_to_char[time_temp[3]];lcd1602_line1[14]='';break;
case8:
lcd1602_line2[2]='_';break;/*时*/
case9:
lcd1602_line2[3]='_';break;
case10:
lcd1602_line2[5]='_';break;/*分*/
case11:
lcd1602_line2[6]='_';break;
case12:
lcd1602_line2[8]='_';break;/*秒*/
case13:
lcd1602_line2[9]='_';break;
}
}
for(i=0;i<16;i++)lcd_char_write(i,0,lcd1602_line1[i]);
for(i=0;i<16;i++)lcd_char_write(i,1,lcd1602_line2[i]);
menu_