51单片机(四) --- DHT11温湿度传感器
·
一、DHT11 基础参数
- 测量范围温度:0~50℃湿度:20~90% RH
- 精度温度:±2℃湿度:±5% RH
- 分辨率:1
- 供电:3~5.5V
- 数据格式:40bit(5 字节)先发高位1 字节湿度整数 + 1 字节湿度小数 + 1 字节温度整数 + 1 字节温度小数 + 1 字节校验和
二、工作原理
DHT11 内部将湿度、温度模拟量转为数字信号,通过单总线与单片机通信。
- 仅需1 根数据线完成双向通信
- 单片机为主机,DHT11 为从机
- 通信由主机发起起始信号,DHT11 响应后发送 40bit 数据
- 数据需校验,确保传输可靠
三、单总线通信时序(核心)
1. 主机起始信号

- 主机拉低总线至少 18ms(代码用 20ms)
- 释放总线,拉高20~40μs
- 完成起始,等待 DHT11 响应
2. DHT11 响应信号

- DHT11 拉低总线至少 80μs
- 释放总线,拉高80μs
- 再拉低总线,准备发数据
3. 数据位传输(关键)
- 数据 0:拉低 50μs → 拉高 26~28μs
- 数据 1:拉低 50μs → 拉高 60~70μs
- 判定方法:延时采样高电平时长,长为 1,短为 0
四、DHT11基础编程
1. 引脚定义
#define DHT11_PIN_HIGH (P2 |= (1 << 0)) // 拉高
#define DHT11_PIN_DOWN (P2 &= ~(1 << 0)) // 拉低
#define DHT11_PIN_CHECK ((P2 & (1 << 0)) != 0) // 读电平
2. 主机起始信号(对应时序)-> 唤醒 DHT11,启动通信
void master_start(void)
{
DHT11_PIN_DOWN; // 拉低总线
Delay_ms(20); // ≥18ms,满足时序
DHT11_PIN_HIGH; // 释放拉高
Delay_30us(1); // 20~40μs
}
3. DHT11 响应检测 -> 确认 DHT11 正常响应,准备接收 40bit 数据
int dht11_response(void)
{
int time = 0;
// 1. 等待DHT拉低(80μs低)
while (DHT11_PIN_CHECK && time < 4)
{
Delay_30us(1);
time++;
}
if (time >= 4) return -1; // 超时无低电平
// 2. 等待DHT拉高(80μs高)
time = 0;
while (!DHT11_PIN_CHECK && time < 4)
{
Delay_30us(1);
time++;
}
if (time >= 4) return -2; // 超时无高电平
// 3. 等待DHT拉低,进入数据发送
while (DHT11_PIN_CHECK);
return 1;
}
4. 读取 40bit 数据
int dht11_read(void)
{
int i,j;
unsigned char dht_dat[5] = {0};
unsigned char checksum = 0;
master_start(); // 发起始
if(dht11_response() != 1) return -1; // 无响应退出
// 接收5字节=40bit
for(j=0;j<5;j++)
{
for(i=0;i<8;i++)
{
while(!DHT11_PIN_CHECK); // 等待高电平到来
Delay_30us(2); // 延时60μs采样
if(DHT11_PIN_CHECK) // 仍为高→判定为1
{
dht_dat[j] |= (1 << (7 - i));
}
}
}
// 校验和判断
checksum = dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
if (checksum != dht_dat[4]) return -2; // 校验失败
humity = dht_dat[0]; // 湿度整数
temp = dht_dat[2]; // 温度整数
return 1;
}
- 采样逻辑:延时 60μs 后读电平,高 = 1,低 = 0
- 校验:前 4 字节和等于第 5 字节,数据有效
五、总结
5.1 时序精度
- 起始信号拉低必须 ≥18ms短了 DHT11 醒不来,建议写 20ms 最稳。
- 起始拉高 20~40us,不能太长也不能太短。
- 数据位判断靠延时采样0:拉低 50us + 高 26~28us1:拉低 50us + 高 60~70us→ 代码通用做法:延时 60us 左右采样,高 = 1,低 = 0。
- 全程必须用微秒级延时,毫秒延时会直接通信失败。
- 通信时不能开中断,否则时序被打乱,读不到数据。
5.2 数据格式
- 一共 40bit = 5 字节,先传高位
- 湿度整数
- 湿度小数
- 温度整数
- 温度小数
- 校验和
- 校验和 = 前 4 字节相加,校验不通过必须丢弃数据。
5.3 代码编写注意事项
- 引脚要配置为开漏 / 准双向口,支持电平拉高拉低(51 单片机 P1/P2/P3 默认可用)。
- 必须加超时判断不超时,程序会卡死在 while 里。
- 读取间隔 ≥1 秒DHT11 转换慢,频繁读会数据错乱。
- 只取整数就够用DHT11 小数位基本无意义,工程只读整数。
- 通信失败要重试,不要只读一次。
5.4 硬件注意点
- 供电 3.3~5V 都可以,3.3V 更稳定。
- 数据线建议加 10K 上拉电阻,远距离必加。
- 电源线不要太长,避免干扰导致数据错误。
DHT11 是单总线传感器,驱动关键在严格时序、微秒延时、高位先行、校验和验证,通信时必须关中断、加超时保护,读取间隔不小于 1 秒。
更多推荐


所有评论(0)