//程序头函数
#include
//显示函数
#include
//宏定义
#define uint unsigned int
#define uchar unsigned char
//管脚声明
sbit jdq= P1^0; //加热继电器
sbit shui=P1^3;//加水继电器
sbit Feng = P2^6; //蜂鸣器
//按键
sbit Key1=P1^4; //设置
sbit Key2=P1^5; //加
sbit Key3=P1^6; //减
sbit Key4=P1^7; //确定
sbit shang=P3^7;//上限
sbit xia=P3^6;//下限
sbit DQ=P2^2; //定义DS18B20总线I/O
signed char w,bj,bjx,bjd; //温度值全局变量
uchar c; //温度值全局变量
bit bdata flag=0,flag_BJ,flag_off=1,que;
//时间计算
#define Imax 14000 //此处为晶振为11.0592时的取值,
#define Imin 8000 //如用其它频率的晶振时,
#define Inum1 145 //要改变相应的取值。
#define Inum2 700
#define Inum3 3000
//解码变量
unsigned char Im[4]={0x00,0x00,0x00,0x00};
//全局变量
uchar f;
unsigned char m,Tc;
unsigned char IrOK;
//设置变量
uchar xx=29;
//下限
uchar sx=35;
//上限
int ds=0;
uchar Mode=0;
void delay(uint z)
{
uint i,j;
for(i=0;i
for(j=0;j<121;j++);
}
/**************************************************************************************************
**************************温度工作程序*************************************************************
**************************************************************************************************/
/*****延时子程序*****/
void Delay_DS18B20(int num)
{
while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
Delay_DS18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay_DS18B20(8); //精确延时,大于480us
DQ = 1; //拉高总线
Delay_DS18B20(14);
x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
Delay_DS18B20(20);
}
/*****读一个字节*****/
unsigned char 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_DS18B20(4);
}
return(dat);
}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 1;
DQ = dat&0x10;
Delay_DS18B20(5);
DQ = 0;
dat>>=1;
}
}
/*****读取温度*****/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xC1); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0xC1); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
t=b;
t<<=8;
t=t|a;
tt=t*0.00625;
t= tt*10+0.5; //放大10倍输出并四舍五入
return(t);
}
/*****读取温度*****/
void check_wendu(void)
{
c=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差
w=c/10; //计算得到整数位
if(w<0){w=0;} //设置温度显示上限
if(w>99){w=99;} //设置温度显示上限
}
/**************************************************************************************************
***************************************************************************************************
**************************************************************************************************/
/**************************************************************************************************
************************************按键工作程序***************************************************
**************************************************************************************************/
void Key()
{
//模式选择
if(Key1==0)
{
while(Key1==0);
Feng=0;
Mode++;
Display_wd();
if(Mode==4)
{
Mode=1;
Feng=1;
}
write_com(0x38);//屏幕初始化
write_com(0x0d);//打开显示 无光标 光标闪烁
write_com(0x06);//当读或写一个字符是指针后一一位
switch(Mode)
{
case 1:
{
write_com(0x80+15);//位置
Feng=1;
break;
}
case 2:
{
write_com(0x80+0x40+5);//位置
Feng=1;
break;
}
case 3:
{
write_com(0x80+0x40+14);//位置
Feng=1;
break;
}
}
}
if(Key2==0&&Mode!=0)
{
while(Key2==0);
Feng=0;
switch(Mode)
{
case 1:
{
if(ds<999)
{
ds++;
write_com(0x80+13);
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx<99-1)
{
sx++;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx
{
xx++;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
if(Key3==0&&Mode!=0)
{
while(Key3==0);
Feng=0;
switch(Mode)
{
case 1:
{
if(ds>0)
{
ds--;
write_com(0x80+13);
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx>xx+1)
{
sx--;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx>0)
{
xx--;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
if(Key4==0)
{
while(Key4==0);
Feng=0;
Mode=0;
// write_com(0x38);//屏幕初始化
// write_com(0x0c);//打开显示 无光标 无光标闪烁
Init1602();
if(ds>0)
{
flag=1;
jdq=1;
TR1=1;
}
Feng=1;
}
if(IrOK==1)
{
if(Im[2]==0x0d) //遥控设置键
{
Feng=0;
Mode++;
Display_wd();
if(Mode==4)
{
Mode=1;
Feng=1;
}
write_com(0x38);//屏幕初始化
write_com(0x0d);//打开显示 无光标 光标闪烁
write_com(0x06);//当读或写一个字符是指针后一一位
switch(Mode)
{
case 1:
{
write_com(0x80+15);//位置
Feng=1;
break;
}
case 2:
{
write_com(0x80+0x40+5);//位置
Feng=1;
break;
}
case 3:
{
write_com(0x80+0x40+14);//位置
Feng=1;
break;
}
}
}
//+键
else if(Im[2]==0x40)
{
if(Mode!=0)
{
Feng=0;
switch(Mode)
{
case 1:
{
if(ds<999)
{
ds++;
write_com(0x80+13);
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx<99-1)
{
sx++;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx
{
xx++;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
}
//-键
else if(Im[2]==0x19)
{
if(Mode!=0)
{
Feng=0;
switch(Mode)
{
case 1:
{
if(ds>0)
{
ds--;
write_com(0x80+13);
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx>xx+1)
{
sx--;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx>0)
{
xx--;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
}
//确定键
else if(Im[2]==0x15)
{
Feng=0;
Mode=0;
Init1602();
if(ds>0)
{
flag=1;
jdq=1;
TR1=1;
}
Feng=1;
}
IrOK=0;
}
}
/**************************************************************************************************
***************************************************************************************************
**************************************************************************************************/
/**************************************************************************************************
************************************报警部分程序***************************************************
**************************************************************************************************/
void Alam()
{
if(flag_BJ==1&&flag_off==1)
{
Feng=0;
delay(1000);
Feng=1;
flag_off=0;
// flag_BJ=0;
}
}
/**************************************************************************************************
***************************************************************************************************
**************************************************************************************************/
/**************************************************************************************************
*********************************************主程序************************************************
**************************************************************************************************/
void main()
{
Init1602();
EA=1;//打开中断总开关
IT1=1;//下降沿有效
EX1=1;//外部中断1开
ET1=1;//打开允许开关
TMOD=0x01;//设置工作方式
TL1=0x3c;
TH1=0xb0;//赋初值
TH0=0;//T0赋初值
TL0=0;
TR0=0;//t0开始计时
check_wendu();
delay(1000);
bjd=99;
bjx=0; //这两个变量的作用就是,防止温度大范围跳动造成加热设备误动作
while(1)
{
check_wendu();
if(Mode==0)
{
Display_1602(c,ds,sx,xx);
if((xia==1)&&(shang==1)) //低于下限
{
que=1;
shui=0;
jdq=1;
}
else
{
que=0;
}
if((shang==0)&&(xia==0)) //高于上限
{
shui=1;
if(flag_BJ==0)
flag_BJ=1;
}
if((shang==0)&&(xia==1)) //错误
{
shui=1;
jdq=1;
Feng=0;
que=1;
}
if(flag==0)
{
if((wbjx))
{
if(w>=sx)
{
jdq=1;
if(flag_BJ==0)
flag_BJ=1;
}
else if((w
{
jdq=0;
if(flag_BJ==0)
flag_BJ=1;
}
else
{
flag_BJ=0;
flag_off=1;
}
bjd=w+5;
bjx=w-5;
}
}
}
Key();
Alam();
}
}
/**************************************************************************************************
***************************************************************************************************
**************************************************************************************************/
/**************************************************************************************************
****************************************定时器工作程序*********************************************
**************************************************************************************************/
void time1() interrupt 3//定时器函数
{
uint s;
TH1=0x3c;
TL1=0xb0;//重新赋初值
s++;
if(s==1200) //s=20为1s钟 1200为1分钟
{
s=0;
ds--;
if(ds==0)
{
flag=0;
if(w>=sx)
{
jdq=1;
if(flag_BJ==0)
flag_BJ=1;
}
else if((w
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………