基于51单片机DS18B20温度传感器——智能温控风扇(散热系统)

目录

一、项目简介

1、介绍

2、实现过程 

3、材料准备

二、主要代码实现

1、DS18B20模块(温度监测)

         (1)、OneWire.c

         (2)、OneWire.h

        (3)、DS18B20.c

        (4)、DS18B20.h

2、独立按键模块(温度阈值设定、风速调节)

        (1)、Key.c

        (2)、Key.h

3、定时器0中断

      (1)、Timer0.c

      (2)、Timer0.h

4、定时器1中断

      (1)、Timer1.c

       (2)、Timer1.h

5、main主函数

三、总结


DS18B20智能温控风扇

一、项目简介

1、介绍

本项目基于51单片机DS18B20温度传感器和直流电机,设计一款智能温控风扇,根据外界温度值来自动控制风扇风速,也可以手动调节风扇风速,实现人机交互,智能控制,应用场景非常广泛,可用于给机器散热、智能家居系统、温室大棚等领域,通过该系统监测环境温度来自动控制风扇的开关和风速。

2、实现过程 

基于51单片机DS18B20温度传感器来实时监测外界温度,在LCD1602小屏幕上实时显示温度、显示风速、显示设定的温度阈值。可以通过独立按键K1、K2(按下K1阈值加1℃、按下K2阈值减1℃)来调节温度阈值,当温度高于阈值时,则自动驱动直流电机开启风扇风速为1档,当大于额定阈值2℃时,风速自动加到2档,大于额度阈值4℃时,风速自动加到3档;若人为控制风速,通过独立按键K3、K4(按下K3风速加1档、按下K4风速减1档),温控风速这会取消,防止因外界环境变化,而影响人为的体验。

3、材料准备

AT89C52芯片,直流电机,扇叶,LCD1602屏幕,供电源(充电宝)。

二、主要代码实现

  • 这里我只显示该项目中的主要代码实现过程,LCD1602模块实现代码这里没有显示,整个项目代码我放在github上面,需要自取。

1、DS18B20模块(温度监测)

  • 通过单总线协议(OneWire)与 DS18B20 进行通信,获取当前环境温度。

         (1)、OneWire.c

#include <REGX52.H>
sbit OneWire_DQ=P3^7;
/**
	*@brief  OneWire初始化
	*@param  无
	*@retval 返回DQ总线的值
*/
unsigned char OneWire_Init()
{
	unsigned char i;
	unsigned char AckBit;
	EA=0;                      //关闭定时器全部中断
	OneWire_DQ=1;              //先把总线拉高
	OneWire_DQ=0;	           //再把总线拉低
	i = 247;while (--i);       //Delay500us
	OneWire_DQ=1;              //释放总线
	i = 32;while (--i);        //Delay70us
	AckBit=OneWire_DQ;
	i = 247;while (--i);       //Delay500us
	EA=1;                      //打开定时器中断
	return AckBit; 
}
/**
	*@brief  OneWire发送一位
	*@param  一位
	*@retval 无
*/
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	EA=0;                    //关闭定时器全部中断
	OneWire_DQ=0;           //把总线拉低
	i = 4;while (--i);      //Delay10us
	OneWire_DQ=Bit;         //发送一位数据
	i = 24;while (--i);     //Delay50us
	OneWire_DQ=1;           //释放总线
	EA=1;                   //打开定时器中断
}
/**
	*@brief  OneWire接收一位
	*@param  无
	*@retval 返回一位
*/
unsigned char ReceiveBit()
{
	unsigned char i;
	unsigned char AckBit;
	EA=0;                  //关闭定时器全部中断
	OneWire_DQ=0;          //把总线拉低
	i = 2;while (--i);     //Delay5us
	OneWire_DQ=1;          //释放总线需要时间,所以释放完刚好到15us未尾
	i = 2;while (--i);     //Delay5us
	AckBit=OneWire_DQ;
	i = 24;while (--i);    //Delay50us
	EA=1;                  //打开定时器中断
	return AckBit;
	
}
/**
	*@brief  OneWire发送一个字节
	*@param  一个字节
	*@retval 无
*/
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01<<i));//逐位进行发送
	}
}
/**
	*@brief  OneWire接收一个字节
	*@param  无
	*@retval 返回一个字节
*/
unsigned char OneWire_ReceiveByte()
{
	unsigned char i;
	unsigned char Byte=0x00;//初始化为0000 0000
	for(i=0;i<8;i++)
	{
		if(ReceiveBit())
		{
			Byte=Byte|(0x01<<i);//有1,则置1
		}
	}
	return Byte;
}

         (2)、OneWire.h

#ifndef __ONEWIRE_H__
#define __ONEWIRE_H__
unsigned char OneWire_Init();
void OneWire_SendBit(unsigned char Bit);
unsigned char ReceiveBit();
void OneWire_SendByte(unsigned char Byte);
unsigned char OneWire_ReceiveByte();
#endif

        (3)、DS18B20.c

#include <REGX52.H>
#include "OneWrie.h"
#define DS18B20_SKIP_ROM           0xcc //跳过ROM
#define DS18B20_CONVERT_T          0x44 //温度变换
#define DS18B20_READ_SCRATCHPAD    0xbe //读暂存器
/**
	*@brief  DS18B20温度转化(数字形式)
	*@param  无
	*@retval 无
*/
void DS18B20_ConverT()
{
	OneWire_Init();//初始化
	OneWire_SendByte(DS18B20_SKIP_ROM);//跳过Rom
	OneWire_SendByte(DS18B20_CONVERT_T);//温度转化(数字形式)
}
/**
	*@brief  DS18B20温度转化(数字形式)
	*@param  无
	*@retval 返回温度
*/
float DS18B20_ReadT()
{
	unsigned char TLSB,TMSB;//TSLB低8位 TMSB高8位
	int Temp;//16位
	float T;
	OneWire_Init();//初始化
	OneWire_SendByte(DS18B20_SKIP_ROM);//跳过Rom
	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);//读暂存器
	TLSB=OneWire_ReceiveByte();//连续读操作
	TMSB=OneWire_ReceiveByte();
	Temp=(TMSB<<8)|TLSB;//转化成16位
	T=Temp/16.0;
	return T;
}

        (4)、DS18B20.h

#ifndef __DS18B20_H__
#define __DS18B20_H__
void DS18B20_ConverT();
float DS18B20_ReadT();
#endif

2、独立按键模块(温度阈值设定、风速调节)

  • 通过定时器扫描(在这里按键值获取只能通过定时器,因为在温度监测的单总线协议中有延时函数,如果使用Delay()函数,DS18B20温度监测会出现错误。当然也可以把延时函数写出定时器扫描方式,这里我就采用软件延时),来获取当前按下按键值

        (1)、Key.c

#include <REGX52.H>

unsigned char Key_KeyNumer;
/**
	*@brief     获取按键键码
	*@param     无
	*@retval    返回那个按键按下
*/
unsigned char KeyNum()
{
	unsigned char Temp=0;
	Temp=Key_KeyNumer;
	Key_KeyNumer=0;
	return Temp;
}
/**
    *@brief     当有按键按下时,为Key_Loop()函数更新当前状态
	*@param     无
	*@retval    返回按键码
*/
unsigned char Key_GetNumer()
{
	unsigned char KeyNumer=0;
	
	if(P3_1==0){KeyNumer=1;}
	if(P3_0==0){KeyNumer=2;}
	if(P3_2==0){KeyNumer=3;}
	if(P3_3==0){KeyNumer=4;}
	return KeyNumer;
}
/**
    *@brief     在定时器中断0中扫描按键状态
	*@param     无
	*@retval    无
*/
void Key_Loop()
{
	static unsigned char NowState,LastState;
	LastState=NowState;             //1毫秒前的状态         
	NowState=Key_GetNumer();        //当前状态
	//如果上个时间点按键按下,这个时间点未按下,则是松手瞬间,以此避免消抖和松手检测
	if(LastState==1&&NowState==0)
	{
		Key_KeyNumer=1;
	}
	if(LastState==2&&NowState==0)
	{
		Key_KeyNumer=2;
	}
	if(LastState==3&&NowState==0)
	{
		Key_KeyNumer=3;
	}
	if(LastState==4&&NowState==0)
	{
		Key_KeyNumer=4;
	}
}

        (2)、Key.h

#ifndef __KEY_H__
#define __KEY_H__
unsigned char KeyNum();
void Key_Loop();

#endif

3、定时器0中断

  • 用于扫描独立按键。

      (1)、Timer0.c

#include <REGX52.H>

/**
	*@brief  定时器0初始化,500微秒@12.000MHz
	*@param  无
	*@retval  无
*/
void Timer0_Init()		
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x90;				//设置定时初始值
	TH0 = 0xE8;				//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;         //使能定时器0中断
	EA=1;          //全局中断使能标志(1:全局中断使能,0:全局中断失能)
	PT0=1;
}

      (2)、Timer0.h

#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0_Init();

#endif

4、定时器1中断

  • PWM驱动电机实现控制风速。

      (1)、Timer1.c

#include <REGX52.H>
/**
	*@brief  定时器1初始化,100微秒@12.000MHz
	*@param  无
	*@retval  无
*/
void Timer1_Init()		
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x10;		//设置定时器模式
	TL1 = 0x9C;				//设置定时初始值
	TH1 = 0xFF;				//设置定时初始值
	TF1 = 0;			//清除TF1标志
	TR1 = 1;			//定时器1开始计时
	ET1 = 1;			//使能定时器1中断
	EA=1;               //全局中断使能标志(1:全局中断使能,0:全局中断失能)
	PT0=0;             //低优先级中断
}

       (2)、Timer1.h

#ifndef __TIMER1_H__
#define __TIMER1_H__
void Timer1_Init();

#endif

5、main主函数

  • 主函数实现的逻辑与项目简介的实现过程一致,代码注释有具体实现步骤

    #include <REGX52.H>
    #include "LCD1602.h"
    #include "Delay.h"
    #include "DS18B20.h"
    #include "Key.h"
    #include "Timer0.h"
    #include "Timer1.h"
    
    sbit Motor=P1^0;           //电机驱动P1_0引脚(1:使能,0:失能)
    float T;
    unsigned char KeyNumer,Speed;
    unsigned char Compare,Speed_Flag=0;//风速标准位(当为0:表示没有人为调速,可智能温控风速)
    signed char STD=30;       //设置温度阈值:30(可以根据自己的需求进行设置)
    /**
    	*@brief       实时监测温度并显示(DS18B20温度范围:-55~125)
    	*@param       无
    	*@retval      无
    */
    void Show_Temperature()
    {
    	DS18B20_ConverT();
    	T=DS18B20_ReadT();
    	if(T<0)
    	{
    		LCD_ShowChar(1,3,'-');
    		T=-T;
    	}
    	else
    	{
    		LCD_ShowChar(1,3,'+');
    	}
    	LCD_ShowNum(1,4,T,3);
    	LCD_ShowChar(1,7,'.');
    	LCD_ShowNum(1,8,(unsigned long)(T*100)%100,2);
    }
    /**
    	*@brief       实时控制温度阈值和风速并显示(DS18B20温度范围:-55~125,风速:0~3)
    	*@param       无
    	*@retval      无
    */
    void Control_Value()
    {
    	KeyNumer=KeyNum();
    	if(KeyNumer)
    	{
    		if(KeyNumer==1)
    		{
    			if(STD<=125)
    			{
    				STD++;
    			}
    		
    		}
    		if(KeyNumer==2)
    		{
    			if(STD>=-55)
    			{
    				STD--;
    			}
    		}
    		if(KeyNumer==3){Speed++;Speed_Flag=1;}
    		if(KeyNumer==4)
    		{
    			if(Speed!=0)
    			{
    				Speed--;
    				Speed_Flag=1;
    			}
    		}
    		Speed%=4;
    	}
    	LCD_ShowSignedNum(2,4,STD,3);
    	LCD_ShowNum(2,16,Speed,1);
    }
    
    void main()
    {	
    	DS18B20_ConverT();
    	Delay(1000);
    	LCD_Init();
    	Timer0_Init();
    	Timer1_Init();
    	LCD_ShowString(1,1,"T:");
    	LCD_ShowString(2,10,"Speed:");
    	LCD_ShowString(2,1,"STD:");
    	while(1)
    	{	
    		Show_Temperature();
    		Control_Value();
    		if(T>STD)
    		{
    			if(Speed_Flag==0)
    			{
    				Speed=1;
    			}
    			if(Speed_Flag==0&&T-2>STD)
    			{
    				Speed=2;
    			}
    			if(Speed_Flag==0&&T-4>STD)
    			{
    				Speed=3;
    			}
    		}
    		else
    		{
    			if(Speed_Flag==0)
    			{
    				Speed=0;
    			}
    		}
    		if(Speed==0){Compare=0;}
    		if(Speed==1){Compare=45;}
    		if(Speed==2){Compare=60;}
    		if(Speed==3){Compare=75;}
    	}
    }
    
    void Timer0_Routine() interrupt 1  //中断函数
    {
    	static unsigned int T0Count;
    	T0Count++;
    	TL0 = 0x90;				//设置定时初始值
    	TH0 = 0xE8;				//设置定时初始值
    	if(T0Count>20) 
    	{
    		T0Count=0;
    		Key_Loop();
    	}
    }
    
    void Timer1_Routine() interrupt 3  //中断函数
    {
    	static unsigned int T1Count;
    	T1Count++;
    	T1Count%=100;
    	TL1 = 0x9C;				//设置定时初始值
    	TH1 = 0xFF;				//设置定时初始值
    	if(T1Count<Compare)
    	{
    		Motor=1;
    	}
    	else
    	{
    		Motor=0;
    	}
    }
  • 三、总结

  • 这个系统通过 51 单片机控制 DS18B20 温度传感器,实时监测环境温度,并根据设定的温度阈值自动控制风扇的开关,也可以通过人为需求来控制风速。这种智能温控系统能够有效地调节温度,提高环境舒适度和设备的工作效率。本文为学习笔记,欢迎大家在评论区积极讨论,一起学习,可以与我私信交流单片机学习,虽然项目能实现应有的功能,但也存在一定的不足,欢迎指出我的不足!

基于51单片机DS18B20温度传感器设计的温控系统主要是用于测量和控制温度的系统DS18B20温度传感器是一款数字温度传感器,基于单总线协议,可直接与51单片机进行通信。 首先,系统通过DS18B20温度传感器实时测量环境温度。该传感器使用3引脚结构(VCC、GND和DATA),其中DATA引脚与51单片机的IO口相连,通过总线控制器将数据发送给单片机。传感器输出的数字信号可以转换成温度值,使用51单片机的ADC模块进行模数转换,得到实际温度。 其次,系统根据测得的温度值进行控制。根据设定的温度范围,在单片机程序中设定一个目标温度值。当实际温度高于该目标温度值时,单片机可以通过控制继电器或开关来开启降温装置,如风扇或空调。当实际温度低于目标温度时,则关闭降温装置。以此实现对温度的控制。 此外,系统还可以加入一些功能以增强可调节性和稳定性。例如,可以设置上下限警报温度,当温度超过上限或低于下限时,系统可以通过蜂鸣器或显示屏发出警报,提醒操作人员。另外,还可以利用51单片机的定时功能,定时监测温度并记录,以便分析温度变化趋势。 综上所述,基于51单片机DS18B20温度传感器设计的温控系统,通过实时测量温度值,并根据设定的目标温度值进行温度控制,不仅可以稳定环境温度,还可以发出警报和记录温度变化。这样的系统在实验室、温室和家庭等环境中都有广泛应用前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值