文章目录
这是一套完整的实战系列:用 STM32F411RET6 + HAL 库 + ESP-12F,从空工程一路做到"网页能看数据、能控硬件"的智能家居。本文是第一篇,只讲一件事------动手前把项目想清楚。
适合人群:学过一点 C 语言、装过 Keil,但还没独立做过一个完整 STM32 工程的同学。
一、为什么第一篇不写代码
我一开始做这个项目的时候,犯了一个很典型的错误:上来就找例程,把 DHT11、PWM、串口的代码一段段抄进 main.c,然后烧录、看串口、没反应,再换一段代码继续抄。
结果一周过去,板子上的风扇偶尔转一下,串口偶尔打印一行乱码,我甚至说不清是接线错了、时钟配错了,还是程序根本没跑到那一行。
后来我把代码全删了,先在一张纸上画清楚三件事:
- 这块板子最终要能干什么;
- 每个模块接在哪个引脚上;
- 数据从哪来、到哪去。
画完之后再写代码,之前那些"玄学问题"大部分都变成了能一句话解释的普通问题。
所以这个系列的第一篇不写一行代码。项目总览不是凑字数,它决定了后面几百行代码往哪儿放。
二、这个项目最终能做什么
一句话概括:
一块 STM32 板子,能测温度湿度和空气质量,能按键手动开关风扇、加热、窗帘,能按温度自动控制,还能用手机蓝牙或网页远程控制。
把它拆成 5 个可以独立完成、独立验证的小功能,做完一个再做一个:
| 编号 | 功能 | 怎么触发 | 应该看到什么现象 |
|---|---|---|---|
| 功能 1 | 按键打印环境数据 | 按任意键(key1) | 电脑串口助手打印温度、湿度、空气质量 |
| 功能 2 | 自动控制 | 进入自动模式(key3) | 温度高就开风扇并拉开窗帘;温度低就加热并关窗帘;空气差就通风 |
| 功能 3 | 手动控制 | 进入手动模式(系统默认)(key2) | KEY1 控制风扇、KEY3 控制窗帘、KEY4 控制加热,各自开关 |
| 功能 4 | 蓝牙远程 | 进入远程模式(默认蓝牙)(首先按下key2退出手动模式再按下key4) | 手机发 FAN_ON 等字符串,设备执行并原样回显 |
| 功能 5 | 网页远程(MQTT) | 远程模式下再按一次 key4 | 浏览器上能看到温湿度和空气质量,点按钮能控制设备 |
这 5 个功能不是并列关系,而是层层叠加:功能 1 验证了传感器和串口,功能 2、3 验证了执行器和状态机,功能 4 验证了串口收发,功能 5 才轮到网络。
顺序一旦颠倒,排查就会变成玄学。 比如 MQTT 连不上时,你根本无法判断是 WiFi 问题、ESP 问题,还是前面的传感器把主循环卡死了。
三、系统框图:一块板子连了哪些东西
先看整机的连接关系(后面每一章都会回到这张图):
text
┌──────────────┐
DHT11 ──PB1──▶│ │──PA6(TIM3_CH1)──▶ 风扇
│ │──PA7(TIM3_CH2)──▶ 加热片
ENS160 ─I2C3─▶ │ STM32F411RET6│──PA0(TIM5_CH1)──▶ SG90 舵机(窗帘)
(PA8/PC9) │ │
│ │──PA9/PA10──▶ USB转TTL ──▶ 电脑串口助手(调试日志)
KEY1~KEY4 ───▶│ │
(PC2/PC3/PA1/ │ │──PA2/PA3──┬─ 拨码开关 ── HC-06 蓝牙(9600)
PB10) └──────────────┘ └─ ESP-12F WiFi(115200)──▶ broker.emqx.io
│
H5 网页 ◀── wss
可以看到,STM32 是绝对的中心:
- 输入:DHT11(温湿度)、ENS160(空气质量)、4 个按键;
- 输出:风扇、加热片、舵机(模拟窗帘)、调试串口;
- 通信:USART1 专用于调试打印,USART2 分时复用给蓝牙或 ESP-12F。
这里有一个容易被忽略的点:PA2/PA3 (USART2)只有一组,却要接两个模块。 所以必须用拨码开关做硬件二选一,软件再配合切换波特率。这是整个项目最难的部分,后面会用一整章来讲。
四、三条数据链路
项目中所有数据流动,其实只有三条链路。把这三条记住,看代码就不会迷路。
| 链路 | 物理路径 | 用途 | 关键点 |
|---|---|---|---|
| 调试链路 | printf → USART1(PA9) → USB 转 TTL → 电脑 |
看日志、定位问题 | 全程 115200,从头到尾都不改 |
| 蓝牙链路 | 手机/小程序 → HC-06(蓝牙模块) → USART2(PA2/PA3) → STM32 | 近距离发命令 | HC-06 默认 9600 |
| 网络链路 | H5 网页 ⇄ wss://broker.emqx.io:8084/mqtt ⇄ broker.emqx.io:1883 ⇄ ESP-12F ⇄ USART2 → STM32 |
远程看数据、控设备 | ESP-AT 默认 115200 |
其中第 2、3 条共用 USART2,靠"硬件拨码开关 + 软件切波特率"分时复用。
还有一个很实用的结论,建议现在就记住:
串口日志是唯一可信的"真相",网页只是"展示"。
网页显示"已连接",只代表浏览器连上了 broker,不代表命令到了单片机。排查问题永远先看串口。
五、硬件清单与采购避坑
| 器件 | 数量 | 说明 |
|---|---|---|
| STM32F411RET6 核心板 | 1 | 板载 HSE 25MHz 晶振、ST-Link 接口 |
| 扩展板(智能家居底板) | 1 | 风扇、加热、舵机、按键、DHT11 已焊在上面 |
| ENS160 空气质量模块 | 1 | I2C 接口,3.3V 供电 |
| HC-06(或 HC-05)蓝牙模块 | 1 | 默认 9600 8N1 |
| ESP-12F / ESP8266 模块 | 1 | 烧 ESP-AT 固件,默认 115200 |
| USB 转 TTL(CH340/CP2102) | 1 | 接 USART1 看日志 |
| ST-Link V2 | 1 | 烧录与调试 |
| 5V 电源 | 1 | 舵机建议单独 5V 供电 |
| 杜邦线、拨码开关 | 若干 | 拨码开关用于 USART2 二选一 |
采购和接线时有三个坑,几乎每个新手都会踩:
- ESP-12F 不能用 USB 转 TTL 的 3.3V 供电。 它的瞬时电流能到几百毫安,而下载器那点电流根本带不动,现象就是日志里反复打印
ready(模块不停重启)。正确做法是给它一路稳定的 3.3V,电流能力至少 500mA。 - SG90 舵机要独立 5V 供电。 舵机启动瞬间电流很大,直接吃板子的 3.3V 会把电压拉低,轻则舵机乱抖,重则 STM32 直接复位。
- 所有模块必须共地。 DHT11、ENS160、蓝牙、ESP-12F、USB 转 TTL 的 GND 都要和 STM32 的 GND 连在一起。不共地最典型的现象是:串口能发不能收,或者收到的全是乱码。
六、软件清单
| 软件 | 用途 | 备注 |
|---|---|---|
| STM32CubeMX 6.x | 生成初始化代码 | 需要安装 STM32F4 固件包 |
| Keil MDK5 + STM32F4xx DFP | 编译、烧录 | 记得勾选 Use MicroLIB |
| STM32CubeProgrammer / ST-Link 驱动 | 下载程序 | Keil 里也能直接下载 |
| 串口助手(SSCOM / XCOM) | 看日志 | 115200 8N1,不要勾"十六进制显示" |
| Chrome / Edge | 打开 H5 页面 | 需要支持 WebSocket |
| Python 3(可选) | 起本地静态服务器 | python -m http.server 8000 |
关于 Keil 的 Use MicroLIB ,这里单独提醒一句:不勾选它,printf 很可能一个字符都打印不出来,或者程序卡在重定向函数里。很多人以为是自己串口配置错了,其实是这个勾没打。
七、推荐的推进顺序
这是整篇文章最值钱的一条建议:
text
CubeMX 建工程 → 串口打印 → DHT11 → ENS160 → PWM 三件套
→ 按键 + 三模式 → 蓝牙 → MQTT(ESP-AT) → H5 → 整机联调
每一步都必须单独验证通过,才允许进入下一步。
原因很简单:这个项目后面 90% 的"疑难问题",都是"上一步没通就开始写下一步"造成的。比如传感器读取偶尔失败,你直接去调 MQTT,最后看到的就是"网页数据时有时无",你会以为是网络问题,实际上是 DHT11 的时序被风扇干扰了。
分层验证的本质,是让每一层都有独立、可观察的现象:
- 串口能打印 → 说明时钟、下载、串口都对了;
- 串口能打印出温湿度 → 说明 GPIO 和单总线时序对了;
- 按键能打印 → 说明中断和消抖对了;
- 手机发
FAN_ON风扇转 → 说明 USART2 接收和命令解析对了; - 网页能看到数据 → 说明 ESP-AT、WiFi、MQTT 全通了。
只要任何一层没有现象,就停在这一层。不要带着问题往上叠。
八、本章易错点总结
| 现象 | 真正原因 | 正确做法 |
|---|---|---|
| 程序在跑,但串口一个字都没有 | 把 USART1(PA9/PA10)和 USART2(PA2/PA3)搞混了 | 调试口只接 PA9/PA10,蓝牙/WiFi 才接 PA2/PA3 |
| 蓝牙和 WiFi 同时接上后,数据随机乱码 | 两个模块的 TX 同时驱动 PA3,电平对打 | 用拨码开关二选一,绝不能同时接 |
| 网页数据时有时无,越调越乱 | 基础层(DHT11/按键)没验证就直接上 MQTT | 按推进顺序逐层验收,下层不通不往上做 |
| 舵机一转,整块板子就复位 | 舵机用板子的 3.3V 供电,启动电流拉低电压 | 舵机用独立 5V,并且与板子共地 |
| 串口收到的全是乱码或空数据 | 模块之间没有共地,或 TX/RX 没有交叉 | 所有 GND 连在一起;MCU 的 TX 接模块的 RX |
printf 完全没输出 |
Keil 没勾 Use MicroLIB | Options for Target → Target → 勾选 Use MicroLIB |
九、小结与下一篇
这篇没有代码,但把后面所有代码的"位置"都定下来了:
- 项目由 5 个可独立验证的功能组成,必须按顺序做;
- STM32 是中心,输入是传感器和按键,输出是 PWM 和串口;
- 全机只有三条数据链路,其中蓝牙和 WiFi 共用 USART2;
- 串口日志是唯一可信的真相,网页只是展示。
下一篇进入实操:从零安装 Keil、CubeMX、ST-Link 驱动和串口助手,把开发环境一次配好,并且把"工程目录怎么放、哪些代码能改、哪些不能改"这条纪律讲清楚。
如果这篇文章对你有帮助,欢迎点赞收藏。系列更新中,下一篇见。