专业的编程技术博客社区

网站首页 > 博客文章 正文

基于c51单片机的智能温度控制系统设计与实现(含代码)

baijin 2025-05-16 11:36:34 博客文章 3 ℃ 0 评论

大家好,今天给大家介绍基于c51单片机的智能温度控制系统设计与实现,文章末尾附有本毕业设计的论文和源码的获取方式,可直接进群免费领取。

前言

本设计采用AT89C51单片机为控制芯片,硬件上用dsb18202做温度采集(有需要也可以采用dht11温湿度模块)直流电机作为降温风扇,用户可通过按键来控制转速的大小,用继电器来控制电阻丝提高温度。用lcd1602显示屏来显示环境温度并且通过按键来设置模式与最高温和最低温。

实验现象:

首先它能显示环境的温度并能设置上下限阀值,这是最基本的功能,系统上电的时候显示的是当前环境温度和设定的温度阀值,我们可以通过按键来修改温度上下限阀值。我们看,按下这个K1键会进入温度阀值设置 界面,每按一下,切换一次阀值设置(上下阀值)界面,按第3次时,会自动回到主界面,如此循环。


在进入温度阀值设计界面时,可以通过K2、K3键对阀值进行加减,这里我们只对温度整数部分进行设置,小数部分我们就不需要了,将设置好的上下限阀值保存到AT24C02(EEPROM)内,当下一次开启系统时只需从AT24C02内读取保存的阀值数据,而不需要重复设置上下限阀值。这样的话,我们用3个按键就实现了温度上下限阀值的设定,这是温度检测控制系统基本的功能。假如我们把温度上限设置为32°C,下限设置为30°C。


另外还有恒定温度的功能。当设定好上下限阀值时,系统即会把当前的温度与设定的上下限阀值对比,如果高于上限温度,开启散热进行降温,同时报警;如果低于下限温度,开启加热,同时报警;如果当前温度处于下限和上限温度之间时,关闭散热、加热及报警。从而可将温度控制在阀值的范围内。

仿真图展示:

温度高于设定值,风扇反转,警报开启

温度低于设定值,加温开启并发出警报

核心代码展示:

ds18b20的测温原理

DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。 DS18B20测温原理如图3所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。

计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。


lcd1602工作原理

点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成。显示屏上64×16个显示单元与显示RAM区的1024字节相对应,每一字节的内容与显示屏上相应位置的亮暗对应。

例如显示屏第一行的亮暗由RAM区的000H~00FH的16字节的内容决定,当(000H)=FFH时,屏幕左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,屏幕右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=00H…,(00EH)=00H,(00FH)=00H时,在屏幕的顶部显示一条由8条亮线和8条暗线组成的虚线。这就是LCD显示的基本原理。


ds18b20初始化

#include "temp.h"
 
void Delay1ms(unsigned int y)
{
	unsigned int x;
	for(y;y>0;y--)
		for(x=110;x>0;x--);
}
 
 
unsigned char Ds18b20Init()//初始化
{
	unsigned int i;
	DSPORT=0;			 //将总线拉低480us~960us
	i=70;	
	while(i--);//延时642us
	DSPORT=1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	i=0;
	while(DSPORT)	//等待DS18B20拉低总线
	{
		i++;
		if(i>5000)//等待>5MS
			return 0;//初始化失败	
	}
	return 1;//初始化成功
}
 
 
void Ds18b20WriteByte(unsigned char dat)//写入一字节
{
	unsigned int i,j;
	for(j=0;j<8;j++)
	{
		DSPORT=0;			//每写入一位数据之前先把总线拉低1us
		i++;
		DSPORT=dat&0x01; //然后写入一个数据,从最低位开始
		i=6;
		while(i--); //延时68us,持续时间最少60us
		DSPORT=1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		dat>>=1;
	}
}
 
 
unsigned char Ds18b20ReadByte()//读取字节
{
	unsigned char byte,bi;
	unsigned int i,j;	
	for(j=8;j>0;j--)
	{
		DSPORT=0;//先将总线拉低1us
		i++;
		DSPORT=1;//然后释放总线
		i++;
		i++;//延时6us等待数据稳定
		bi=DSPORT;	 //读取数据,从最低位开始读取
		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
		byte=(byte>>1)|(bi<<7);						  
		i=4;		//读取完之后等待48us再接着读取下一个数
		while(i--);
	}				
	return byte;
}
 
void  Ds18b20ChangTemp()
{
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
	Ds18b20WriteByte(0x44);	    //温度转换命令
//	Delay1ms(100);	//等待转换成功,而如果你是一直刷着的话,就不用这个延时了
   
}
 
void  Ds18b20ReadTempCom()
{	
 
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
	Ds18b20WriteByte(0xbe);	 //发送读取温度命令
}
 
 
short Ds18b20ReadTemp()
{
	unsigned char temp=0;
	unsigned char tmh,tml;
	short tem;
 
	Ds18b20ChangTemp();			 	//先写入转换命令
	Ds18b20ReadTempCom();			//然后等待转换完后发送读取温度命令
	tml=Ds18b20ReadByte();		//读取温度值共16位,先读低字节
	tmh=Ds18b20ReadByte();		//再读高字节
 
	if(tmh>7)
    {
        tmh=~tmh;
        tml=~tml; 
        temp=0;//温度为负  
    }
	else
	{
		temp=1;//温度为正	
	} 
		  	  
    tem=tmh; //获得高八位
    tem<<=8;    
    tem|=tml;//获得底八位
    tem=(double)tem*0.625;//转换   放大10倍  精度0.1 
	if(temp)
		return tem; //返回温度值
	else 
		return -tem; 
}

完整代码可进群免费领取!!!

嵌入式物联网的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而错失高薪offer。不过别担心,我为大家整理了一份150多G的学习资源,基本上涵盖了嵌入式物联网学习的所有内容。点击下方链接,0元领取学习资源,让你的学习之路更加顺畅!记得点赞、关注、收藏、转发哦!

点击这里找小助理0元领取:扫码进群领资料


Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表