智能热水器C语言程序,单片机智能热水器设计方案 含仿真与源码及视频讲解

//程序头函数

#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黑下载附件…………

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值