1. 为什么我劝你从Keil烧录里“跳出来”
做STM32开发的人,十有八九是从Keil MDK入的门。工程编译、下载调试、断点查看,一条龙服务确实省心。但说句实话,Keil的调试下载功能虽然好用,日常开发也确实离不开它,但“烧录”这个环节,Keil真的不是最优解。
我见过太多刚入门的朋友,手里拿着一块STM32最小系统板,没有ST-Link,只有一个USB转TTL的CH340模块,结果在Keil里点了半天Download,提示找不到目标设备,当场就懵了。还有人项目做完了想发给朋友烧录试试,结果对方电脑上没装Keil,也没装驱动,只能干瞪眼。
这种情况下,FlyMCU串口烧录就是那个“救火队员”。它不用装庞大的IDE,不用买调试器,一根USB转TTL线加三个杜邦线,几十块钱的成本就能把程序烧进去。而且它操作极其简单,点两下鼠标就能完成烧录,对新入门的同学来说非常友好。
这篇东西我打算一次性讲透——
- 为什么串口烧录在某些场景下比ST-Link更方便
- FlyMCU从下载、接线到烧录的完整保姆级操作
- 它和ST-Link Utility到底有哪些实质性区别
- 我在实际使用中踩过的坑和排查经验
先说一下适合谁看:刚接触STM32、手头设备不齐全的新手;想给批量板子快速烧程序不想反复插拔调试器的工程师;以及所有对“到底该用哪种方式烧录”这个问题有困惑的人。
2. 为什么串口烧录在某些场景下比ST-Link更方便
很多人有个误区,觉得ST-Link是STM32调试的“标配”,串口烧录是个上不了台面的东西。这个看法其实片面了。
ST-Link这类调试器解决的核心问题是“调试”,比如在线打断点、单步运行、查看寄存器值。这些能力串口烧录确实做不到,也不该指望它做到。但如果你只是想把一个编译好的hex文件刷进芯片,“下载”这个动作本身,串口的体验反而更好。
核心原因有几个,都是我在项目里实际体会过的:
**第一,ST-Link烧录依赖目标芯片的SWD或JTAG引脚,而串口烧录只需要UART引脚配合BOOT0引脚。**某些板子设计比较特殊,SWD接口被复用了或者没引出来,这时候ST-Link根本没法接,但串口烧录完全不受影响。特别是买的一些廉价核心板,只留了串口引脚的情况太常见了。
**第二,批量烧录场景下串口效率更高。**我自己做过一个几十块板子的小批量项目,用ST-Link烧录就需要一块一块地插上、烧写、拔下来,反复插拔很容易磨损排针。用串口烧录的话,只要板子设计时留好了烧录接口,用线夹子一夹就能烧,来回切换很顺畅。
**第三,也是最重要的——串口烧录是STM32的“系统级后备方案”。**芯片原厂在设计STM32时就在系统存储器里固化了一段BootLoader,这段代码的职责就是通过串口接收数据并写入Flash。这意味着无论你用什么工具链,Keil也好、IAR也罢,哪怕是GCC裸开发,只要生成hex文件,FlyMCU就能通过这个内置的BootLoader完成烧录。它绕过了所有IDE层面的依赖,是芯片出厂自带的“保守疗法”,永远不会失效。
当然,串口烧录也有明显的短板。最突出的就是速度慢——串口波特率再高,和SWD的时钟频率也没法比。一个几百KB的程序,ST-Link一两秒就写完了,串口可能要等十几秒甚至更久。而且串口烧录无法调试,只能烧代码,不能打断点,不能看变量。
所以我的态度很明确:调试用ST-Link,纯烧录用FlyMCU,两者不是替代关系,是互补关系。谁要是想用串口烧录完全取代调试器,那是不现实的;但谁要是只会用Keil的Download按钮,那你的工具箱确实缺了一把好用的扳手。
3. FlyMCU烧录的完整实操流程
这一章我按实际的动手顺序来写,从软件准备到接线再到具体操作,每一步都写清楚为什么这么做,避免你照着做的时候踩到我当年踩过的坑。
3.1 软件准备:别去来路不明的网站下
FlyMCU的全名是Flies MCU ISP Programmer,是国内开发者黄某毅做的免费工具,原版作者官网大家搜一下都知道,但这里我强烈提醒几句。
先去确认你的USB转TTL模块是什么芯片。FlyMCU要工作,底层依赖的是USB串口驱动,而市面上常见的USB转TTL模块分两类:CH340和CP2102。CH340需要装CH340驱动,CP2102需要装CP210x驱动。很多人烧录失败,不是FlyMCU的问题,而是驱动没装上,设备管理器里根本看不到COM口。
验证驱动是否装好的办法很简单:把USB转TTL模块插到电脑上,打开设备管理器,展开“端口(COM和LPT)”,如果能看到一个类似USB-SERIAL CH340 (COM3)的条目,说明驱动正常。如果看到的是黄色感叹号,那就先解决驱动问题,否则后面全白搭。
装好驱动后,把FlyMCU下载下来解压,你会看到FlyMcu.exe这个主程序。注意,FlyMCU是个绿色软件,不需要安装,但首次使用建议右键以管理员身份运行,因为部分系统下它对串口的访问权限有要求,不升权限可能会报打开串口失败。
3.2 硬件接线:三个引脚的事,别搞反了
接线这块是翻车率最高的环节,尤其是新手。STM32串口烧录用的是USART1,对应芯片的PA9(TX)、PA10(RX)引脚。注意这个对应关系:
- STM32的PA9(TX) → USB转TTL模块的RXD
- STM32的PA10(RX) → USB转TTL模块的TXD
- STM32的GND → USB转TTL模块的GND
很多人死就死在“TX接TX,RX接RX”的直觉上,这是错的。串口通信是交叉接线的,你可以这样理解:我说你听,你说我听,所以我的嘴要对着你的耳朵,你的嘴要对着我的耳朵。把“嘴”理解成TX,“耳朵”理解成RX就永远不会接错。
除了这三根线,最关键的还有一根:BOOT0引脚的跳线帽。
STM32上电启动时,BOOT0引脚的电平决定了芯片从哪里启动。BOOT0拉低是从用户Flash启动,也就是正常运行你烧录进去的程序;BOOT0拉高是从系统存储器启动,也就是进入内置BootLoader模式。FlyMCU烧录的前提就是让芯片进入BootLoader模式,所以必须把BOOT0接3.3V高电平。
有些朋友用的是现成的开发板,板上一般会有BOOT0的跳线帽或者拨码开关,操作起来很方便。如果是自己画的最小系统板,就要在烧录前用杜邦线把BOOT0接到3.3V。烧完之后记得把BOOT0拉回来,否则芯片上电后又会进入BootLoader而不是执行你的程序。
还要注意一点:如果你板子上的PA9、PA10是接到了板载的USB转串口芯片上,比如CH340直接焊在板子上,那你就不用额外的USB转TTL模块了,直接用USB线连板子就行。这点看板子的设计决定,不是所有板子都一样。
3.3 生成hex文件:在Keil里只多一步操作
FlyMCU烧录的是hex文件,不是Keil工程编译出来的axf文件。所以第一步是在Keil里把输出格式改成生成hex。
操作路径是:Options for Target(点魔术棒)→Output选项卡 → 勾选Create HEX File。勾上之后,每次编译会在工程的Objects或Listings目录下生成同名的.hex文件,里面是Intel十六进制格式的烧录数据。
不要小看这一步,我见过不少人编译了半天,飞到FlyMCU里选文件,结果找不到hex,就是因为没勾这个选项。
3.4 FlyMCU里的关键参数设置
打开FlyMCU后,界面其实不算复杂,但有几个参数必须设置对,否则要么连不上,要么烧录到一半卡死。
串口选择:下拉框里选择你USB转TTL模块对应的那个COM口,必须和设备管理器里看到的端口号一致。如果你插了多个USB串口设备,不能确定是哪个,可以先拔掉再插上,看COM号哪个消失了就说明是哪个。
波特率:这个参数非常关键。FlyMCU默认的波特率如果是115200,一般不推荐改。如果你芯片的外部晶振频率不是标准的8MHz,可能会涉及波特率偏差的问题,这时候可以适当降低波特率,比如降到38400或者9600。实测下来,烧录稳定的优先级高于烧录速度,宁可慢一点,也别追求高波特率导致传输失败。
编程前擦除:默认是打勾的,保持打勾就行。每次烧录前会全片擦除一次Flash,避免旧数据残留影响新程序运行。如果你做的是OTA之类的增量升级,可能会考虑不擦除某些扇区,但那是进阶玩法,日常烧录保持默认即可。
校验:这个选项建议一定要勾。烧录完成后会读回Flash里的数据和hex文件做比对,万一烧录过程中有字节错误,能及时发现。
3.5 完整操作流程:从打开软件到烧录成功
设置都做好之后,完整流程是这样的:
- 给板子断电
- 把BOOT0跳线帽接到高电平(3.3V)
- USB转TTL模块插到电脑上,确保驱动正常
- 把USB转TTL的TXD、RXD、GND分别接到STM32的PA10、PA9、GND
- 在FlyMCU里选择正确的COM口和波特率
- 点“打开”按钮选择要烧录的hex文件
- 先点“开始编程”(有的版本叫“写入”),提示连接中
- 此时再给板子上电
这里有个容易搞反的时间点:“先点烧录,再上电”。因为FlyMCU是通过BOOT0高电平时系统存储器里的BootLoader来接收数据的,如果板子已经上电进入BootLoader状态了,它只会持续等待一小段时间,如果你烧录动作慢了,可能它就超时退出了。实际操作中,FlyMCU在发出连接请求后会等待目标板上电,所以步骤是先点烧录再上电。这个顺序是很多人第一次用串口烧录失败的常见原因。
- 上电后,FlyMCU的日志窗口会滚动显示连接信息、擦除信息、编程进度条,走到100%后会显示“校验成功”或类似字样
- 烧录完成后断电,把BOOT0跳线帽恢复为低电平
- 重新上电,程序就开始运行了
整个过程看起来步骤多,实际上熟练后十秒内就能完成整套动作。
4. ST-Link Utility是什么,和FlyMCU本质区别在哪
聊完了FlyMCU,再聊聊标题里提到的另一个角色:ST-Link Utility。很多新手容易把这两个概念搞混,觉得都是“烧录工具”,其实它们差别非常大。
4.1 ST-Link Utility的正确定位
ST-Link Utility是ST官方出的STM32烧录工具,全称是STM32 ST-LINK Utility。它的运行前提是你手里必须有ST-Link这个硬件调试器——就是那个长得像个U盘一样的下载器,可能是ST-Link/V2,也可能是兼容的国产版。
这个工具的核心价值有几点:
第一,它通过SWD(Serial Wire Debug)或者JTAG协议和芯片通信,这是ST-Link硬件支持的调试协议,不是串口那种UART通信。SWD协议只需要两根线加地线就能完成通信,分别是SWDIO和SWCLK,速度比UART快得多。
第二,它支持读Flash、写Flash、擦除Flash,还能查看芯片的Option Bytes配置。你在FlyMCU里想都不敢想的“读回芯片里已有程序”这个操作,ST-Link Utility能做到。这对分析二手板子、备份固件、检查位配置这些场景非常有用。
第三,它可以整片Flash导出成bin文件保存下来。所以ST-Link Utility不只是“烧录工具”,更是芯片底层维护工具。
4.2 两者的核心区别对照
下面这个表总结了两者的关键差异,我建议你收藏一下,以后选工具的时候直接对照查。
| 对比维度 | FlyMCU串口烧录 | ST-Link Utility |
|---|---|---|
| 所需硬件 | USB转TTL模块(CH340/CP2102) | ST-Link/V2调试器(或兼容版本) |
| 通信协议 | UART串口,依赖BOOT0引脚 | SWD/JTAG调试协议 |
| 是否可调试 | 不能,纯烧录 | 可以配合Keil调试(单独Utility不支持调试) |
| 烧录速度 | 较慢,几十KB程序需要数秒到十几秒 | 快,几百KB程序几秒钟写完 |
| 读Flash功能 | 不支持 | 支持,可读取芯片内部程序并导出 |
| 擦除方式 | 片擦除,简单粗暴 | 可以按扇区擦除,更灵活 |
| 适用场景 | 快速烧录、廉价款、无调试器环境、批量烧录 | 需要读回固件、检查Option Bytes、配合调试 |
这里补充一个容易被忽略的点:ST-Link Utility和Keil的关系。其实Keil MDK内嵌的下载功能,底层也是通过ST-Link这个调试器接口来烧写芯片的。所以如果你平时用的是Keil + ST-Link的组合,那么ST-Link Utility做的大多数事情,Keil本身在下载时也做了一部分。只是Keil把“烧录”这件事包装成了“点一下下载按钮”,你感知不到细节而已。
4.3 不同场景怎么选,我给出我的判断
我自己平时是这样分的,你也可以参考:
- 项目开发调试阶段:用Keil + ST-Link。在线打断点看变量,效率最高,别折腾串口。
- 只烧程序不调试,比如把编译好的固件发给同事测试:首选FlyMCU,只要对方有个USB转TTL就能烧,不用买调试器。
- 批量生产的程序烧录:如果板子设计上预留了SWD口,而且产量不大,用ST-Link全手动也OK;如果产量稍大,我偏向用串口方式做个简易的烧录工装,配合FlyMCU的命令行模式甚至能做半自动烧录。
- 拿到一块二手板子,想看看里面的程序或者确认芯片是否被锁死:必须用ST-Link Utility,FlyMCU完全做不到。
所以两句话总结:FlyMCU解决“有没有办法烧”的问题,ST-Link Utility解决“能不能深入了解芯片”的问题。两者不是平级替代关系。
5. 实战中那些让人崩溃的坑和排查方法
工具本身很简单,难的是遇到问题时怎么排查。这里我把这几年实际踩过的坑整理一下,基本都是新手最容易碰到的情况,以及对应的解决思路。
5.1 问题一:FlyMCU点“开始编程”后一直提示“连接失败”或“芯片无应答”
这个问题的概率最高,排查顺序建议如下:
第一步,确认BOOT0的跳线帽真的接到了3.3V。不要只看插了跳线帽,有些板子的跳线帽旁边有丝印标记,要确认是接在1-2还是2-3。有的板子设计比较坑,标记不明显,用万用表量一下BOOT0引脚的电平最靠谱,上电后应该是高电平。
第二步,确认接线没有接反。这是最常见的人为错误。PA9(TX)必须接USB转TTL的RXD,PA10(RX)必须接TXD。如果你不确定哪根线接哪根,可以这样快速验证:在电脑上打开串口助手,把USB转TTL模块的TXD和RXD短接,然后在串口助手里发送数据,如果自己能收到自己发的内容,说明模块本身没问题,问题一定出在STM32侧的接线上。
第三步,确认芯片供电正常。缺少共地是最容易被忽略的问题,所谓共地就是STM32板的GND和USB转TTL模块的GND必须连在一起,不共地会导致电平参考点不一致,通信波形乱掉,必然连不上。如果你的USB转TTL模块输出的3.3V或者5V同时给板子供电了,那地线必须连上,否则电流回路都建立不起来。
第四步,确认USART1没有被其他功能占用。如果你的板载串口芯片和STM32之间的连接带有跳线或者切换开关,要把它切到烧录/下载模式,否则USB转TTL过来信号会被板载另一颗串口芯片干扰。
第五步,看看芯片的供电是不是3.3V系统。如果你用的是5V供电的最小系统板,USB转TTL的TXD还输出5V电平,这可能导致STM32的RX引脚被灌入过高电压,虽然一般不至于烧坏芯片,但会导致通信不稳定,最好的做法是用支持3.3V逻辑电平的USB转TTL模块,或者加个电平转换电路。
5.2 问题二:烧录提示成功但程序没跑起来
这种情况也出现了不少。烧录显示成功,说明BootLoader确实收到了数据并写入了Flash。程序不运行,多半是BOOT0没有拉回低电平。你烧录完断电后,BOOT0应该恢复为低电平,如果它还停留在高电平状态,芯片上电后依然进BootLoader,自然跑不了用户程序。
还有一个可能,是你在烧录时选择的起始地址不对。FlyMCU默认的编程起始地址是0x08000000,这是STM32 Flash的起始地址。如果你改了这个地址,程序被写到了别的位置,CPU正常启动时根本不会执行到那里。正常情况保持默认即可。
再一个可能,是你的芯片有过看门狗或者其他外设初始化设置。如果你在初始化里开了独立看门狗,一旦程序跑到一半卡死,看门狗就会不断复位芯片,看起来就像程序跑不起来。这个和烧录本身没关系,但排查时要考虑到。
5.3 问题三:烧录过程中途卡死,进度条不动
遇到这种情况先不要慌,多半不是芯片坏了,而是通信链路不稳定造成的丢包或错帧。解决办法:
尝试调低波特率再烧一次,建议降到9600再试。波特率越低,一个bit的时间就越长,对线路上的干扰和时序偏差容忍度越高。实测很多卡死问题降到低波特率就消失了。
检查USB转TTL模块的电源输出能力。有些劣质CH340模块在给板子供电时电流不够,芯片在写入Flash时电流需求会瞬间升高,导致电压跌落,通信就失败了。如果条件允许,给STM32板子单独供电,USB转TTL模块只接TXD、RXD、GND三根线,不要用模块给板子供电,这样更稳定。
部分芯片存在“写保护”的情况。如果芯片的Flash被设置了读保护或写保护,BootLoader在写入时会失败或卡住。这时候用ST-Link Utility连接,打开Option Bytes把读保护等级修改为Level 0(不保护),然后再试串口烧录。ST-Link Utility在解锁这类芯片时比串口工具靠谱得多。
5.4 问题四:FlyMCU识别不到COM口
这个问题的根源基本都在驱动层。排查两步:
第一步,换一个USB口插试试,优先插电脑后置面板的USB口。前置扩展口的供电和信号质量都不如后置原生口,某些情况下会引起模块无法枚举。
第二步,卸载驱动重新安装。Windows系统有时候会缓存错误的驱动状态,卸载设备后在设备管理器里扫描检测硬件改动,重新安装驱动。CH340的驱动要认准厂商版本,别用三四年前的老驱动。
如果你的USB转TTL模块是CP2102芯片,相对麻烦一些,需要下载官方CP210x VCP驱动。装完之后如果设备管理器里有串口但打开失败,检查是否有其他软件占用了这个COM口,比如串口助手、其他烧录工具,先关掉再试。
5.5 经验之说:串口烧录最要紧的几件事
最后把我个人的几条经验连续说透一下:
第一,不要把串口烧录当成万能方案。它确实好用,但你能调试时尽量调试。只烧不调,出了问题还是得抓瞎。我的做法是:开发阶段Keil+ST-Link全流程调试,版本确认没问题后,需要给别的机器烧时用FlyMCU,或者量产阶段做烧录工装时用FlyMCU。
第二,文件名和路径别用中文。FlyMCU早年版本对中文路径支持不太好,会莫名其妙地报错,后来版本可能好一点,但为了省事,所有工具链路径、工程路径、hex文件路径建议统一用英文。这个经验同样适用于Keil,Keil工程即便能放在中文路径下,也常常会出现各种奇怪的编译错误。
第三,烧录完成后设置BOOT0跳线是个容易遗忘的动作。我自己踩过不止一次:烧录完了,直接接上串口测试,结果程序没跑,还以为是逻辑bug,排查了半天才发现是BOOT0跳线没拉回来。所以养成习惯:烧录完成后顺手把BOOT0恢复为低电平,再上电运行。
6. 进阶玩法:批量烧录和半自动化方案
既然用到FlyMCU了,很多人不会满足只烧一块板子。这里简单说一个批量烧录的思路。
FlyMCU其实支持命令行参数模式,可以不用图形界面直接执行烧录。一般来说参数包括串口号、波特率、hex文件路径等。写好一个批处理脚本后,烧录的步骤简化成:接好线、上电、双击Bat文件,烧录完成。配合一个自动断电上电的工装,就能实现半自动批量烧录。
如果想更进一步,板子上预留SWD接口的话,也可以考虑用ST-Link批量烧录工具,或者直接写一个小的Python脚本调用stm32flash这类开源工具做串口烧录。但那是另一个话题了,本文重点是先把FlyMCU用明白。
7. 一文说清:Keil、FlyMCU、ST-Link Utility各自扮演什么角色
我在各个社区里看到很多新手问同一个问题:“我有Keil了,为什么还要装FlyMCU?”“ST-Link Utility和Keil的下载功能重复吗?”这里我统一做个角色说明。
Keil MDK:你写代码、编译、调试的主战场。它自带下载功能,通过ST-Link接入SWD接口,烧录只是它众多能力中的一个。它解决的是“开发”这件事,不是“烧录”这件事。
FlyMCU:轻量级串口烧录工具,解决的是“在没有任何调试器、只有串口的情况下,如何把程序写入芯片”的问题。它不写代码、不调试、不读Flash,就是一个纯粹的写入器。
ST-Link Utility:官方维护的芯片底层工具,解决的是“如何通过SWD协议对芯片进行更底层的操作(读、写、擦、改Option Bytes)”的问题。它是调试器和芯片之间直接的跨IDE通道。
三个工具,使用场景差异很大,但可以这样理解:Keil是你的工作台,FlyMCU是你的便携螺丝刀,ST-Link Utility是你的万用表——你在工作台上做开发,手边放一把螺丝刀应急拆装,真需要测量电路状态时再用万用表上阵。
至少从我的经验来看,这三个工具都装上没毛病,哪个场合用哪个,心里有数就行。
8. 我个人在实际操作中最后的几点体会
说实话,串口烧录这件事,真正动手做一次比看十篇文章都有用。FlyMCU这个工具虽然界面风格停留在很多年前,看起来不够现代,但它的实用性经过了这么多年验证,功能简洁、逻辑清晰,依然是串口烧录STM32这块最顺手的工具。
我在实际项目中有个习惯,每次编译出hex文件后都会顺手用FlyMCU烧录验证一遍,确认固件能正常启动再交给别人,这样做的好处是能提前暴露一些在调试器环境中不会出现的问题,比如时钟配置在冷启动时的稳定性、BOOT引脚的初始化状态等。
最后再分享一个小技巧:如果你的项目长期需要串口烧录,强烈建议在PCB设计时就把烧录接口标准化,比如留一个4Pin的排针,丝印上标清楚TXD、RXD、GND、BOOT0或者加个BOOT0自动切换电路。这样每次烧录只需要一分钟,不用每次去翻原理图找引脚。真正的高手不是工具用得多花哨,而是把最常用的流程做到最顺手。