STM32F4_DHT11数字温湿度传感器

这篇具有很好参考价值的文章主要介绍了STM32F4_DHT11数字温湿度传感器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

1. DHT11简介

2. DHT11数据结构

3. DHT11的传输时序

3.1 DHT11开始发送数据流程

3.2 主机复位信号和DHT11响应信号

3.3 数字 “0” 信号表示方法

3.4 数字 “1” 信号表示方法

4. 硬件分析

5. 实验程序详解

5.1 main.c

5.2 DHT11.c

5.3 DHT11.h


前言

        DHT11数字温湿度传感器不但能测温度,还能测湿度。本节我们将利用STM32F4来读取DHT11的温湿度传感器,获取环境的温度和湿度值。

1. DHT11简介

        DHT11是广州奥松有限公司生产的一款温湿度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机相连。通过单片机等微处理器简单的电路连接就能实时的采集本地的温度和湿度DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个I/O 口

性能指标和特性:

  •         工作电压范围:3.5V~5.5V
  •         工作电流:0.5mA
  •         湿度测量范围:20-90%RH
  •         温度测量范围:0-50℃
  •         湿度分辨率:1%RH  8位
  •         温度分辨率:1℃  8位
  •         采样周期:1S
  •         单总线结构
  •         与TTL兼容(5V)

STM32F4_DHT11数字温湿度传感器

2. DHT11数据结构

DHT11数字温湿度传感器采用单总线数据格式。通过单个数据的引脚端口就可以完成输入输出双向传输。其数据包由5Byte(5*8=40Bit)组成。数据分小数部分和整数部分。

一次完整的数据传输为40bit,高位先行

数据格式:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和

                其中校验和数据为前四个字节相加。

DHT11和DS18B20相同,传感器输出的都是未编码的二进制数字。数据(湿度、温度、整数、小数)之间应该分开进行处理。

比方说:

        STM32F4_DHT11数字温湿度传感器

DHT11温湿度传感器一次完整的数据传输位如上图所示

那么:humidity(湿度)=byte4 . byte3=45.0(%RH)

           temperature(温度)=byte2 . byte1=28.0(℃)

           校验位byte0:byte4+byte3+byte2+byte1=73(humidity+temperature)

因此:温湿度的读取方式就是整数部分的二进制转换成十进制放在整数部分;小数部分的二进制转换成十进制放在小数部分。

注意:DHT11和MCU的一次通讯时间最大3ms,主机连续向DHT11采样的间隔建议不小于100ms。

3. DHT11的传输时序

3.1 DHT11开始发送数据流程

STM32F4_DHT11数字温湿度传感器

主机发送开始信号后,延时等待20us~40us后读取DHT11的应答信号,正常的话,DHT11 会拉低数据线,保持40~50us时间,读取总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高,保持40-50us,准备发送数据,每一位 bit 数据都以低电平开始。

如果读取响应为高电平,则DHT11没有响应,检查线路是否连接正常。

3.2 主机复位信号和DHT11响应信号

STM32F4_DHT11数字温湿度传感器

主机发送复位信号后,主机拉低总线,延时至少18ms,然后将主机拉高,延迟20-40us等待DHT11的应答信号。读取总线电平,如果为低电平,则表示从机DHT11发送应答信号成功。然后从机把总线拉高,准备发送数据。之所以拉高,是因为每发送一位数据都是以低电平开始的,为发送数据做准备。

3.3 数字 “0” 信号表示方法

STM32F4_DHT11数字温湿度传感器

因为DHT11也是遵循单总线协议的。所以也是通过高低电平延时不同时间进行组合来发送逻辑1或者逻辑0.

从机DHT11拉低总线,延时12-14us,然后从机释放总线,延时26-28us。表示发送数字 “0” 

3.4 数字 “1” 信号表示方法

STM32F4_DHT11数字温湿度传感器

从机DHT11拉低总线,延时12-14us,然后从机释放总线,延时116-118us。表示发送数字 “1” 

4. 硬件分析

STM32F4_DHT11数字温湿度传感器

  • VCC:正电源,支持3.5V~5.5V
  • Dout:输出引脚
  • NC:空脚
  • GND:地

DHT11数字温湿度传感器的第一脚接电源正极,第四脚接电源地端。数据端为第二脚。第二端数据引脚可以直接接在主机(单片机)的IO口。同时为了提高稳定性,一般在数据端和电源正极之间接一只4.7K的上拉电阻。第三脚NC为空脚,此管脚悬空不用。

STM32F4_DHT11数字温湿度传感器

5. 实验程序详解

实验现象:开机的时候先检测是否有DHT11存在,如果没有,则提示错误。只有在检测到DHT11之后才会开始读取温湿度值。如果发现了DHT11,则程序每隔100ms左右读取一次数据。

5.1 main.c

#include "stm32f4xx.h"                 
#include "delay.h"
#include "usart.h"
#include "LED.h"
#include "lcd.h"
#include "Key.h"
#include "usmart.h"
#include "MyI2C.h"
#include "AT24C02.h"
#include "DS18B20.h"
#include "DHT11.h"

//LCD状态设置函数
void led_set(u8 sta)//只要工程目录下有usmart调试函数,主函数就必须调用这两个函数
{
	LED1=sta;
}
//函数参数调用测试函数
void test_fun(void(*ledset)(u8),u8 sta)
{
	led_set(sta);
}
int main(void)
{
	u8 t=0;
	u8 temperature;
	u8 humidity;
	delay_init(168);
	uart_init(115200);
	
	LED_Init();
	LCD_Init();
	
	POINT_COLOR=RED;
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
	LCD_ShowString(30,70,200,16,16,"DHT11 Text");
	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTER");
	LCD_ShowString(30,110,200,16,16,"2023/20/23");
	
	while(DHT11_Init())//返回1表示没有检测到DHT11的存在,报错
	{
		LCD_ShowString(30,130,200,16,16,"DHT11 Rrror");
		delay_ms(200);
		LCD_Fill(30,130,239,130+16,WHITE);  //清除这块区域 x 30~239 y 130~130+16
		delay_ms(200);
	}
	LCD_ShowString(30,130,200,16,16,"DHT11 OK");
	POINT_COLOR=BLUE;
	LCD_ShowString(30,150,200,16,16,"Temperature:  C");
	LCD_ShowString(30,170,200,16,16,"Humidity:  %");
	while(1)
	{
		if(t%10==0) //每100ms读取一次
		{
			DHT11_Read_Data(&temperature,&humidity);  //读取温湿度的值
			LCD_ShowNum(30+12*8,150,temperature,2,16);  //显示温度
			LCD_ShowNum(30+9*8,170,humidity,2,16);  //显示湿度
		}
		delay_ms(10);
		t++;
		if(t==20)
		{
			t=0;
			LED0=!LED0;
		}
	}
}



5.2 DHT11.c

#include "stm32f4xx.h"            
#include "DHT11.h"
#include "delay.h"


//复位DHT11
void DHT11_Reset(void)
{
	//复位DHT11的时序:主机拉低总线,延时至少18ms,然后主机拉高总线,延时20-40us,等待从机应答
	DHT11_IO_OUT(); //复位时序是主机来完成的,所以首先设置主机IO引脚输出模式
	DHT11_DQ_OUT=0;  //主机拉低总线
	delay_ms(20);   //延时至少18ms
	DHT11_DQ_OUT=1;  //主机拉高总线
	delay_us(30);    //延时20-40us
}
//等待DHT11的应答信号
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_CheckExist(void)
{
	//应答信号的时序是:主机发送应答信号后,从机DHT11会拉低信号线,保持40-50us。此时,若读取主机总线为低电平,这说明DHT11发送了应答信号
	//DHT11发送应答信号之后,再把总线拉高,保持40-50us,准备发送数据,每一位bit数据都是以低电平开始的。
	u8 Existence=0;
	DHT11_IO_IN();  //主机IO引脚设置为输入模式,等待从机的应答信号输入
	while(DHT11_DQ_IN&&Existence<100) //从机DHT11会拉低信号线,保持40-80us,等待应答  按位&&操作必须两个条件都为真才是真
	{
		//DHT11_DQ_IN为真,就一直在这里循环,表示始终没有接收到从机DHT11的应答信号;因为总线拉低,读取高电平是始终没有响应的
		//DHT11_DQ_IN是从机DHT11发送主机MCU的信号,应答信号时,从机会拉低信号线,因此,如果主机收到的是高电平,那么意味着没有发送应答信号
		//Existence<100表示:设置一个缓冲时间去等待从机发送应答,这里设置的就是100us
		Existence++;
		delay_us(1);
	}
	if(Existence>=100)
	{
		return 1; //主机给从机的缓冲时间是100us,主机等了从机100us还是没有接收到应答信号,那么返回信息,未检测到DHT11的存在
	}
	else         //在给定的100us内接收到了应答信号,将缓冲计时变量Existence清0,为后续总线拉高后延迟做准备
		Existence=0;
	while(!DHT11_DQ_IN&&Existence<100) //拉低后再次拉高,准备发送数据,延迟40-80us
	{
		//!DHT11_DQ_IN表示主机接收到了应答信号,也就是主机接收到了低电平,延迟100us
		Existence++;
		delay_us(1);
	}
	if(Existence>=100)
	{
		return 1;
	}
	return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
	//DHT11读取一位的时序:不管读的那一位是高电平1还是低电平0,首先从机DHT11都需要拉低总线
	//数据0:从机拉低总线,延时12-14us,然后从机释放总线,延时26-28us
	//数据1:从机拉低总线,延时12-14us,然后从机释放总线,延时116-118us
	u8 data=0;
	while(DHT11_DQ_IN&&data<100)//等待变为低电平
		//主机从DHT11读取一位,从机要拉低总线,在没有拉低之前,主机收到的DHT11_DQ_IN一定是高电平1,而通过观察低电平的时序可以发现,不管是逻辑1还是0,低电平延时12-14us
	//所以设置的100us是远远大于低电平延时时间的,所以data<100这个条件在此while循环中一定为真,跳出循环的条件一定是DHT11_DQ_IN=0,也就是等待变为低电平
	{
		data++;
		delay_us(1);
	}
	data=0; //离开while循环时主机一定收到了低电平,此时DHT11_DQ_IN=0;设置data=0是为后续等待高电平做准备
	while(!DHT11_DQ_IN&&data<100) //等待变为高电平
	{
		//从上面的循环出来时,DHT11_DQ_IN=0,取反就为真
		//条件data<100:低电平0的整个发送时序延时时间(包括低电平延时12-14us,高电平延时26-28us)也远远小于100us,所以data<100在该循环中也是始终为真的
		//				高电平1的整个发送时间是大于100us的(低电平延时12-14us,高电平延时116-118us)
		//经分析,离开循环的条件是DHT11_DQ_IN变为高电平=1,取反等于0,为假。在低电平0的12-14us过去以后,高电平信号就会来临
		data++;
		delay_us(1);
	}
	//delay_us(40) 没有这个延迟40us是无法判断是数据1还是数据0的
	delay_us(40);//从上一个while循环出来以后,时序停留在刚刚变为高电平的瞬间,这个时候延时40us,数据0会跳过高电平,数据1会停留在高电平
	if(DHT11_DQ_IN) //这个时候根据主机读到的是1还是0设置返回值
		return 1;
	else
		return 0;
}
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)
{
	u8 i,data;
	data=0;
	for(i=0;i<8;i++)
	{
		data=data<<1;  //DHT11读取的字节是高位先行的,所以每循环一次都要将上次读取的那一位左移,右侧最低位补0,每次都将新读取的那一位数据和0进行|或运算。
		data=data|DHT11_Read_Bit();
	}
	return data;
}
//从DHT11读取一位数据
//temperature:温度值(范围:0~50℃)
//humidity:湿度值(范围:20%~90%)
//返回值:0 正常;1 读取失败
u8 DHT11_Read_Data(u8 *temperature,u8 *humidity)
{
	//DHT11的数据格式是:5个字节,40位数据,前两位是湿度的整数和小数部分,第三、第四位是温度的整数和小数部分,最后一位是校验位
	u8 Buf[5]; //定义一个数组来存放收到的5个字节的数组
	u8 i;
	DHT11_Reset();
	if(DHT11_CheckExist()==0)  //应答信号返回值为0,表示检测到了DHT11应答信号
	{
		for(i=0;i<5;i++) //调用读字节函数将读取到的5个字节存放到Buf数组中
		{
			Buf[i]=DHT11_Read_Byte();
		}
		if((Buf[0]+Buf[1]+Buf[2]+Buf[3])==Buf[4]) //检验成功
		{
			*humidity=Buf[0];   //这里只显示了温湿度的整数部分
			*temperature=Buf[2];
		}
	}
	else
		return 1;  //DHT11_CheckExist()==1 表示没有检测到DHT11的应答信号,报错
	return 0; //返回正常情况
}
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
u8 DHT11_Init(void)
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);  //使能GPIOG时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;  //默认设置为输出模式
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	DHT11_Reset();
	return DHT11_CheckExist(); //初始化返回检测DHT11是否成功,0:成功 1:收不到应答信号,报错
}



5.3 DHT11.h

#ifndef _DHT11__H_
#define _DHT11__H_
#include "sys.h"


//IO方向设置
//IO方向是通过位段设置的,调用GPIO模式寄存器,以下代码已经多次使用,如有不理解,可回头温习DS18B20的实验代码
#define DHT11_IO_IN() {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=0<<9*2;}	//PG9输入模式
#define DHT11_IO_OUT() {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=1<<9*2;} 	//PG9输出模式 

//IO引脚设置
#define DHT11_DQ_OUT PGout(9)  //PG9输出
#define DHT11_DQ_IN PGin(9)    //PG9输入


void DHT11_Reset(void);
u8 DHT11_CheckExist(void);
u8 DHT11_Read_Bit(void);
u8 DHT11_Read_Byte(void);
u8 DHT11_Read_Data(u8 *temperature,u8 *humidity);
u8 DHT11_Init(void);

#endif

本节程序每一步都进行了详细的注释,有哪里解释的不对的,欢迎指正!!!文章来源地址https://www.toymoban.com/news/detail-474338.html

到了这里,关于STM32F4_DHT11数字温湿度传感器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stm32连接DHT11温湿度传感器

    目录 1. DHT11简介 1.1. 连接电路  1.2. 串行接口 (单线双向)  2. cubeMX设置 3. 代码开发  3.1. 实现定时函数 3.2. 打开串口调试 3.4. 测试代码实现 4. 运行效果 信息如下: 建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使 用合适的上拉电阻  DHT11的供电电压为 3-5

    2023年04月16日
    浏览(50)
  • stm32读取DHT11温湿度传感器

    我们知道DHT11是单总线协议,只有一根数据线。 且内部有个上拉电路(下图)。那么数据线默认就是高电平那接下来就可以讲解主机如何和DHT11通讯的 读取DHT11的芯片手册,可以知道,DHT11一次完成的数据输出是40bit,高位先出。 格式:8bit湿度整数数据+8bit湿度小数数据 +8bi温

    2024年02月09日
    浏览(51)
  • STM32+DHT11采集温湿度传感器数据

            DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。 DHT11 与单片机之间能采用简单的单总线进行通信,仅

    2024年02月07日
    浏览(40)
  • stm32项目之DHT11温湿度显示(LCD1602)

    掌握LCD1602的使用 掌握DHT11的原理及使用 看懂LCD1602和DHT11时序图 看懂DHT11的原理 掌握LCD1602的显示 编写程序用LCD1602显示温湿度 DHT11部分: DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次 通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当

    2024年02月02日
    浏览(52)
  • [教程]一文搞懂STM32使用DHT11采集温湿度

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

    2024年02月01日
    浏览(39)
  • STM32使用温湿度DHT11基于HAL库开发

    DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一 个

    2024年02月03日
    浏览(64)
  • 【STM32】DHT11温湿度模块传感器详解&代码

    DHT11是数字温湿度传感器,测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调、汽车等领域。 如上图DATA引脚用于MCU与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右(超时时间的判断)。一次完整的数据传输为40bit,高位先出(MSB最高

    2024年02月12日
    浏览(52)
  • STM32+DHT11温湿度传感器(含完整代码)

    前言 DHT11数字温湿度传感器是一种数字信号输出的温湿度传感器,具有高可靠性和长期稳定性。它采用专用的数字模块和温湿度传感技术,提供准确的温湿度数据。传感器内部包含感湿元件和测温元件,并与高性能单片机连接。因此,该传感器具有优异的品质、快速响应、抗

    2024年04月08日
    浏览(70)
  • 第七章 OLED+DHT11+STM32动态显示温湿度

            上一章给大家介绍了OLED显示模块的使用,但上一章我们在OLED上显示的是静态的,不会变动的,所以这一章我结合第一章介绍的DHT11温湿度模块,实现温湿度数值在OLED显示模块上进行动态显示,其实也是非常简单。         首先打开第一章提供的DHT11代码工程文件和

    2024年01月16日
    浏览(42)
  • STM32驱动dht11检测温湿度由OLED12864显示

    本次实验所使用的硬件环境如下: STM32F103C8T6开发板 DHT11温湿度传感器 OLED12864显示屏 杜邦线若干 软件环境 本次实验所使用的软件环境如下: Keil C51编译器 ST-LINK V2下载器 ST-LINK Utility软件 硬件连接 首先,将STM32F103C8T6开发板、DHT11温湿度传感器和OLED12864显示屏分别连接在一起

    2023年04月13日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包