基于与STM32的加湿器之温湿度驱动

1.简介

温湿度计是一种用于测量和监测环境中温度和湿度的仪器,其工作原理基于热力学原理和物理原理。通过测量和显示环境中的温度和湿度,帮助用户了解当前环境的温湿度状况,从而采取相应的措施来调节或控制环境,以达到最佳的生产、存储或生活条件。

2.工作原理

温度传感器通常使用热敏电阻或热电偶等传感器来测量被测物体的温度。当被测物体的温度发生变化时,传感器会产生与温度相关的电阻或电压变化,这些变化会被转换成电信号或数字信号输出给仪表;湿度传感器常采用电容式湿度传感器来测量相对湿度。该传感器由一个金属氧化物电极和一个介质组成,介质中包含一个固定量的水分子。当被测物体的相对湿度发生变化时,介质中的水分子数量也会发生变化,从而导致电容值的变化,电容值的变化会被转换成数字信号输出给仪表。

3.分类与类型

温湿度计可按不同的标准进行分类,主要包括以下几种:

按测量方法分类:干湿球湿度计、露点温度计、毛发湿度计、库伦湿度计、电化学湿度计、光学型湿度计等。

按显示类型分类:指针温湿度计和数字温湿度计。指针温湿度计通过指针在表盘上的位置来指示温湿度值,而数字温湿度计则通过液晶屏幕以数字形式显示温湿度值。

按精度级别分类:民用温湿度计和工业温湿度计。工业温湿度计通常具有更高的测量精度和稳定性,适用于对温湿度要求较高的场合。

4.DHT11温湿度模块

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。

4.1 硬件接口电路

注意:

微处理器与 DHT11 的连接典型应用电路如上图所示,DATA 上拉后与微处理器的 I/O 端口相连。

1.典型应用电路中建议连接线长度短于 5m 时用 4.7K 上拉电阻,大于 5m 时根据实际情况降低上拉电阻的阻值。

2. 使用 3.3V 电压供电时连接线尽量短,接线过长会导致传感器供电不足,造成测量偏差。

3. 每次读出的温湿度数值是上一次测量的结果,欲获取实时数据,需连续读取 2 次,但不建议连续多次读取传感器,每次读取传感器间隔大于 2 秒即可获得准确的数据。

4. 电源部分如有波动,会影响到温度。如使用开关电源纹波过大,温度会出现跳动。

硬件引脚说明:

引脚 说明
VDD 电源,工作电压3.3~5V
DATA 串行数据,单总线PA11引脚
NC 空脚
GND 电源地

DHT11 器件采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约 4.7kΩ 的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。

4.2 单总线通讯简介

单总线传送数据位定义

DATA 用于微处理器与 DHT11 之间的通讯和同步,采用单总线数据格式,一次传送 40 位数据,高位先出。

数据格式:

8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位。

注:其中湿度小数部分为 0。

校验位数据定义:

"8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据"8bit 校验位等于,所得结果的末 8 位。

4.3 单总线时序

用户主机(MCU)发送一次开始信号后,DHT11 从低功耗模式转换到高速模式,待主机开始信号结束后,DHT11 发送响应信号,送出 40bit 的数据,并触发一次信采集。信号发送如图所示。

注:主机从 DHT11 读取的温湿度数据总是前一次的测量值,如两次测间隔时间很长,请连续读两次以第二次获得的值为实时温湿度值。

5.DHT11驱动示例

1.发送开始信号,等待设备响应。

主机发起时序:由主机拉低至少18ms,且不超过30ms。接着释放总线,等待从机响应。(释放总线,延时约20~40us)。

c 复制代码
//IO方向设置
#define DHT11_IO_IN()  {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=0X00008000;}
#define DHT11_IO_OUT() {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=0X00003000;}
IO操作函数											   
#define	DHT11_DQ_OUT(x) HAL_GPIO_WritePin(DHT11_GPIO_Port,DHT11_Pin,(GPIO_PinState)x)
#define	DHT11_DQ_IN  HAL_GPIO_ReadPin(DHT11_GPIO_Port,DHT11_Pin)  //数据端口	PA0 

/*******起始信号***************/
void DHT11_Rst(void)	   
{      
	DHT11_IO_OUT(); 	//配置为输出模式
	DHT11_DQ_OUT(0); 	//总线拉低
	Delay_Ms(20);    	//拉低至少18ms
	DHT11_DQ_OUT(1); 	//总线拉高
	Delay_Us(30);     	//主机拉高20~40us
}

从机响应信号:DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA引脚处于输出状态,输出 83 微秒的低电平作为应答信号,紧接着输出 87 微秒的高电平通知外设准备接收数据。

c 复制代码
/***********等待DHT11的回应***************
**返回1:未检测到DHT11的存在
**返回0:存在
*******************************************/
u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	DHT11_IO_IN();//配置为输入模式	
  	while (!DHT11_DQ_IN&&retry<100)//DHT11会拉低83us左右
	{
		retry++;
		Delay_Us(1);
	}
	if(retry>=100)return 1;	  	
   while (DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高87us
	{
		retry++;
		Delay_Us(1);
	}	 
	if(retry>=100)return 1;
	else retry=0;  
	return 0;
}

2.读取数据'0'和数据'1'。

位数据"0"的格式为: 54 微秒的低电平和 23-27 微秒的高电平;

位数据"1"的格式为: 54 微秒的低电平加 68-74微秒的高电平。

位数据"0"、"1"格式信号如图所示:

c 复制代码
/*******************读取1bit数据***************
**	数字0: 50~58us低电平,23~27us高电平
**	数字1:50~58us低电平,68~74us高电平
**返回值:1/0
*************************************************/
u8 DHT11_Read_Bit(void) 			 
{
 	u8 retry=0;
	while(DHT11_DQ_IN&&retry<100)//等待变为低电平
	{
		retry++;
		Delay_Us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100)//等待变高电平,第电平时间50~58us
	{
		retry++;
		Delay_Us(1);
	}
	Delay_Us(40);//等待40us
	if(DHT11_DQ_IN)return 1;
	else return 0;		   
}

读一字节数据示例(高位在前):

c 复制代码
/**************读取1byte数据*************
**
**从DHT11读取一个字节
**返回值:读到的数据
**
******************************************/

u8 DHT11_Read_Byte(void)    
{        
	u8 i,dat;
	dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

读取一次温湿度数据示例(5个字节):

c 复制代码
//从DHT11读取一次数据
//temp:温度值-20~60℃
//humi:湿度值5~95%RH
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
 	u8 buf[5]={0};
	u8 i;
	DHT11_Rst();//起始信号
	if(DHT11_Check()==0)//应答信号
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi++=buf[0];
			*humi=buf[1];
			*temp++=buf[2];
			*temp=buf[3];
		}
	}else return 1;
	return 0;	    
}

DHT11初始化

c 复制代码
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在    	 
u8 DHT11_Init(void)
{	 
	/*1.开时钟*/		    
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
} 

6.温湿度采集

循环采集温湿度数据,实时显示在LCD屏幕上:

c 复制代码
while(1)
{
	Delay_Ms(1);
	time++;
	if(time>=1000)
	{
		if(DHT11_Read_Data((u8*)&temp,(u8*)&humidity)==0)
		{
			//printf("温度:%d.%d℃  湿度:%d %%\r\n",temp[0],temp[1],humidity[0]);
			if(lcd_show_flag==0)
			{
				snprintf(buffer,sizeof(buffer),"%d.%dC ",temp[0],temp[1]);
				LCD_ShowStr(30,30,64,buffer,RED,WHITE);
				LCD_DrawLine(0,94,240,94,RED);
				LCD_DrawLine(0,95,240,95,RED);
				if(humidity[0]<100)
				{
					snprintf(buffer,sizeof(buffer),"%02d%% ",humidity[0]);
					LCD_ShowStr(70,125,64,buffer,RED,WHITE);
				}
				LCD_DrawLine(0,189,240,189,RED);
				LCD_DrawLine(0,190,240,190,RED);
			}
		}
		time=0;
	}
}

7.运行效果

相关推荐
螺丝钉的扭矩一瞬间产生高能蛋白2 小时前
基于FreeRTOS和STM32的微波炉
stm32·单片机·嵌入式硬件
Aspiring Q2 小时前
vscode+keil嵌入式软件开发全流程
vscode·stm32·单片机
努力创造奇迹2 小时前
STM32 HAL库 内部传感器驱动实现
stm32·单片机·嵌入式硬件
田甲5 小时前
【STM32】STemWin库,使用template API
stm32·单片机·嵌入式硬件
四夕白告木贞5 小时前
stm32week11
stm32·单片机·嵌入式硬件·学习
the sun346 小时前
深入理解单片机的运行流程
stm32·单片机·嵌入式硬件
努力创造奇迹6 小时前
STM32 HAL库 低功耗的实现
stm32·单片机·嵌入式硬件
Despacito0o6 小时前
FreeRTOS二值信号量详解与实战教程
驱动开发·stm32·单片机·嵌入式硬件·mcu·51单片机·嵌入式实时数据库
强化学习与机器人控制仿真7 小时前
ROS & ROS2 机器人深度相机激光雷达多传感器标定工具箱入门教程(一)
开发语言·人工智能·stm32·深度学习·机器人·自动驾驶
技术干货贩卖机10 小时前
0基础 | 开发环境 |51单片机编译环境 Keil C251和C51,STM32的编译环境Keil 5 MDK-ARM
arm开发·stm32·嵌入式硬件