STM32+DHT11湿度传感器【附整套代码+流程图】
目录
目录
一、模块介绍
1、模块介绍
DHT11是一款常用的数字式温湿度传感器模块,集成了温度测量与湿度测量功能,广泛应用于环境监测、智能家居、农业大棚、气象站等领域。该模块内部集成了温湿度传感器元件和一颗单片机,经过校准后可输出数字信号,用户可直接通过单片机读取数据,无需额外的模数转换电路。


2、引脚描述
DHT11温湿度传感器模块通常为3Pin或4Pin排针接口,常见引脚定义如下:
|
引脚编号 |
引脚名称 |
功能描述 |
|
1 |
VCC |
电源正极,通常接 3.3V 或 5V |
|
2 |
DATA |
单总线数据输入/输出,连接MCU的GPIO(需上拉电阻) |
|
3 |
NC |
无连接(某些模块为 4Pin) |
|
4 |
GND |
电源地线 |
3、工作参数
|
参数名称 |
参数值 |
|
工作电压 |
3.3V~5.5V |
|
工作电流 |
0.5~2.5mA |
|
温度测量范围 |
0℃~60℃ |
|
温度测量精度 |
±2℃ |
|
湿度测量范围 |
20%RH~90%RH |
|
湿度测量精度 |
±5%RH |
|
通信接口 |
单总线通信 |
|
采样周期 |
≥1s |
|
模块尺寸 |
15.5mm×12mm×5.5mm(具体视模块厂家而定) |
二、模块工作原理
1、原理图与接线说明

DHT11单总线通信需要上拉电阻(R1),因为DHT11的DATA引脚是开漏输出,它本身并不会主动驱动高电平,而是靠上拉电阻将总线电平拉高,DHT11只在需要时将数据线拉低,形成低电平信号。
如果没有上拉电阻,总线在空闲时会处于悬空状态,STM32读取到的电平可能是不可预测的,导致通信失败或数据出错。
2、通讯时序
STM32作为主机,DHT11作为从机,通信过程包含“启动信号”“响应信号”和“数据传输”三个阶段,整个通信过程的时序要求较严格,通常需通过延时精确控制GPIO读取/写入时序。通讯总时序图如下:

通信流程如下:
2.1单片机发送起始信号:STM32将DATA线拉低持续≥18ms,再将DATA线拉高持续20~40us,等待DHT11响应。
2.2DHT11响应信号:DHT11检测到起始信号后,先将DATA线拉低80μs,然后拉高80μs,表示准备发送数据。

2.3 数据传输阶段:每当DATA线拉低50μs,即表示将要开始发送下一位bit。DATA线拉高70μs表示该bit为“1”,DATA线拉低26~28μs表示该位为“0”。持续发送40bit数据为一组,顺序为:8bit湿度整数、8bit湿度小数、8bit温度整数、8bit温度小数、8bit校验和(前四字节相加取低8bit)。

2.4 0和1的表示方式,0的表示方法

1的表示方法

3、与STM32主控通讯流程图

三、程序设计
DHT11.C代码
#include "dht11.h"
#include "delay.h"
/*****************乘风单片机工作室******************
项目 : STM32DHT11传感器
版本 : V0.0
MCU : STM32F103C8T6
哔哩哔哩 : 乘风单片机工作室
CSDN : 乘风单片机工作室
****************************************************/
void DHT11_Rst(void) //复位DHT11
{
//SET OUTPUT
DHT11_Mode(OUT);
//拉低DQ
DHT11_Low;
//主机拉低18~30ms
delay_ms(20);
//拉高DQ
DHT11_High;
//主机拉高10~35us
delay_us(13);
}
/*==========================================================
Name: DHT11_Check
Function: 等待DHT11的回应
pars: 无
return: 1:未检测到DHT11的存在
0:检测到DHT11的存在
notes: 无
==========================================================*/
uint8_t DHT11_Check(void)
{
uint8_t retry=0;
DHT11_Mode(IN);//SET INPUT
while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT,DHT11_GPIO_PIN)&&retry<100)//DHT11会拉低40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while (!GPIO_ReadInputDataBit(DHT11_GPIO_PORT,DHT11_GPIO_PIN)&&retry<100)//DHT11拉低后会再次拉高40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
/*==========================================================
Name: DHT11_Read_Bit
Function: 读取DHT11一位
pars: 无
return: 1/0
notes: 无
==========================================================*/
uint8_t DHT11_Read_Bit(void)
{
uint8_t retry=0;
while(GPIO_ReadInputDataBit(DHT11_GPIO_PORT,DHT11_GPIO_PIN)&&retry<100)//等待变为低电平
{
retry++;
delay_us(1);
}
retry=0;
while(!GPIO_ReadInputDataBit(DHT11_GPIO_PORT,DHT11_GPIO_PIN)&&retry<100)//等待变高电平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(GPIO_ReadInputDataBit(DHT11_GPIO_PORT,DHT11_GPIO_PIN))return 1;
else return 0;
}
/*==========================================================
Name: DHT11_Read_Byte
Function: 读取DHT11一个字节
pars: 无
return: 读到的数据
notes: 无
==========================================================*/
uint8_t DHT11_Read_Byte(void)
{
uint8_t i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
/*==========================================================
Name: DHT11_Read_Data
Function: 读取DHT11数据
pars: temp:温度
humi:湿度
return: 0-读取成功
1-读取失败
notes: 无
==========================================================*/
uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *humi)
{
uint8_t buff[5];
uint8_t i;
DHT11_Rst(); //发送起始信号
if(DHT11_Check()==0) //等待响应
{
for(i=0;i<5;i++)//读取40位数据
{
buff[i]=DHT11_Read_Byte();
}
if((buff[0]+buff[1]+buff[2]+buff[3])==buff[4])
{
*humi=buff[0]; //温度数据
*temp=buff[2]; //湿度数据
}
}
else return 1;
return 0;
}
/*==========================================================
Name: DHT11_Init
Function: 初始化DHT11的IO口,同时检测DHT11的存在
pars: temp:温度
humi:湿度
return: 0-存在
1-不存在
notes: 无
==========================================================*/
uint8_t DHT11_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(DHT11_GPIO_CLK, ENABLE); //使能PA端口时钟
GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure); //初始化IO口
GPIO_SetBits(DHT11_GPIO_PORT,DHT11_GPIO_PIN); //输出高电平
DHT11_Rst(); //发送起始信号
return DHT11_Check();//等待DHT11的回应
}
void DHT11_Mode(uint8_t mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
if(mode)
{
GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
}
else
{
GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
}
GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure);
}
DHT11.H
#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"
#include "delay.h"
/*****************乘风单片机工作室******************
项目 : STM32光敏电阻传感器
版本 : V0.0
MCU : STM32F103C8T6
哔哩哔哩 : 乘风单片机工作室
CSDN : 乘风单片机工作室
****************************************************/
/***************自定义修改****************/
//DHT11引脚宏定义
#define DHT11_GPIO_PORT GPIOA
#define DHT11_GPIO_PIN GPIO_Pin_6
#define DHT11_GPIO_CLK RCC_APB2Periph_GPIOA
/*********************END**********************/
//输出状态定义
#define OUT 1
#define IN 0
//控制DHT11引脚输出高低电平
#define DHT11_Low GPIO_ResetBits(DHT11_GPIO_PORT,DHT11_GPIO_PIN)
#define DHT11_High GPIO_SetBits(DHT11_GPIO_PORT,DHT11_GPIO_PIN)
uint8_t DHT11_Init(void);//初始化DHT11
uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *humi);//读取温湿度数据
uint8_t DHT11_Read_Byte(void);//读取一个字节的数据
uint8_t DHT11_Read_Bit(void);//读取一位的数据
void DHT11_Mode(uint8_t mode);//DHT11引脚输出模式控制
uint8_t DHT11_Check(void);//检测DHT11
void DHT11_Rst(void);//复位DHT11
#endif
main.c
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "dht11.h"
#include "oled.h"
/*****************乘风单片机工作室******************
项目 : STM32-DHT11传感器
版本 : V0.0
MCU : STM32F103C8T6
哔哩哔哩 : 乘风单片机工作室
CSDN : 乘风单片机工作室
单片机定制+V:cfdz788 QQ:3883997176 组团优惠多多
****************************************************/
uint8_t temp,humi;
int main(void)
{
//配置系统时钟为72M
SystemInit();
delay_init(72);
LED_Init();
LED_On();
USART1_Config();//串口初始化
OLED_Init();
delay_ms(1000);
while(DHT11_Init())
{
printf("DHT11 初始化失败!\r\n");
delay_ms(1000);
}
//显示“温度:”
OLED_ShowChinese(1,1,0);
OLED_ShowChinese(1,2,1);
OLED_ShowChar(1,5, ':');
OLED_ShowChar(1,9, 'C');
//显示“湿度:”
OLED_ShowChinese(2,1, 2);
OLED_ShowChinese(2,2, 1);
OLED_ShowChar(2, 5, ':');
OLED_ShowChar(2, 9, '%');
while (1)
{
DHT11_Read_Data(&temp,&humi);//数据获取
printf("temp %d ,humi %d\r\n",temp,humi);
LED_Toggle();
delay_ms(1000);
OLED_ShowNum(1,6,temp,2); //显示温度数据
OLED_ShowNum(2,6,humi,2); //显示湿度数据s
}
}
四、视频效果演示、
DHT11温湿度传感器讲解与使用(STM32)
五、整套代码工程
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)