STM32 从 0 到 1 做智能家居(二):把开发环境一次配好

文章目录

系列第二篇。上一篇把"要做什么、模块怎么连、数据怎么流"定下来了;这一篇把写代码之前的工具链全部装好,并且立下一条贯穿全项目的纪律。

适合人群:已经想清楚项目结构,准备真正打开 Keil 动手的同学。

一、环境没配好,后面每一步都在还债

我做第一个 STM32 项目时,最崩溃的不是代码写不出来,而是根本不知道问题出在哪一层:

  • 烧录失败,是 ST-Link 驱动没装,还是芯片没识别?
  • 编译报错,是缺固件包,还是路径里有中文?
  • 串口没打印,是波特率错了,还是 printf 重定向没生效?

这三类问题,只要环境本身是干净的,都能在几分钟内定位。但如果环境带着毛病,你就会在"写代码"和"修环境"之间反复横跳,最后连自己改了什么都不知道。

所以这一篇的目标很明确:装完、配完、验证完,一个都不留到后面。

装完之后你应该达到这个状态:

检查项 达标标准
Keil 能新建工程并选到 STM32F411RETx
固件包 Pack Installer 里 Keil::STM32F4xx_DFP 已安装
CubeMX 能生成 F4 系列工程,且固件包版本确定
ST-Link Keil 的 Debug 设置里能读到芯片 IDCODE
串口助手 115200 8N1 能收到板子打印的文本
H5 本地 http://localhost:8000 能打开页面

二、安装 Keil MDK5

  1. 安装 Keil MDK 5.36 及以上。

  2. 安装路径必须是纯英文、无空格 ,例如 D:\Keil_v5。

    这一点别嫌麻烦。路径里带中文或空格,轻则编译报奇怪的错误,重则链接阶段直接失败,而且报错信息完全指不到真正原因。

  3. 打开 Keil → 点工具栏的 Pack Installer → 搜索 STM32F4 → 安装 Keil::STM32F4xx_DFP。

    DFP 就是"器件支持包"。没有它,Keil 根本不认识 STM32F411 这颗芯片,新建工程时设备列表里是空的。

  4. 验证:Options for Target → Device 里能选到 STM32F411RETx,才算真的装好。

小提醒:Pack Installer 下载慢是常态,可以挂着去装 CubeMX,不用干等。

三、安装 STM32CubeMX

  1. 安装 CubeMX 6.x,同样放英文路径。
  2. 首次启动 → Help → Manage embedded software packages → 安装 STM32F4 固件包,建议 1.27.x 或 1.28.x。
  3. 把固件包版本记下来。

为什么一定要记版本?因为 CubeMX 生成的 Keil 工程会引用这个固件包路径,版本对不上时,换一台电脑打开工程就可能满屏红叉。团队协作时这一步尤其重要。

  1. 插上 ST-Link,打开设备管理器,出现 STMicroelectronics STLink dongle 就说明驱动正常。
  2. Keil 里配置:Options for Target → Debug 选 ST-Link Debugger → 点 Settings。
  3. 在 SW Device 区域能看到一列 IDCODE,才说明电脑真正连上了芯片。

如果这里显示 No target connected,先别怀疑程序,按顺序查:

  • 板子有没有供电(只插 ST-Link 不一定给板子供电);
  • SWDIO / SWCLK / GND 三根线是否接对;
  • 芯片是否处于复位或低功耗状态(按住复位再点连接试试)。

五、串口驱动与串口助手

串口助手是我们后面调试的"眼睛"。但在打开它之前,得先让电脑"看见"这个串口------没有 COM 口,串口助手装得再好也白搭。

5.1 安装 USB 转 TTL 驱动

STM32 输出的是 TTL 电平,电脑只认 USB,中间靠一块 USB 转 TTL 模块(常见芯片 CH340、CP2102、FT232)做转换。这个模块需要驱动。

第一步:确认你手上模块的芯片型号。

模块背面或芯片丝印上一般能直接看到:

芯片 常见丝印 驱动来源
CH340 / CH341 CH340G、CH340C 沁恒官网 CH341SER.EXE
CP2102 / CP2104 CP2102 Silicon Labs CP210x VCP Driver
FT232 FT232RL FTDI 官网 VCP 驱动

第二步:装驱动。

  • 优先用芯片厂商官网的驱动,别用来路不明的"万能串口驱动",这类驱动经常版本老旧,装上反而频繁蓝屏。
  • Windows 10/11 有时会通过 Windows Update 自动装好,插上就有 COM 口,那就什么都不用做。
  • CH340 的安装包右键 以管理员身份运行,装完建议重启一次。

第三步:验证。

  1. 插上 USB 转 TTL(先别接 STM32,排除接线干扰);

  2. 右键"此电脑" → 管理 → 设备管理器;

  3. 展开 端口 (COM 和 LPT),应该出现类似:

    text 复制代码
    USB-SERIAL CH340 (COM6)
  4. 记住这个 COM 号,串口助手打开时要选它。

如果看不到这一项,或者出现一个带黄色感叹号的未知设备,按下面顺序排查:

现象 原因 处理
完全没有任何新设备 USB 线是"只充电"线,没有数据线芯 换一根确定能传数据的线
黄色感叹号 / 未知设备 驱动没装或装错型号 卸载设备,重装对应芯片驱动
有 COM 口但打不开 被其他软件占用(另一个串口助手、Keil 的串口窗口) 关掉占用它的软件再打开
端口号是 COM10 以上,助手列表里没有 部分老版本串口助手只枚举 COM1~COM9 设备管理器 → 端口属性 → 端口设置 → 高级 → 改成 COM3 之类
换了个 USB 口,COM 号变了 Windows 按"设备+端口"分配号 正常现象,重新在助手里选新号

还有一个新手常忽略的点:USB 转 TTL 必须和 STM32 共地 ,并且接线要交叉------模块的 RX 接 STM32 的 TX(PA9) ,模块的 TX 接 STM32 的 RX(PA10)。接反的典型现象是:能发不能收,或者干脆一片空白。

5.2 串口助手参数

驱动装好、COM 口出现之后,打开串口助手,参数必须固定:

参数 值
端口 设备管理器里看到的 COM 号
波特率 115200
数据位 8
停止位 1
校验 无
流控 无

5.3 两个细节

  1. 接收区不要勾"十六进制显示"。 我们要看的是 [MODE] Manual ... 这种文本日志,勾了十六进制就只剩一串 5B 4D 4F 44 45 5D,没法读。
  2. 编码选 UTF-8 或 GBK 都行。本项目的 printf 全部是纯 ASCII,所以不会出现中文乱码问题。

六、本地起一个网页服务(H5)

后面的 H5 页面用了 mqtt.js 的 CDN 和 wss 连接。直接双击 index.html(也就是 file:// 协议)有时会被浏览器的安全策略拦住,表现为页面能开、但 MQTT 一直连不上。

推荐用 Python 起一个本地静态服务器:

powershell 复制代码
cd "d:\IOT_Experiment\ZLRC_Experiment\STM32_SCH_project\project\8.HAL_SmartHome\3.H5界面\4班智能家居"
python -m http.server 8000

然后浏览器打开:

text 复制代码
http://localhost:8000

这样页面就走 http:// 协议,WebSocket 和 CDN 都不会被限制。

页面改完记得按 Ctrl + F5 硬刷新。浏览器缓存非常顽固,"代码改了但页面没变"十有八九是缓存,不是代码。

七、最重要的一条纪律:只写 USER CODE

这一节比前面所有安装步骤都重要,因为它是唯一一个会让你白干几小时的坑。

CubeMX 生成的 .c/.h 文件里,到处是这种成对出现的标记:

c 复制代码
/* USER CODE BEGIN 2 */
  // 你的代码写这里
/* USER CODE END 2 */

规则只有一条:

位置 点 GENERATE CODE 之后
两个标记中间 保留你的代码
两个标记外面 直接覆盖,写了也会丢

我第一次踩这个坑时,在 main.c 的 while(1) 外面加了一整段初始化代码,调通之后回 CubeMX 改了一个引脚,再点生成------那段代码连同当时的调试思路一起消失了。更痛苦的是,我一开始还以为是 Keil 工程坏了。

所以请从现在开始养成习惯:

  1. 所有人工代码,只写在 USER CODE BEGIN/END 之间;
  2. 每次点 GENERATE CODE 之前,先确认没有代码写在标记外面;
  3. 生成后先编译一次,确认没有丢东西再继续。

自己新增的文件放哪里

除了改生成代码,我们还要写三个自己的驱动模块:

text 复制代码
HAL_SmartHome\
└─ App\
   ├─ DHT11.c / DHT11.h     温湿度(单总线)
   ├─ ens160.c / ens160.h   空气质量(I2C)
   └─ mqtt.c / mqtt.h       ESP-AT + MQTT

放在 App\ 目录下有两个好处:

  • CubeMX 不管这个目录,所以怎么改都不会被覆盖;
  • 结构清晰,和生成代码彻底分开,出问题一眼就知道该看哪边。

但要注意:文件放进文件夹 ≠ 加入工程 。而且 .c 和 .h 的处理方式完全不同,这一步必须分开做。

7.1 .c 文件:加进 Keil 工程组

.c 文件里是真正的函数实现,必须参与编译。做法:

  1. 在 Keil 左侧工程树里右键 Target 1 → Manage Project Items;
  2. 在 Groups 里新建一个组,命名为 App;
  3. 选中 App 组,点右侧 Add Files ,把 DHT11.c、ens160.c、mqtt.c 三个文件加进去;
  4. 点 OK 保存。

只放文件夹不加工程,编译时不会报错,但链接时会报:

text 复制代码
L6218E: Undefined symbol ReadData (referred from main.o)

看到这个错误,第一反应就应该是".c 没加进 Keil 工程"。

7.2 .h 文件:靠 Include Paths,不靠 Add Files

.h 文件里只有函数声明、宏定义和类型定义,它不参与编译,不需要(也不应该)加进 App 组去编译。编译器找头文件靠的是"搜索路径",不是"工程文件列表"。

所以真正要做的是告诉 Keil:App 这个目录也要去搜。做法:

  1. 点魔术棒 Options for Target → 切到 C/C++ 选项卡;
  2. 找到 Include Paths ,点右边的 ...;
  3. 新增一行,填 ..\App(相对于 .uvprojx 所在目录);
  4. 确定保存,然后重新编译。

..\App 是相对路径,工程整体挪到别的电脑上也不会失效;用绝对路径 D:\...\App 换台电脑就会找不到。

验证方法很简单:在 main.c 的 USER CODE BEGIN Includes 里写

c 复制代码
#include "DHT11.h"

编译。如果报下面的错误,就是 Include Paths 没加对:

text 复制代码
error: cannot open source input file "DHT11.h"

如果编译通过,说明头文件已经能被正确找到。

可以在 Manage Project Items 里顺手把 .h 也 Add 进 App 组,这样工程树里能直接双击打开、方便查看。但要清楚:它只是"显示在树里",并不解决"找不到头文件"的问题,Include Paths 该加还得加。

7.3 顺带说清 .c 和 .h 的分工

文件 放什么 是否需要加入工程
DHT11.c 函数实现、私有变量 必须 Add Files 到 App 组
DHT11.h 函数声明、宏、extern 声明 不需要,但要加进 Include Paths
main.c 顶部 #include "DHT11.h" 已有文件,无需操作

头文件里记得加"防重复包含"保护,否则多个 .c 互相包含时会报重复定义:

c 复制代码
#ifndef __DHT11_H
#define __DHT11_H

/* 声明写这里 */

#endif

八、装完先做一次冒烟测试

环境全部装好后,不要急着写传感器代码。先做一个最小的"冒烟测试":

  1. 用 CubeMX 新建一个 F411 工程,只开 USART1;

  2. 生成代码,Keil 里勾上 Use MicroLIB;

  3. 在 main() 的 while(1) 里加一句:

    c 复制代码
    printf("hello stm32\r\n");
    HAL_Delay(1000);
  4. 编译、烧录、打开串口助手(115200)。

如果每秒能看到一行 hello stm32,说明这几件事同时成立了:

  • 时钟配置正确(否则波特率会偏,收到乱码);
  • 下载链路正常;
  • 串口助手参数正确;
  • printf 重定向和 MicroLIB 都生效了。

这一步通过,后面的所有调试才有"可信的观察窗口"。

九、本章易错点总结

现象 真正原因 正确做法
编译或链接报莫名其妙的错误 Keil 装在带中文或空格的路径下 装到 D:\Keil_v5 这类纯英文无空格路径
新建工程时找不到 STM32F411RETx 没装 Keil::STM32F4xx_DFP Pack Installer 里安装 DFP 后再新建
串口全是乱码,或完全没输出 波特率不是 115200,或 printf 没重定向 串口助手固定 115200 8N1;重定向到 USART1
printf 有代码但一个字符都不出 Keil 没勾 Use MicroLIB Options for Target → Target → Use MicroLIB
改了一次引脚,之前写的代码全没了 代码写在 USER CODE 标记外面 只写在 BEGIN/END 之间,生成前检查一遍
编译通过但链接报 L6218E Undefined symbol 新增的 .c 只放进文件夹,没加进 Keil 工程 Manage Project Items 里 Add Files
H5 页面能打开但 MQTT 连不上 用 file:// 直接双击打开的 用 python -m http.server 8000 起本地服务
改了 H5 代码但页面没变化 浏览器缓存 按 Ctrl + F5 硬刷新

十、小结与下一篇

这一篇做完,工具链已经齐了,而且验证过:

  • Keil 能识别 F411,DFP 已装;
  • CubeMX 能生成工程,固件包版本已记录;
  • ST-Link 能读到芯片,串口助手能收到文本;
  • H5 能用本地服务器打开;
  • 最重要的:所有代码只写在 USER CODE 里,自己的驱动统一放 App\。

下一篇开始动硬件:电源与共地怎么接、每个模块接哪个引脚、拨码开关怎么做 USART2 二选一,以及上电前的自检清单。接线是后面所有问题的源头,值得单独用一篇讲透。

如果这篇文章对你有帮助,欢迎点赞收藏。系列更新中,下一篇见。

相关推荐
zhangzhangkeji3 小时前
stm32, HAL 库,PVD 与低功耗:
stm32
创界工坊工作室4 小时前
50-基AT89C51的自动窗帘控制系统的设计
stm32·单片机·嵌入式硬件·51单片机·proteus
新晨单片机设计4 小时前
S030D-WIFI空气净化器(温湿度、甲醛、空气质量)【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·空气净化器
Zw-awa5 小时前
一只按键不只“按下”:短按、长按和连按如何共存
stm32
笨笨饿5 小时前
#143_屏幕画撕裂的问题及解决方法
linux·stm32·单片机·嵌入式硬件·mcu·lvgl·嵌入式实时数据库
_YouziTech_5 小时前
【STM32+MAX98357】MP3转PCM存入Flash并控制音频输出
stm32·单片机·音视频·内存·pcm·i2s·wav
沐欣工作室_lvyiyi5 小时前
基于STM32的老人跌倒与防走失报警系统设计与实现(论文+源码)
stm32·单片机·嵌入式硬件
沐欣工作室_lvyiyi6 小时前
基于STM32的人体健康检测设计(论文+源码)
stm32·单片机·嵌入式硬件
艾络迅Acceleronix6 小时前
气象监测:STM32+EG800Z AT + 艾络迅平台实战|气压/光照/雨量采集全流程
stm32·单片机·嵌入式硬件·mcu·物联网·1024程序员节