首页 > 编程语言 >基于STC89C51单片机的智能热水器控制系统设计(含文档、源码与proteus仿真,以及系统详细介绍)

基于STC89C51单片机的智能热水器控制系统设计(含文档、源码与proteus仿真,以及系统详细介绍)

时间:2024-07-24 20:27:34浏览次数:15  
标签:Feng proteus STC89C51 write 单片机 热水器 源码 0x80 com

本篇文章论述的是基于STC89C51单片机的智能热水器控制系统设计的详情介绍,如果对您有帮助的话,还请关注一下哦,如果有资源方面的需要可以联系我。

目录

摘  要

原理图

仿真图

代码

系统论文

资源下载


摘  要

现在社会发展迅速,人们的生活水平都有所提高,各种热水器的使用早已屡见不鲜,但是即便如此,目前市场上的热水器控制电路与人们理想中的还相差甚远,因此,我设计了智能家用点热水器来满足人们的需求。我的设计主要是以STC89C51单片机为主要核心。同时我还对单片机控制电热水器实现智能化的可能性进行了分析。主要实现的功能是可以对水位进行设置并加水,先设置好需要加水的水位段数,单片机会根据这个数判断是否需要加水,同时还可以测量并显示水温、设置水温范围,若水温超过或低于所设置的水温范围,则会报警。

该水温水位测控系统设计采用软件设计来控制,用C语言进行编程,可以实现检测水位,自动加水;检测水温,智能加热的功能,并且提高了整个系统的可靠性和稳定性。

关键词:STC89C51,DS18B20,水温水位控制

原理图


 仿真图


代码


//程序头函数
#include <reg52.h>
//显示函数
#include <display.h>
//宏定义
#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<z;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<sx-1)
				{
					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<sx-1)
							{
								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;	  
		}
}

系统论文


目  录

摘  要

ABSTRACT

第1章  绪论

1.1 选题的背景、目的及意义

1.2 国内研究状况和成果

1.3 研究设想和实验设计

第2章 硬件系统设计

2.1 方案验证

2.2 硬件系统设计

2.2.1 电源电路

2.2.2 按键电路

2.2.3 报警电路

2.2.4继电器驱动电路

2.2.5温度检测电路

2.2.6水位检测电路

2.2.7 1602液晶模块

2.2.8 红外一体接收模块

2.2.9 STC89C51功能特点介绍

2.3 硬件测试结果

第3章 软件系统设计

3.1 主程序流程图 24

总  结

参考文献

致  谢

附录1

附录2

第1章  绪论

1.1 选题的背景、目的及意义

据不完全统计,我市城镇居民家庭以电热水器为主,占总量的60%以上;从前风光无限的燃气热水器渐渐地黯然失色,市场份额仅剩不足20%;新兴的太阳能热水器虽然受到安装条件的限制,但其安全、环保的性能广受消费者青睐,发展态势迅猛,市场占有率已达到15%左右。出于对安全的考虑,城镇居民更多选择电热水器和太阳能热水器。时下的商品房通风效果并不好,燃气产生的污染无法及时消除,而电热水器和太阳能热水器则基本没有这方面的忧虑[6]。电热水器的优点:易安装,不受天气的影响,不受楼层和供水管道的限制,投入成本小。随着技术的进步和新品的开发,下置式、嵌入式等多种安装形式的电热水器先后上市,彻底摆脱了房间空间的限制。在当今社会,科技日新月异,热水器技术飞速发展,越来越多的科技成果被运用到热水器的制造中。如今的热水器产品已经绝对不是一个简单的加热器,而是科技含量高的现代化家电产品[1]。随着我国人民生活水平的逐渐提高,其生活条件有了很大的改善,与家庭生活密切相关的热水器品种层出不穷,花样翻新。正是在这样的背景下,本设计选择基于STC89C51单片机的智能电热水器的设计研究。

本课题的意义在于对热水器的智能化改进,采用单片机对其水温水位参数进行控制,提高了热水器的工作稳定性,同时引进了温度传感器DS18B20对水温进行数据采集,这样也就提高了系统的控制精度,对水位的控制结构简单,易于实现,具有很强的现实应用价值。虽然是对热水器的改进,但这种智能化的改进方法也可以应用到工业、生活的各个水温和水位控制的环境中去,对于其他相关参数的控制的改进也具有一定的借鉴意义。此次的基于单片机的水温水位测控系统是一个改进型的智能化产品,以其自身的控制精度高、稳定性好和成本低的独特优点在今后将会由广泛的实用价值,其基于单片机的改进方法也具用广泛的应用意义。

本课题的目的是为了满足人们对现代家庭舒适、便利、安全以及多元化信息服务的需求,而基于STC89C51单片机的水温水位测控系统可以实现。

选用STC89C51单片机作为控制芯片,实现了电热水器的智能化、持续稳定的热水供应、自动断电等功能,使人们洗浴时能放心享受,利于人们的身体健康,其实用、便捷的优点能快速满足人们对现代生活快节奏的需求[3]。

1.2 国内研究状况和成果

    随着人们生活质量的提高,家庭生活中随处都会见到水温和水位控制的影子,水温水位测控系统将更好的服务于社会,尤其是基于单片机的控制系统具有性价比高、使用寿命长、自动化程度高的特点。 

随着社会的发展,热水器在改善人们生活质量中起到了非常重要的作用。现在市面上的热水器种类繁多,电热水器、太阳能热时器、煤气热水器等,它们仅仅是提供能量的方式不同而已,但它们都需要对其主要的水温和水位参数加以控制,实现热时器的自动化。 

中国产业调研网发布的中国热水器行业现状调查分析及市场前景预测报告(2016 年版)认为,2014 年,电热水器及燃气热水器分别以48.94%和41.05%的占比毫无悬念 地成为市场主力。值得注意的是,以往默默无闻的空气能热水器及太阳能热水器迎来了 市场大爆发,分别实现了2420.95%和1360.51%的高增幅。

    早期温度和水位的参数控制时通过模拟电路实现的,这种方式不仅电路复杂,成本高,而且误差大,系统地稳定性不好,单片机及微型计算机技术的发展和应用有效地解决了这些缺点,特别是传感器的发展,更好的提高了检测参数的精度[7]。

1.3 研究设想和实验设计

STC89C51单片机低功耗,高性能CMOS8位单片机,片内4kb的可系统编程Flash只读程序存储器,器件采用高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。它集合了Flash程序存储器,既可在线编程(ISP)也可用传统方法进行编程及通用8位微处理器于单片机芯片中,功能很强大,可灵活应用于各种控制领域。

具体实验设计:采用STC89C51作为智能电热水器的控制芯片,通过选用电源模块、单片机模块、ISP在线编程接口、键盘模块、数码管及指示灯显示模块、水温、水位检测模块、报警输出模块,来实现智能控制的要求[5]。系统工作时,首先检测功能按键,进行温度范围设置。其次检测加减按键,进行温度范围调节,也可以按下红外遥控器上的按键操作,与主板上的按键功能一样,然后运行程序,由传感器DS18B20检测水温,当检测温度低于预设温度下限时,开始加热;检测温度高于预设温度上限时,停止加热。并可以预约加热,设定时间0-999分钟,定时时间到达自动开始加热。

第3章 软件系统设计

软件设计由主程序,键扫描子程序以及一些其他功能模块子程序三部分组成。其中主控制器子程序包括A/D转换子程序(水位、水温),键盘处理及显示子程序,温度控制子程序(使用输出比较功能),漏电保护子程序等组成。主程序要先对单片机的定时器、COP模块、A/D转换、端口、键中断等部分的工作模式参数进行初始化设定,之后系统的主程序循环可以调用各个功能模块的子程序,对相关事件的处理则是依靠标志位和判断标志位来实现。

3.1主程序流程图:

当程序开始运行时,1602LCD液晶显示器上会显示一个初始的默认值,此时通过按下按键来设定温度范围,若是没有按下则返回初始状态;若是设定了最低温度和最高温度值,则通过新设定的温度范围来运行;但是若是设定完毕之后没有按下确认键,则设定不成功,需返回重新设定温度范围,再次按下确认键。

参考文献

[1]殷为民,太阳能水温水位仪[J].家用电子,1999(1):37-38

[2]张毅刚,彭喜元.单片机原理及应用设计[M].电子工业出版社,2010:180-200

[3]王俊杰,基于89C51单片机的太阳能热水器只能控制器的设计[J].郑州轻工业学院学报:自然科学版,2005(8):67-68

[4]周秀明,曹隽,张春龙.基于DS18B20的单片机温度检测与调节系统设[J].实验室科学,2011,14(1):79-81.

[5]张振荣,晋明武,王投平,MCS-51单片机原理及实用技术[M].北京:人民邮电出版社,2012:64-120


资源下载


感谢阅读,你的点赞是我更新最大的动力!!!

如果有需要这个系统的源码、仿真、论文等资源的可以私信我。感谢你的阅读~

标签:Feng,proteus,STC89C51,write,单片机,热水器,源码,0x80,com
From: https://blog.csdn.net/m0_56379011/article/details/140672361

相关文章