资讯动态

STM32温湿度采集报警系统实战:DHT11时序、代码与避坑指南

发布时间:2026/10/27 17:00:24 来源:尧图企业网站定制
简介这份资源是面向嵌入式初学者与STM32开发者的温湿度采集报警系统完整工程包围绕环境监测与超限报警场景展开可用于农业、仓储、智能家居等方向的课程设计或练手项目。压缩包共204个文件约3.29MB以52个c源文件与43个h头文件为核心配合30个d依赖文件、30个o目标文件、28个crf编译中间文件以及uvprojx工程文件、sct分散加载文件、hex烧录文件等构成可直接编译的Keil工程结构。内容涉及DHT系列单总线传感器的时序配置与数据解析、ADC采样、GPIO与定时器初始化、串口通信驱动以及基于中断机制的阈值判断与蜂鸣器、LED或无线模块报警逻辑代码注释与分层结构便于理解硬件交互流程。目前已有4799人学习下载适合希望掌握STM32外设驱动、传感器通信与报警系统设计的读者参考借鉴。1. 从一份“温湿度采集报警系统”压缩包说起STM32 上最容易翻车的小系统很多人第一次接触 STM32 项目都是从温湿度采集报警系统开始的。它看起来简单一个传感器读温湿度一个单片机做判断超限就报警。但真正动手做你会发现坑比想象中多——传感器时序不对、串口打印乱码、报警阈值抖动、蜂鸣器一响程序就跑飞。这份“基于 STM32 的温湿度采集报警系统 源代码”压缩包本质上就是一套最小可用的物联网感知节点方案适合刚学完 GPIO 和串口、想找一个完整项目练手的嵌入式新手也适合需要快速搭一个环境监测原型的工程师。它解决的核心问题很明确把温湿度数据稳定采集上来在本地做超限判断并通过声光或串口输出报警。下面我按实际落地顺序把选型、接线、代码结构、参数设置和常见翻车点拆开讲你照着做就能跑通也能看清哪些地方值得投入时间优化。2. 硬件选型与最小系统搭建DHT11、STM32F103 和报警外设怎么配2.1 为什么常见方案是 DHT11 STM32F103 蜂鸣器/LED温湿度采集报警系统的硬件选型市面上最常见的组合是 STM32F103C8T6 最小系统板、DHT11 温湿度传感器、有源蜂鸣器和 LED。选 DHT11 不是因为它精度高而是因为它便宜、单总线协议简单、资料多适合验证逻辑。DHT11 的湿度测量范围 20%~90%RH精度 ±5%RH温度范围 0~50℃精度 ±2℃采样周期不低于 1 秒。如果你需要更准的数据可以换 DHT22 或 SHT30但代码时序要改。STM32F103C8T6 有足够的 GPIO 和定时器价格低标准库和 HAL 库资料都全。报警外设用有源蜂鸣器最省事给高电平就响不需要 PWM 驱动LED 用来做视觉指示方便调试时确认报警状态。接线方面DHT11 的数据脚接 STM32 的某个 GPIO比如 PA0同时接一个 4.7kΩ~10kΩ 上拉电阻到 3.3V。蜂鸣器信号脚接 PB0LED 接 PB1都串联限流电阻。供电统一用 3.3VDHT11 虽然标称 3.3V~5.5V但和 STM32 共 3.3V 时电平匹配最稳。注意 DHT11 的电源脚和地脚不要接反反接一次传感器基本就废了这是血泪经验。2.2 最小系统搭建步骤与供电检查搭建顺序建议按以下步骤走避免一上来就焊死所有线先把 STM32 最小系统板用 USB 转 TTL 模块连接电脑确认能通过串口打印“Hello”之类的测试信息证明下载和串口都正常。单独给 DHT11 接 3.3V 和 GND数据脚先悬空用万用表测电源电压是否稳定在 3.3V 附近。把 DHT11 数据脚接到 PA0加上拉电阻再下载一个只读 DHT11 的测试程序串口观察数据。最后接蜂鸣器和 LED下载完整报警程序用吹风机或湿布改变温湿度观察报警动作。供电检查容易被忽略如果 STM32 和 DHT11 由不同电源供电或者 USB 供电电流不足DHT11 会返回校验和错误。常见现象是串口打印“DHT11 Error”或数据全 0。解决方法是统一用板载 3.3V 稳压输出或者给 DHT11 单独加 100nF 去耦电容。2.3 报警外设的驱动方式与参数选择有源蜂鸣器只需要 GPIO 输出高电平就能响但要注意电流。STM32 单个 GPIO 最大输出 20mA而蜂鸣器工作电流可能到 30mA所以最好用三极管驱动比如 S8050基极串 1kΩ 电阻接 GPIO集电极接蜂鸣器负极发射极接地蜂鸣器正极接 3.3V。LED 同样串 220Ω~1kΩ 限流电阻。如果你用的是无源蜂鸣器就需要 PWM 输出方波频率 2kHz~4kHz 声音最响这时候要占用一个定时器通道。报警逻辑上我一般设两个阈值温度上限 35℃湿度上限 80%RH。超过就蜂鸣器响、LED 快闪低于下限 10℃ 或 20%RH 则 LED 慢闪蜂鸣器不响避免夜间吵人。阈值不要设得太接近日常环境值否则数据一抖动就频繁报警看起来像玄学其实是阈值太窄。3. 源代码结构拆解从 DHT11 时序到报警状态机3.1 DHT11 单总线时序的代码实现与微秒级延时DHT11 的通信协议是单总线一次完整读取包括主机拉低至少 18ms然后拉高 20~40us接着释放总线DHT11 响应 80us 低电平 80us 高电平之后连续输出 40 位数据每位以 50us 低电平开始高电平持续时间决定 0 或 1。代码里最关键的是微秒级延时不能用 HAL_Delay要用定时器或空循环校准。下面是一段基于 STM32 标准库的 DHT11 读取核心代码你可以直接抄到工程里// 微秒延时基于 SysTick 或空循环需根据主频校准 void delay_us(uint32_t us) { uint32_t i; for (i 0; i us * 8; i); // 72MHz 下约 1us需实测调整 } // 读取 DHT11 一个字节 uint8_t DHT11_ReadByte(void) { uint8_t i, byte 0; for (i 0; i 8; i) { while (DHT11_DATA_IN() 0); // 等待 50us 低电平结束 delay_us(40); // 延时 40us 判断高电平持续时间 byte 1; if (DHT11_DATA_IN() 1) { byte | 1; while (DHT11_DATA_IN() 1); // 等待剩余高电平结束 } } return byte; } // 完整读取温湿度返回 0 成功1 失败 uint8_t DHT11_ReadData(uint8_t *temp, uint8_t *humi) { uint8_t buf[5]; // 主机发送起始信号 DHT11_DATA_OUT(); DHT11_DATA_LOW(); HAL_Delay(20); // 拉低至少 18ms DHT11_DATA_HIGH(); delay_us(30); // 拉高 20~40us DHT11_DATA_IN(); // 切换为输入等待响应 if (DHT11_DATA_IN() 0) { while (DHT11_DATA_IN() 0); // 等待 80us 低电平响应 while (DHT11_DATA_IN() 1); // 等待 80us 高电平响应 for (int i 0; i 5; i) { buf[i] DHT11_ReadByte(); } DHT11_DATA_OUT(); DHT11_DATA_HIGH(); // 校验和 if (buf[0] buf[1] buf[2] buf[3] buf[4]) { *humi buf[0]; *temp buf[2]; return 0; } } return 1; }逻辑说明delay_us 的循环次数需要根据你的 STM32 主频实测调整72MHz 下空循环 8 次大约 1us但编译器优化等级会影响最好用示波器看波形。DHT11_ReadByte 里先等低电平结束再延时 40us 采样如果还是高电平就是 1否则是 0。校验和判断能过滤大部分通信错误。参数上拉低时间不能少于 18ms拉高 20~40us 之间太短 DHT11 不响应太长也不影响但浪费。3.2 主循环里的采集、判断与报警状态机主循环不要用 delay 死等建议用定时器或系统滴答做 1 秒周期任务。下面是一个简单的状态机框架typedef enum { STATE_NORMAL, STATE_ALARM_HIGH, STATE_ALARM_LOW } AlarmState; AlarmState state STATE_NORMAL; uint8_t temp, humi; while (1) { if (DHT11_ReadData(temp, humi) 0) { printf(Temp: %d C, Humi: %d %%RH\r\n, temp, humi); // 判断报警条件 if (temp TEMP_HIGH || humi HUMI_HIGH) { state STATE_ALARM_HIGH; } else if (temp TEMP_LOW || humi HUMI_LOW) { state STATE_ALARM_LOW; } else { state STATE_NORMAL; } } else { printf(DHT11 read error\r\n); } // 执行报警动作 switch (state) { case STATE_NORMAL: BEEP_OFF(); LED_OFF(); break; case STATE_ALARM_HIGH: BEEP_ON(); LED_TOGGLE(); // 快闪 break; case STATE_ALARM_LOW: BEEP_OFF(); LED_TOGGLE(); // 慢闪可通过计数器分频 break; } HAL_Delay(1000); // 1 秒采集一次 }逻辑说明状态机把报警逻辑和硬件动作分开方便扩展。TEMP_HIGH、HUMI_HIGH 等宏定义在头文件里改阈值不用动主逻辑。LED_TOGGLE 快闪和慢闪可以通过计数器实现比如快闪每 100ms 翻转慢闪每 500ms 翻转。注意 DHT11 读取失败时不要立刻报警而是保持上一次状态或进入错误提示否则传感器偶尔出错会导致误报。3.3 串口打印与数据格式避免 GBK 转 UTF8 的乱码坑串口打印是调试温湿度系统最常用的手段但很多人会遇到中文乱码。STM32 标准库默认用 GBK 编码而电脑串口助手如果设成 UTF-8 就会乱码。常见做法是串口只打印英文和数字比如“Temp: 25 C, Humi: 60 %RH”这样任何编码都不会乱。如果你非要打印中文要么把串口助手编码改成 GBK要么在代码里做 GBK 转 UTF8 的转换表但后者很占空间不推荐在资源紧张的 STM32F103 上做。串口参数一般设 115200-8-N-1波特率太高在长线或干扰环境下容易丢数据。打印频率不要太高1 秒一次足够否则串口缓冲区溢出会丢包。如果你用 printf记得重定向 fputc 到串口发送函数并在工程设置里勾选 Use MicroLIB。4. 避坑与排查温湿度采集报警系统最常见的 5 个翻车现场4.1 现象串口一直打印 DHT11 Error数据全 0原因DHT11 时序不对最常见的是 delay_us 不准或者 GPIO 模式切换没做对。DHT11 数据脚在输出和输入之间切换时必须重新配置 GPIO 方向标准库用 GPIO_Init 重新初始化HAL 库用 HAL_GPIO_DeInit 再 Init。另外上拉电阻缺失也会导致总线无法拉高。解决用示波器看 PA0 波形确认起始信号拉低 18ms、拉高 30us然后 DHT11 有响应。没有示波器就用逻辑分析仪几十块钱的够用。delay_us 用定时器实现最准比如 TIM4 做 1us 计数。4.2 现象温度值偶尔跳到 0 或 255湿度正常原因DHT11 小数部分在高温高湿环境下可能不稳定或者电源纹波大导致位判断错误。DHT11 的温度整数部分在 buf[2]小数在 buf[3]但很多代码只取整数小数丢弃。如果 buf[2] 偶尔变成 0可能是校验和通过但数据位错位。解决连续读三次取中间值或平均值电源脚加 100nF 和 10uF 电容数据线尽量短远离电机和继电器。4.3 现象蜂鸣器一响串口就停止打印或程序复位原因蜂鸣器电流太大拉低电源电压导致 STM32 复位。有源蜂鸣器直接接 GPIO 时瞬间电流可能超过 20mA而且反向电动势会干扰电源。解决用三极管驱动蜂鸣器两端并联续流二极管比如 1N4148。电源加 100uF 电解电容。如果还复位检查复位引脚是否被干扰加 100nF 电容到地。4.4 现象报警阈值附近数据频繁跳动蜂鸣器断断续续原因没有做迟滞判断温度在阈值上下 0.5℃ 波动时状态机反复切换。DHT11 精度 ±2℃本身就不适合做精确阈值判断。解决加迟滞区间比如上限 35℃只有超过 36℃ 才报警低于 34℃ 才解除。湿度同理。或者用滑动平均滤波连续 5 次超过阈值才触发报警。4.5 现象下载程序后不运行必须按复位键原因STM32 的 BOOT0 和 BOOT1 跳线不对或者下载器没有复位信号。常见于用串口下载时BOOT0 接高电平进入系统存储器下载完忘记接回 GND。解决检查 BOOT0 接地BOOT1 任意。用 ST-Link 下载时勾选“Reset after download”。如果还不行检查晶振是否起振用示波器看 8MHz 晶振引脚。5. 进阶技巧用定时器中断做非阻塞采集与低功耗优化如果你已经跑通了基础版本下一步值得做的是把主循环里的 HAL_Delay(1000) 去掉改成定时器中断触发采集。这样主循环可以处理按键、串口命令等其他任务系统响应更快。具体做法用 TIM2 配置 1Hz 中断在中断里置位标志位主循环检测标志位再调用 DHT11_ReadData。注意 DHT11 读取过程需要关中断或提高优先级否则微秒延时会被打断。低功耗方面如果系统用电池供电可以在采集间隔让 STM32 进入 Sleep 模式定时器唤醒。DHT11 不采集时断电用 GPIO 控制其电源脚。报警时再唤醒蜂鸣器。实测下来这样可以把平均电流从 20mA 降到 2mA 左右。验证方法用串口打印时间戳观察采集周期是否稳定在 1 秒用万用表测电流确认 Sleep 模式生效。我一般会保留一个调试宏一键切换阻塞和非阻塞版本方便对比。最后说个习惯每次改完代码先读一遍 DHT11 的校验和再打印原始 5 个字节确认数据来源正确。这个后悔药能帮你省下大量排查时间。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑