一、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. 主机起始信号

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

2. DHT11 响应信号

  1. DHT11 拉低总线至少 80μs
  2. 释放总线,拉高80μs
  3. 再拉低总线,准备发数据

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 时序精度

  1. 起始信号拉低必须 ≥18ms短了 DHT11 醒不来,建议写 20ms 最稳。
  2. 起始拉高 20~40us,不能太长也不能太短。
  3. 数据位判断靠延时采样0:拉低 50us + 高 26~28us1:拉低 50us + 高 60~70us→ 代码通用做法:延时 60us 左右采样,高 = 1,低 = 0。
  4. 全程必须用微秒级延时,毫秒延时会直接通信失败。
  5. 通信时不能开中断,否则时序被打乱,读不到数据。

5.2 数据格式

  • 一共 40bit = 5 字节先传高位
    1. 湿度整数
    2. 湿度小数
    3. 温度整数
    4. 温度小数
    5. 校验和
  • 校验和 = 前 4 字节相加,校验不通过必须丢弃数据。

5.3 代码编写注意事项

  1. 引脚要配置为开漏 / 准双向口,支持电平拉高拉低(51 单片机 P1/P2/P3 默认可用)。
  2. 必须加超时判断不超时,程序会卡死在 while 里。
  3. 读取间隔 ≥1 秒DHT11 转换慢,频繁读会数据错乱。
  4. 只取整数就够用DHT11 小数位基本无意义,工程只读整数。
  5. 通信失败要重试,不要只读一次。

5.4 硬件注意点

  1. 供电 3.3~5V 都可以,3.3V 更稳定。
  2. 数据线建议加 10K 上拉电阻,远距离必加。
  3. 电源线不要太长,避免干扰导致数据错误。

DHT11 是单总线传感器,驱动关键在严格时序、微秒延时、高位先行、校验和验证,通信时必须关中断、加超时保护,读取间隔不小于 1 秒。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐