智能热水器控制程序.docx
《智能热水器控制程序.docx》由会员分享,可在线阅读,更多相关《智能热水器控制程序.docx(28页珍藏版)》请在冰豆网上搜索。
智能热水器控制程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P3^3;//定义DS18B20端口DQ
sbitBEEP=P3^7;//蜂鸣器驱动线
bitpresence,flag;
bitcompare_th,compare_tl,alarm_on_off=0,temp_th,temp_tl;
sbitLCD_RS=P2^0;
sbitLCD_RW=P2^1;
sbitLCD_EN=P2^2;
sbitK1=P1^4;
sbitK2=P1^5;
sbitK3=P1^6;
sbitK4=P1^7;
ucharcodecdis1[]={"READ_ROMCORD"};
ucharcodecdis2[]={""};
ucharcodecdis3[]={"DS18B20ERROR"};
ucharcodecdis4[]={"PLEASECHECK"};
ucharcodecdis5[]={"TEMP:
"};
ucharcodecdis6[]={"TH:
TL:
"};
unsignedchardatatemp_data[2]={0x00,0x00};
unsignedchardatatemp_alarm[2]={0x00,0x00};
unsignedchardatadisplay[5]={0x00,0x00,0x00,0x00,0x00};//温度值显示
unsignedchardatadisplay1[3]={0x00,0x00,0x00};//温度报警值显示
//unsignedcharcodeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
//0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
unsignedchardataRomCode[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsignedcharcodemytab1[8]={0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00};
unsignedcharcodemytab2[8]={0x01,0x1b,0x1d,0x19,0x1d,0x1b,0x01,0x00};//小喇叭
#definedelayNOP();{_nop_();_nop_();_nop_();_nop_();};
unsignedcharTemp,temp_comp,timecount,count;
unsignedcharcrc;
voidDisp_Temp_alarm(ucharaddr,ucharnum);
voidspk(ucharaddr);
voidset_temp_alarm();
voidtemp_compare();
voidbeep();
/*******************************************************************/
voiddelay1(intms)
{
unsignedchary;
while(ms--)
{
for(y=0;y<250;y++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/******************************************************************/
/**/
/*检查LCD忙状态*/
/*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据。
*/
/**/
/******************************************************************/
bitlcd_busy()
{
bitresult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
delayNOP();
result=(bit)(P0&0x80);
LCD_EN=0;
return(result);
}
/*******************************************************************/
/**/
/*写指令数据到LCD*/
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*/
/**/
/*******************************************************************/
voidlcd_wcmd(ucharcmd)
{
while(lcd_busy());
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
_nop_();
_nop_();
P0=cmd;
delayNOP();
LCD_EN=1;
delayNOP();
LCD_EN=0;
}
/*******************************************************************/
/**/
/*写显示数据到LCD*/
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
*/
/**/
/*******************************************************************/
voidlcd_wdat(uchardat)
{
while(lcd_busy());
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=dat;
delayNOP();
LCD_EN=1;
delayNOP();
LCD_EN=0;
}
/*******************************************************************/
/**/
/*自定义字符写入CGRAM*/
/**/
/*******************************************************************/
voidwritetab()
{
unsignedchari;
lcd_wcmd(0x40);//写CGRAM
for(i=0;i<8;i++)
lcd_wdat(mytab1[i]);
for(i=0;i<8;i++)
lcd_wdat(mytab2[i]);
}
/*******************************************************************/
/**/
/*LCD初始化设定*/
/**/
/*******************************************************************/
voidlcd_init()
{
delay1(15);
lcd_wcmd(0x01);//清除LCD的显示内容
lcd_wcmd(0x38);//16*2显示,5*7点阵,8位数据
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x0c);//显示开,关光标
delay1(5);
lcd_wcmd(0x06);//移动光标
delay1(5);
lcd_wcmd(0x01);//清除LCD的显示内容
delay1(5);
writetab();//自定义字符写入CGRAM
}
/*******************************************************************/
/**/
/*设定显示位置*/
/**/
/*******************************************************************/
voidlcd_pos(ucharpos)
{
lcd_wcmd(pos|0x80);//数据指针=80+地址变量
}
/*******************************************************************/
/**/
/*us级延时函数*/
/**/
/*******************************************************************/
voidDelay(unsignedintnum)
{
while(--num);
}
/*******************************************************************/
/**/
/*初始化ds1820*/
/**/
/*******************************************************************/
Init_DS18B20(void)
{
DQ=1;//DQ复位
Delay(8);//稍做延时
DQ=0;//单片机将DQ拉低
Delay(90);//精确延时大于480us
DQ=1;//拉高总线
Delay(8);
presence=DQ;//如果=0则初始化成功=1则初始化失败
Delay(100);
DQ=1;
return(presence);//返回信号,0=presence,1=nopresence
}
/*******************************************************************/
/**/
/*读一个字节*/
/**/
/*******************************************************************/
ReadOneChar(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);
}
/*******************************************************************/
/**/
/*写一个字节*/
/**/
/*******************************************************************/
WriteOneChar(unsignedchardat)
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
Delay(5);
DQ=1;
dat>>=1;
}
}
/*******************************************************************/
/**/
/*温度报警值写入DS18B20*/
/**/
/*******************************************************************/
Write_Temperature_alarm(void)
{
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x4e);//将设定的温度报警值写入DS18B20
WriteOneChar(temp_alarm[0]);//写TH
WriteOneChar(temp_alarm[1]);//写TL
WriteOneChar(0x7f);//12位精确度
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x48);//把暂存器里的温度报警值拷贝到EEROM
}
/*******************************************************************/
/**/
/*读取64位序列码*/
/**/
/*******************************************************************/
Read_RomCord(void)
{
unsignedcharj;
Init_DS18B20();
WriteOneChar(0x33);//读序列码的操作
for(j=0;j<8;j++)
{
RomCode[j]=ReadOneChar();
}
}
/*******************************************************************/
/**/
/*DS18B20的CRC8校验程序*/
/**/
/*******************************************************************/
ucharCRC8()
{
uchari,x;ucharcrcbuff;
crc=0;
for(x=0;x<8;x++)
{
crcbuff=RomCode[x];
for(i=0;i<8;i++)
{
if(((crc^crcbuff)&0x01)==0)
crc>>=1;
else{
crc^=0x18;//CRC=X8+X5+X4+1
crc>>=1;
crc|=0x80;
}
crcbuff>>=1;
}
}
returncrc;
}
/*******************************************************************/
/**/
/*数据转换与显示*/
/**/
/*******************************************************************/
Disp_RomCode(ucharH_num)
{
ucharj;
if(H_num==1)
lcd_pos(0x00);
if(H_num==2)
lcd_pos(0x40);
for(j=0;j<8;j++)
{
Temp=RomCode[j];
display[0]=((Temp&0xf0)>>4);
if(display[0]>9)
{display[0]=display[0]+0x37;}
else{display[0]=display[0]+0x30;}
lcd_wdat(display[0]);//高位数显示
display[1]=(Temp&0x0f);
if(display[1]>9)
{display[1]=display[1]+0x37;}
else{display[1]=display[1]+0x30;}
lcd_wdat(display[1]);//低位数显示
}
}
/*******************************************************************/
/**/
/*读取温度*/
/**/
/*******************************************************************/
Read_Temperature(void)
{
uchari;
TR0=0;//关中断,防止读数错误
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
Init_DS18B20();
WriteOneChar(0x55);//匹配ROM命令
for(i=0;i<8;i++)
WriteOneChar(RomCode[i]);
WriteOneChar(0xBE);//读取温度寄存器
temp_data[0]=ReadOneChar();//温度低8位
temp_data[1]=ReadOneChar();//温度高8位
temp_alarm[0]=ReadOneChar();//温度报警TH
temp_alarm[1]=ReadOneChar();//温度报警TL
temp_comp=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
//取温度整数值
TR0=1;//开中断
}
/*******************************************************************/
/**/
/*数据转换与温度显示*/
/**/
/*******************************************************************/
Disp_Temperature()
{
uchars=0;
if(temp_data[1]>127)//温度为负值
{
temp_data[0]=(~temp_data[0])+1;//取反加一,将补码变成原码
if((~temp_data[0])>=0xff)
temp_data[1]=(~temp_data[1])+1;
elsetemp_data[1]=~temp_data[1];
s=1;
}
display[4]=temp_data[0]&0x0f;
display[0]=(display[4]*10/16)+0x30;
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
display[3]=display[4]/100+0x30;
display[1]=display[4]%100;
display[2]=display[1]/10+0x30;
display[1]=display[1]%10+0x30;
if(display[3]==0x30)//高位为0,不显示
{
display[3]=0x20;
if(display[2]==0x30)//次高位为0,不显示
display[2]=0x20;
}
if(s)
display[3]=0x2d;//显示负号
lcd_pos(0x07);
lcd_wdat(display[3]);//百位数显示
lcd_wdat(display[2]);//十位数显示
lcd_wdat(display[1]);//个位数显示
lcd_wdat('.');
lcd_wdat(display[0]);//小数位数显示
lcd_wdat(0x00);//显示自定义字符
lcd_wdat('C');//显示C
}
/*******************************************************************/
/**/
/*蜂鸣器响一声*/
/**/
/*******************************************************************/
voidbeep()
{
unsignedchary;
for(y=0;y<100;y++)
{
Delay(70);
BEEP=!
BEEP;//BEEP取反
}
BEEP=1;//关闭蜂鸣器
Delay(25000);
}
/*******************************************************************/
/**/
/*ROMCORD显示菜单*/
/**/
/*******************************************************************/
voidRomCode_Menu()
{
ucharm;
lcd_init();//初始化LCD
lcd_pos(0);//设置显示位置为第一行
for(m=0;m<16;m++)//显示字符
lcd_wdat(cdis1[m]);
Read_RomCord();//读取64位序列码
CRC8();//CRC效验
if(crc==0)//CRC效验正确
{
Disp_RomCode
(2);//显示64位序列码
}
}
/*******************************************************************/
/**/
/*DS18B20ERROR显示菜单*/
/**/
/*******************************************************************/
voidError_Menu()
{
ucharm;
lcd_init();//初始化LCD
lcd_pos(0);//设置显示位置为第一行的第1个字符
for(m=0;m<16;m++)
lcd