HT11是一款常见的数字温湿度传感器,广泛应用于环境监控、智能家居等领域,因其低成本、高稳定性、易于集成的特点,被嵌入式系统广泛采用。本文将详细讲解DHT11传感器的硬件原理、接线方式、使用注意事项,并提供STM32的驱动代码示例,帮助开发者快速上手。
一、DHT11 传感器简介
DHT11 是一款基于数字信号输出的温湿度传感器,采用单线制通信协议,能够测量环境的温度和湿度,适用于各种嵌入式系统中。它内置温湿度测量元件和数字信号处理模块,提供高精度的温湿度数据,响应迅速且稳定。

1.1 主要特性
- 温度范围:0°C 到 50°C,精度 ±2°C
- 湿度范围:20% 到 80% RH,精度 ±5% RH
- 工作电压:3V 到 5.5V,建议使用 5V 电源
- 接口:采用单线制串行接口进行数据传输,简单易用
- 数据传输方式:数字信号输出
- 测量分辨率:8-bit(温度)、8-bit(湿度)
1.2 典型应用场景
- 智能家居:温湿度监测,自动调节空调、加湿器等设备
- 环境监控:实时监控温湿度,避免设备过热或湿度过高
- 温控系统:用于自动化设备温度报警、温度控制等
- 农业温湿度监测:适用于农业温室、养殖场等环境中
二、硬件原理与接线说明
2.1 工作原理
DHT11传感器通过内部的温度传感器和湿度传感器获取环境数据,并通过单线制串行接口将数据传输给外部设备(如单片机)。传感器的数据传输过程包括温湿度的采样、A/D转换、数据格式化,并最终通过数字信号输出。
2.2 接线说明
2.2.1 引脚功能
- VCC:电源引脚,连接到 3V 到 5.5V 电源
- GND:地引脚,连接到地线
- DATA:数据传输引脚,连接到 MCU 的 GPIO 引脚
2.2.2 电源与滤波
建议为DHT11提供稳定的电源。在传感器的VDD和GND之间加入100nF的去耦电容,以滤除电源中的高频噪声,确保传感器的稳定工作。
2.2.3 数据线连接
- 上拉电阻:为了确保信号稳定,建议使用 4.7kΩ 或 10kΩ 的上拉电阻。对于连接线较长的情况,可能需要根据实际距离调整上拉电阻的阻值。
- 最大传输距离:DHT11支持的最大传输距离为20米,使用高质量的屏蔽线可以有效减少信号干扰,提高传输质量。
2.3 接线图
plaintext
STM32 GPIO 引脚 --- DHT11 数据引脚 --- GND
|
上拉电阻

三、DHT11 驱动代码实现
本文基于 STM32 的标准外设库,提供 DHT11 的驱动代码,包括初始化、数据读取和传感器操作。
3.1 头文件引用
c
#include "stm32f10x.h"
#include "DHT11.h"
#include "Delay.h"
3.2 输入输出模式配置函数
DHT11的接口信号是单线通信,因此需要配置 GPIO 引脚为输入或输出模式。
3.2.1 设置 DHT11 数据引脚为输出模式
c
void DHT11_IO_OUT(void) {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DHT11_IO; // 选择端口号(0~15或all)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置IO接口速度
GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}
3.2.2 设置 DHT11 数据引脚为输入模式
c
void DHT11_IO_IN(void) {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DHT11_IO; // 选择端口号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}
3.3 复位 DHT11 端口并发出起始信号
c
void DHT11_RST(void) {
DHT11_IO_OUT(); // 端口设置为输出模式
GPIO_ResetBits(DHT11_PORT, DHT11_IO); // 使总线为低电平
Delay_ms(20); // 拉低至少18ms
GPIO_SetBits(DHT11_PORT, DHT11_IO); // 使总线为高电平
Delay_us(30); // 主机拉高20~40us
}
3.4 检查 DHT11 是否响应
c
u8 DHT11_Check(void) {
u8 retry = 0;
DHT11_IO_IN(); // 设置为输入模式
while ((GPIO_ReadInputDataBit(DHT11_PORT, DHT11_IO) == 1) && retry < 100) {
retry++;
Delay_us(1); // 延时1微秒
}
if (retry >= 100) return 1; // 超过最大重试次数,返回1(检测失败)
retry = 0;
while ((GPIO_ReadInputDataBit(DHT11_PORT, DHT11_IO) == 0) && retry < 100) {
retry++;
Delay_us(1);
}
if (retry >= 100) return 1;
return 0;
}
3.5 读取数据函数
3.5.1 读取单个位数据
c
u8 DHT11_Read_Bit(void) {
u8 retry = 0;
while ((GPIO_ReadInputDataBit(DHT11_PORT, DHT11_IO) == 1) && retry < 100) {
retry++;
Delay_us(1);
}
retry = 0;
while ((GPIO_ReadInputDataBit(DHT11_PORT, DHT11_IO) == 0) && retry < 100) {
retry++;
Delay_us(1);
}
Delay_us(40); // 等待40us
return GPIO_ReadInputDataBit(DHT11_PORT, DHT11_IO) == 1 ? 1 : 0; // 判断返回数据
}
3.5.2 读取一个字节数据
c
u8 DHT11_Read_Byte(void) {
u8 i, dat = 0;
for (i = 0; i < 8; i++) {
dat <<= 1; // 左移1位
dat |= DHT11_Read_Bit(); // 获取数据位
}
return dat;
}
3.6 读取温湿度数据
c
u8 DHT11_Read_Data(u8 *temp, u8 *humi) {
u8 buf[5], i;
DHT11_RST(); // 复位DHT11
if (DHT11_Check() == 0) { // 检查DHT11是否响应
for (i = 0; i < 5; i++) { // 读取5字节数据
buf[i] = DHT11_Read_Byte();
}
if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) { // 校验数据
*humi = buf[0]; // 湿度
*temp = buf[2]; // 温度
}
} else {
return 1; // 读取失败
}
return 0;
}
四、使用注意事项
- 温湿度范围:DHT11的测量范围为0°C到50°C,湿度为20%到80%,因此在使用时应避免环境条件超出此范围。
- 供电电压:确保DHT11的电压在3V到5.5V之间,过高或过低的电压可能导致传感器损坏。
- 通讯质量:数据线长度过长会影响通信质量,建议使用屏蔽线,并根据距离选择合适的上拉电阻。
- 干扰问题:避免DHT11暴露在强电磁干扰或化学污染环境中,以防传感器灵敏度下降或损坏。