DHT11/DHT22:一根线传温湿度的 40 位时序
更新时间:2026-09-12。本文是「集成电路大类 · 芯片设计」入门层(beginner)数字逻辑基础第一百零三篇。它和 1-Wire/DS18B20一样只用一根数据线,但是另一套私有协议、二者不兼容。理解这种「主机发起始脉冲、从机用高低电平宽度编码」的单总线,就掌握了一大类廉价传感器的解码方法。
本文要回答的问题
- 一根数据线怎么既当时钟又当数据、还区分 0 和 1?
- 主机的起始信号、传感器的应答脉冲各多长?
- 40 位数据怎么排列?DHT11 和 DHT22 的精度/负数有何差别?
- 为什么解码靠「高电平持续时间」而不能在固定时刻读电平?
- 上拉电阻、读取间隔、校验和失败重试有哪些硬性要求?
一、接线与主从握手
数据线 DATA 加 4.7~10kΩ 上拉,空闲为高;GPIO 需在「主机输出拉低」和「主机输入(被传感器/上拉驱动)」之间切换(类似开漏/三态)。通信完全由主机发起:
- 主机起始:把总线拉低至少 18ms(DHT11;DHT22 约 1ms 也可,常用 ≥1ms),再拉高 20~40µs 让出总线;
- 从机应答:传感器检测到起始后,拉低 ~80µs、再拉高 ~80µs,表示「我在、准备发」;
- 数据:紧接着连续发 40 位(MSB 先),发完释放总线回高。
主机: ‾‾\________18ms________/‾‾\__/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
从机: ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\__80µs__/‾‾80µs‾‾\ 40 位... \‾‾
主机起始拉低 应答(低) 应答(高) 数据位二、40 位数据与校验
连续 40 位 = 湿度 16 位 + 温度 16 位 + 校验和 8 位:
- DHT11:湿度高字节整数、低字节小数(基本为 0,分辨率 1%RH);温度高字节整数、低字节小数(分辨率 1°C);
- DHT22/AM2302:16 位湿度分辨率 0.1%RH,温度 0.1°C,温度最高位为 1 表示负温;
- 校验和:前 4 个字节相加取低 8 位,应等于第 5 字节,不等说明时序/干扰导致读错,丢弃重试。
三、位编码:高电平的长短决定 0/1
每个数据位都以一段 约 50µs 的低电平开始(前导),随后高电平的宽度携带数据:
- 0:50µs 低 + 26~28µs 高;
- 1:50µs 低 + 70µs 高。
位0: ‾\__50µs__/‾26~28µs‾\__
位1: ‾\__50µs__/‾‾‾70µs‾‾‾\__因此不能在某个固定时刻采样电平(时序漂移会采错),而要量「低之后那段高电平持续多久」:常见做法是检测到下降沿后延时约 40µs 越过 50µs 低段、在高段中点读电平(>短脉冲时长为 1);更稳的是用定时器/输入捕获量每段宽度并判定(>40~50µs 记 1)。关中断或用硬件捕获,避免解码被打断。
四、工程约束与排错
- 读取节奏:DHT11 采样周期不小于 1 秒(DHT22 约 0.5~2s),连续快读会得到旧值或无应答;它不像 DS18B20 有 ROM 多机寻址,总线一般只挂一个;
- GPIO 方向:起始阶段为输出开漏/推挽拉低,之后必须切回输入(带上拉)让传感器驱动;读前确认空闲为高;
- 失败处理:没见到 80/80µs 应答、位超时、校验和错都要判本次失败,释放总线、等下个周期再试,必要时上拉不足(线长)会导致高电平上升缓慢、位宽判错;
- 与 1-Wire/DS18B20对比:1-Wire 有 ROM 地址、可多挂、时隙更短、用 CRC-8;DHT 无寻址、单设备、40 位定长、用简单和校验,二者只是「单总线+上拉」形似。
与现有篇目的衔接
总结
一句话总结:DHT11/DHT22 是只用一根加 4.7~10kΩ 上拉数据线的廉价温湿度传感器,协议虽和 1-Wire 形似却互不兼容且无多机 ROM 寻址、一条总线通常只挂一个;通信由主机发起——先把双向 GPIO 配成输出拉低约 18ms(DHT11)再释放为输入,传感器回应约 80µs 低加 80µs 高的应答脉冲,然后连续送出湿度 16 位、温度 16 位、校验和 8 位共 40 位数据,DHT11 为整数级分辨率而 DHT22 为 0.1 单位且用温度最高位表示负值,校验方法是前四字节之和的低 8 位等于第五字节;每位都以约 50µs 低电平开头,再用随后高电平的长短区分数据(0 约 26~28µs、1 约 70µs),所以必须测量高段脉宽或延时越过 50µs 低段后在高段中点读电平,而不能在固定时刻采样,并用关中断或输入捕获保证不被打断;使用上读取间隔不小于 1 秒、注意 GPIO 方向切换和上拉、对应答缺失/位超时/校验失败统一判错丢弃下个周期重试;它与 DS18B20 的区别在于无地址、定长 40 位和简单和校验,而后者可多挂、时隙更短且用 CRC-8。