news 2026/9/9 2:34:02

基于STM32的智能除湿器设计与实现:从选型到调试完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于STM32的智能除湿器设计与实现:从选型到调试完整实战

简介:基于STM32的除湿器控制系统完整源码,面向嵌入式初学者与进阶开发者,适合学习外设驱动、传感器采集、控制算法与RTOS综合应用。资料含212个文件,压缩包10.15MB,主要包括C源码、H头文件、Keil工程配置(uvprojx)、编译中间文件(o/d/crf/axf/hex等)以及STM32CubeMX的IOC配置,便于复现工程与二次开发。源码按硬件驱动层、控制算法、用户接口、实时系统和数据通信模块组织,覆盖GPIO控制继电器、定时器轮询、ADC读取湿度、PWM调速,并实现PID等闭环策略控制压缩机或风扇;LCD显示与按键交互,FreeRTOS多任务调度及UART/蓝牙远程监控等内容均有体现。已有488人学习下载,可作为智能家居除湿器、小型环境控制类项目的设计参考与代码模板。 把一个几百块的家用除湿器拆开,里面真正负责控制的往往只是一个简单的湿敏开关;但当我决定基于STM32从零设计一款除湿器的时候,才发现这个小家电其实是一个特别完整的嵌入式练手项目。它要采湿度、要控负载、要做人机交互,还要在高湿环境里稳定运行,软硬件两个方向都能踩出一堆真实问题。这篇博文把我从选型、电路设计、核心控制逻辑到现场调试踩坑的完整过程都记录下来,关键代码直接贴出来。适合正在做课程设计、毕业设计,或者想找一个软硬件都有代表性的STM32实战项目的朋友参考。项目完整源码我也整理好了,工程的目录结构和关键函数会在文末给出,你完全可以照着搭一个自己的版本。

一个看似简单的除湿器,涉及的知识点一点都不少:不同湿度传感器的精度差异、滞回控制为什么必须用、继电器动作对MCU的电源干扰、I2C通信的可靠性问题、下载器连不上芯片的奇葩原因。接下来我按完整项目的推进顺序来写,尽量把每一步的"为什么这么做"也讲清楚。

1. 除湿器项目的选型决策:从需求反推MCU与传感器

1.1 先想清楚:你要做的是"防潮箱除湿"还是"整屋除湿"

很多人一上来就纠结用哪颗芯片,其实第一步应该确定场景。做整屋除湿需要压缩机和大功率控制,还要处理220V强电,安全要求高、结构也复杂,除非你本来就是搞家电设计的,不然不建议第一次就上手。我做的是衣柜、鞋柜、防潮箱这一类小空间的除湿器,功率小、用12V直流供电,安全性和可玩性都高很多。

场景确定之后,需求就很清楚了:实时采集柜内湿度,湿度高了自动开启除湿,达到目标湿度后自动停,并且要有一个显示和手动控制入口。整体来看,它就是一个典型的"传感器+执行器+人机交互"闭环系统,也是STM32最擅长的场景。

1.2 湿度传感器:别只看便宜,要看精度和稳定性

我在网上看了一圈,发现很多"DIY除湿器"教程用的是DHT11,价格确实便宜,但它的精度只有±5%RH,而且湿度高的时候读数迟滞明显。做温度演示可以,但拿它当除湿器的闭环控制输入就有点勉强了——你会发现同样的环境湿度,它上午读60%,下午可能读66%,滞回区间设小了系统就会抖动。

传感器湿度精度接口采样率价格区间适合场景
DHT11±5%RH单总线1Hz几元学习演示
DHT22±2%RH单总线0.5Hz十几元一般控制
AHT20±2%RHI2C真1Hz+几元到十几元性价比之选
SHT30±2~3%RHI2C真1Hz+十几到二十几元长期稳定

最终我选了SHT30,理由是长期稳定性好,而且内部有可选的加热功能可以清除结露。但我必须说,AHT20的设计也很够用,如果预算卡得紧,用AHT20完全没问题,驱动代码和SHT30一样都是I2C,只是寄存器地址和命令不同。

再说一句DHT11和DHT22的单总线协议。单总线对时序要求很严,我在STM32上实测过,关中断或者被中断打断就容易出现读取超时。I2C接口的设备在容错性上好不少,这也是我倾向I2C的原因。

1.3 主控选型:为什么不是51、不是Arduino,而是STM32

如果用Arduino写这个项目,确实更快,但那更像"搭积木"而不是"做开发"。为什么选STM32F103C8T6?这颗芯片核心板十几块钱,货源满大街都是,GPIO、ADC、I2C、定时器全都有,资料最全,即便出问题也能搜到大量解决方案。更关键的是,除湿器的控制逻辑虽然不复杂,但要处理滞回控制、状态机、传感器异常重试这些,用标准库或HAL库写出来结构更清晰,对学习和答辩都更有说服力。

如果要做电池供电的便携款,可以考虑STM32L0系列的低功耗型号,代码层面的逻辑基本不变。我后面的源码仍然以F103C8T6为准,因为这是大多数人手头就有的板子。

2. 硬件电路设计中的几个细节:不只是连线路而已

2.1 传感器不是随便接上去就能用的

拿到SHT30之后,你先确认模块上有没有焊上拉电阻。我买的模块有上拉,但自己做的小板子忘了焊,I2C总线在高湿度环境下波形畸变得一塌糊涂,最后补了4.7k电阻才稳定。上拉电阻选4.7k还是10k?短距离(10cm内)两者都行,但传感器离MCU稍远或者走线比较杂的时候,4.7k的抗干扰更好。

传感器摆放位置比电路还要重要。最开始我把传感器放在半导体制冷片旁边,结果冷端凝结的水珠直接影响了读数,湿度一度显示99%。后来把传感器移到了靠近进风口、远离冷端的侧面,读数才恢复正常。这个教训我想强调一下:传感器的安装位置属于结构设计问题,但它直接影响控制逻辑能否正常工作。

2.2 继电器驱动与电源去耦

控制半导体制冷片和风扇,我用的是MOS管加继电器双保险的方式。严格来说,小电流负载用MOS管就够了,但为了演示电器控制,我还是保留了继电器。驱动继电器时一定要加续流二极管,不然继电器线圈在断电瞬间会产生很高的反向电压,轻则干扰MCU,重则打坏引脚。

"继电器一动作MCU就重启"这个问题我折腾了整整一天,后来用示波器看3.3V电源轨才发现,继电器吸合瞬间电流尖峰把MCU的供电直接拉到了2.8V以下。解决方法是把负载电源与MCU电源分开,再在继电器供电端加470µF电解电容和0.1µF陶瓷电容。软件上我也做了兜底,继电器动作后延时50ms再执行其他逻辑。

小功率场景有一个更干净的替代方案:用MOS管或ULN2003直接驱动12V设备,省掉继电器也就省掉了一大类干扰问题。做产品时我倾向于无继电器方案,教程里保留继电器是为了让大家把感性负载这个坑踩明白。

2.3 潮湿环境下的PCB与结构设计

除湿器的工作环境本身就是高湿,PCB表面容易凝露,我在板子洗干净吹干后喷了一层三防漆,主要保护电源部分和MCU,传感器区域留空不喷以免影响测湿。接线端子尽量选防潮型或用硅胶封闭裸露焊点。交流220V方案我不展开讲了,涉及安全,非专业人士不要自制。

3. 核心控制逻辑与源码架构:让除湿器真正"聪明"起来

3.1 滞回控制:不只是"到了阈值就开关"

很多初学写法是"湿度大于60%就开,低于60%就关",这在真实的湿度信号里会出问题。因为湿度是一个连续波动的量,不是干干净净的60.0数字,它会在60附近上下抖动,继电器就会咔哒咔哒来回吸合。且不说触点和继电器寿命,光那个响声就够烦人。

正确做法是滞回控制,两个阈值之间留一个缓冲区间:

#define HUM_START_THRESHOLD 65.0f #define HUM_STOP_THRESHOLD 55.0f static bool dehumidifier_on = false; void control_task(void) { float hum = sensor_get_humidity(); if (!dehumidifier_on && hum > HUM_START_THRESHOLD) { dehumidifier_on = true; relay_set(RELAY_DEHUMIDIFIER, ON); } else if (dehumidifier_on && hum < HUM_STOP_THRESHOLD) { dehumidifier_on = false; relay_set(RELAY_DEHUMIDIFIER, OFF); } }

湿度超过65%启动,一直运行到低于55%才停止。中间55%到65%这段是盲区,系统保持当前状态不变。这个思路和空调温控一样——设定26℃不是一到26℃就停机,而是降温到25℃再停,等升温到27℃再开,避免压缩机频繁启停。

3.2 传感器数据滤波与异常判定

湿度信号的噪声主要来自风扇气流扰动和传感器自身测量误差。我用了10点滑动平均,相当于给信号做了一个低通滤波。另外还加了一个最简单的毛刺剔除逻辑:如果本次采样值相对上次变化超过±10%RH,就认为是异常值,丢掉并重新采样。这两个函数加起来不到二十行,但对控制稳定性的提升非常明显。

通信类传感器还有一个很重要的问题:I2C读取可能失败。我处理的方式是连续读取3次,3次都失败就进入故障状态并点亮指示灯,控制逻辑保持上一次状态,不让设备在传感器异常的情况下把所有负载都关掉或开着。主循环里的任何一次传感器读取都不能死等,要加超时,否则一个传感器异常会让整个系统卡死。

3.3 按键状态机与显示界面

设备有三种模式:自动模式走滞回控制,手动模式强制开关,定时模式运行指定时间后自动切换回自动模式。我用一个简单的状态机来管理,每个状态对应一个处理函数,状态迁移集中在一个函数里。这种写法虽然基础,但它有一个明显的好处:以后要加新功能,比如联网、定时预约,不会把代码改成一锅粥。

显示部分我用了一块0.96寸OLED,I2C接口,只占两个IO。界面上显示当前湿度、当前温度、运行状态和模式。OLED驱动代码网上非常多,我的工程里也带了一份精简版,方便二次修改。按键我额外做了去抖,按下后延时20ms再读,确认是稳定电平才进入事件处理。

3.4 看门狗与低功耗

除湿器往往在无人的柜子里长时间运行,程序一旦跑飞,最好的情况是设备傻掉,最坏的情况是负载一直开着把柜子烘到过热。我开启了独立看门狗(IWDG),主循环正常轮询时喂狗,程序卡死超过约1秒就强制复位。

如果做电池供电的便携版,需要用到STM32的STOP模式。基本思路是:设备休眠,RTC或低功耗定时器定时唤醒,醒来读一次湿度,高于阈值就开机运行一段时间,然后继续睡。这部分代码我只在开发板上验证过,实测下来,在除湿器这种低频采集场景,续航比一直跑满主频的版本要长得多。

4. 实机调试踩坑复盘:读数漂移、复位重启与通信失败

4.1 湿度读数越跑越高:位置问题,不是代码问题

第一次整机联调时,我遇到过这样的现象:刚上电湿度读数正常,大概20分钟后湿度一路涨到92%。我当时怀疑是传感器坏了,换了一只仍然如此。后来把传感器移开,发现它正对着半导体制冷片的出风口——冷端凝结的水汽直接吹到传感器上,读取的当然是"水里湿度"。把传感器位置改到侧面进风口之后,读数就稳了。

这件事给我的经验是:出现持续读数异常,先检查物理环境,再查电路,最后才查代码。反过来排查会浪费很多时间。

4.2 联调时电源电压跌落:不要只看MCU这边

另一处坑出现在电源上。我用一个12V适配器供电,通过MP1584降压到5V,再经AMS1117降到3.3V给MCU。实测发现,除湿片一启动,3.3V就跟着波动,严重时OLED直接白屏重启。

排查过程是这样的:第一步,用万用表量12V输入,发现带载时从12.2V掉到了10.8V,说明适配器余量不足;第二步,换一个2A输出的适配器后,12V稳定了,但3.3V还是有小幅波动;第三步,示波器看5V节点,发现MP1584输出的纹波叠加了继电器动作的尖峰。最终在5V输出端加了大容量电解电容,3.3V的AMS1117前后各加0.1µF和10µF电容,情况才彻底解决。

这个案例说明,除湿器这种同时有数字电路和感性负载的项目,电源余量一定要留够,至少是峰值负载的1.5倍。

4.3 I2C偶发卡死与SHT30配置寄存器

SHT30的I2C通信偶发失败,是我在所有问题里查得最久的一个。现象是大约运行一两个小时后,主循环偶尔卡在传感器读取上。代码上我已经加了超时,所以不是死等,但显示会短暂定格几百毫秒,体验很差。

排查链路:先用逻辑分析仪抓波形,发现SCL和SDA有的数据包会多出一个小毛刺;把传感器和MCU之间的杜邦线换成一字排开的短排线后,毛刺减少,但偶尔还是会出错。再查SHT30的数据手册,发现它有内置加热功能,配置寄存器里有一个加热位;如果程序在初始化时误写或芯片内部状态发生跳变,加热功能打开会产生额外热量,不仅读数异常,也可能导致通信不稳定。我在初始化代码里显式写了一次配置寄存器,把加热位清零让芯片进入正常测量模式,问题没有再复现。

4.4 下载失败与ST-Link的连接坑

最后说一个几乎每个人都会遇到的:ST-Link下载时报 "no stm32 target found"。最常见的原因有三个:SWDIO、SWCLK、GND、3.3V四根线没接对;目标板没有独立供电;或者程序里把SWD引脚复用成了普通GPIO,导致芯片被程序"锁死"。

第三个坑处理起来最阴间。解决办法是按住板子上的复位键不放,点击下载按钮,在下载器开始连接的瞬间松开复位键,让MCU以默认模式被连接上,然后把程序擦掉。如果连这招都不行,就只能用串口ISP把芯片擦除,或者把Boot0拉高重新上电再擦。这个坑我在不止一块开发板上踩过,每次都能折腾半小时。

还有一类问题是USB虚拟串口驱动显示叹号,大概率是CH340或CP2102的驱动版本不对,去官网装最新版驱动就能解决,别在第三方驱动站瞎下载。

5. 源码组织与二次开发:怎么把这个项目改造成你自己的

5.1 把工程分层,换板子才不会想哭

我见过太多人把所有代码堆在main.c里,最后改一个引脚要翻半天。这个项目我按三层来组织:bsp层管芯片初始化,driver层管设备驱动,app层管控制逻辑和状态机。这样换一块STM32型号,只需要改bsp层;换一个传感器型号,只需要改driver层;不管你换什么硬件,只要driver接口不变,app层的滞回控制逻辑一行都不用动。

工程目录大致是这样:

Project/ ├─ bsp/ │ ├─ bsp_clock.c │ ├─ bsp_gpio.c │ └─ bsp_timer.c ├─ driver/ │ ├─ sensor_sht30.c │ ├─ actor_relay.c │ ├─ actor_fan.c │ └─ display_oled.c ├─ app/ │ ├─ control.c │ ├─ state_machine.c │ └─ ui_task.c ├─ main.c └─ main.h

调用关系在main里很直观:

int main(void) { bsp_init(); driver_init(); control_init(); while (1) { sensor_task(); control_task(); ui_task(); watchdog_feed(); } }

实际项目里,sensor_task可以放在定时器中断标志里做节拍控制,比如每500ms采集一次、每100ms刷一次OLED。这个节奏不需要太快,湿度是一个慢变量,没必要用毫秒级轮询消耗CPU。

5.2 把除湿器改成你自己的:四个扩展方向

做完基础版之后,想继续深入的话,我有几个建议的方向。

第一,加ESP8266或ESP32模块,通过串口或I2C对接,湿度数据上报到服务器,手机远程查看并控制开关。这个方向能一下子把它从"单片机课设"拉到"物联网产品"的层次,毕设的输出也更漂亮。

第二,加冷凝水满检测。半导体除湿器会有集水箱,放一个浮球开关或红外液位传感器,水满之后蜂鸣器报警,同时停止除湿,防止溢水。这个功能简单,但非常实用。

第三,风扇调速。湿度高时全速运行,接近目标湿度时低速运行,降低噪音和功耗。用STM32的PWM输出控制MOS管驱动风扇就行,和继电器方案比,控制更细腻。

第四,按键改成旋钮编码器,或者换成触摸屏界面。数据显示可以再加上历史湿度曲线,配合Flash或外部EEPROM存储,做成一个小数据记录仪。

你不需要把所有扩展都做完,挑一两个感兴趣的,或者根据自己毕设课题的方向选一个即可。

最后再分享一点个人体会:这个项目我在不同阶段做出来过两版,第一版是为了演示功能,第二版是为了追求稳定。第一版能跑但各种小问题不断,第二版把传感器位置、电源去耦、软件滤波这些细节全部补齐之后,整机才能放在柜子里连续运行一星期不用管。做嵌入式项目,"能工作"和"能长期工作"是两回事,这篇文章里记录的细节,前一个是门槛,后一个才是真正的分水岭。如果你照着源码把基础版跑通了,我强烈建议你再花点时间把上面这些坑自己复现一遍,踩一次坑比看十篇教程都管用。源码里的关键函数我已经贴出来了,完整的工程目录结构也给了,剩下的就是动手。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 2:33:40

数模国赛提交前必看:AI结构化自查的六大维度与26项细节

每年到了数模国赛提交前的那几个小时&#xff0c;实验室和宿舍里总会弥漫同一种焦虑&#xff1a;论文看了一眼又一眼&#xff0c;总觉得哪里不对&#xff0c;但又说不出具体问题在哪。格式对不对&#xff1f;摘要有没有踩中评分点&#xff1f;附录代码里面有没有残留自己的路径…

作者头像 李华
网站建设 2026/9/9 2:32:25

MODBUS RTU调试实战:从STM32移植到工业现场排错

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 2:30:43

MongoDB GridFS 大文件存储实战:分块原理、断点续传与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 2:30:26

30分钟掌握AI编程:工具选择、提示词技巧与实战全攻略

“30分钟可以掌握的AI编程&#xff1f;”这个标题&#xff0c;我第一眼看到就想说&#xff1a;可以&#xff0c;但别把“掌握”想得太玄。你要是以为半小时就能变成编程大神&#xff0c;那是做梦&#xff1b;但你要是想在半小时内用AI写出一个能跑的小工具&#xff0c;或者真正…

作者头像 李华
网站建设 2026/9/9 2:30:00

研发生产一体化规划:PLM、ERP、MES协同与BOM数据链路

1. 为什么研发和生产总是“两张皮”&#xff1a;一体化规划要解决的现实问题做制造业数字化这行久了&#xff0c;你会发现一个特别普遍的现象&#xff1a;很多企业上了ERP&#xff0c;后来又上了PLM&#xff0c;甚至MES也上了&#xff0c;但研发部门和生产车间之间&#xff0c;…

作者头像 李华
网站建设 2026/9/9 2:28:27

PGA2310/PGA2311单片机音量控制程序详解与调试指南

简介&#xff1a;PGA2310/PGA2311单片机控制程序是一份可直接参考的嵌入式增益控制源码&#xff0c;面向音频设备、信号调理和数据采集系统开发者。程序演示了通过SPI接口配置PGA2311/CS3310实现多级音量与增益调节的方法&#xff0c;适合具备C语言和基础单片机知识的学习者上手…

作者头像 李华