1. 为什么还要聊 ST-LINK Utility 这个老古董如果你刚开始接触 STM32大概率会经历这样一个过程装好 Keil 或者 IAR新建工程点一下 Download 按钮程序就跑起来了。一切看起来都很顺直到某天你拿到一块别人给的板子或者从产线上拿回来一批芯片发现 Keil 里点下载报了一堆错或者芯片被读保护锁死了这时候你才意识到——原来烧录这件事不只是点一个按钮那么简单。ST-LINK Utility 就是在这个场景下登场的东西。它是 ST 官方早期推出的一款独立烧录工具配合 ST-LINK 系列调试器使用主要干三件事连接目标芯片、烧录固件文件、擦除芯片或扇区。听起来功能很单一但恰恰因为它的独立和底层在很多 Keil 搞不定的场合它反而能救场。我见过太多新人Keil 一报错就懵了不知道问题出在 IDE 配置、调试器固件、芯片状态还是接线。而 ST-LINK Utility 的好处在于它把连接和烧录这两件事从 IDE 里剥离出来让你能单独验证硬件链路是否正常。换句话说它能帮你判断问题到底出在工具链还是出在芯片本身这个诊断价值比它本身的烧录功能还重要。这篇内容适合谁看如果你是刚上手 STM32、手里有一块 ST-LINK V2 或者板载 ST-LINK 的开发板、想搞清楚从连上芯片到把程序写进去这条链路到底发生了什么那这篇就是给你写的。我会从驱动安装、连接配置、烧录文件格式、擦除策略一直讲到常见报错的排查思路尽量把每一步背后的为什么也讲清楚而不是只给你一串操作步骤。需要提前说明的是ST-LINK Utility 官方已经停止更新ST 现在主推的是 STM32CubeProgrammer。但现实中大量教程、老项目、产线工具仍然在用 ST-LINK Utility而且它的操作逻辑更简单直白作为理解烧录这件事的入门工具非常合适。学会它之后你再迁移到 CubeProgrammer 几乎是零成本。2. 连接之前驱动、硬件与那几个容易被忽略的细节2.1 ST-LINK 驱动到底装的是什么东西很多人以为插上 ST-LINK电脑识别出设备就完事了。其实这里有个关键区分ST-LINK 本身是一个 USB 设备它需要驱动才能被系统识别而它对外提供的 SWD/JTAG 接口是另一套协议。你装驱动解决的是电脑能不能跟 ST-LINK 说话而 ST-LINK Utility 能不能连上芯片解决的是ST-LINK 能不能跟 STM32 说话。这两件事经常被混为一谈导致排查方向跑偏。ST-LINK 的驱动通常随 ST-LINK Utility 安装包一起装好安装过程中会注册 USB 驱动。装完之后你可以在设备管理器里看到类似 STMicroelectronics STLink dongle 或者 STLink Virtual COM Port 的条目。如果这里显示黄色感叹号那说明驱动没装好后面所有操作都免谈。提示如果你之前装过 Keil 的 ST-LINK 驱动包或者装过 CubeProgrammer驱动可能会冲突。表现是设备管理器里能看到设备但 ST-LINK Utility 就是连不上。这时候建议先在设备管理器里卸载设备并勾选删除驱动再重新装 ST-LINK Utility 自带的驱动。2.2 接线SWD 四根线少一根都不行ST-LINK 和 STM32 之间最常用的连接方式是 SWDSerial Wire Debug只需要四根线引脚名称作用是否必须1VCC供电参考3.3V视情况2SWDIO数据线必须3SWCLK时钟线必须4GND地必须这里有几个新人最容易踩的坑。第一VCC 这根线到底接不接。如果你的目标板已经独立供电那 ST-LINK 的 VCC 可以不接但 GND 必须共地。如果目标板没供电你可以用 ST-LINK 的 3.3V 给板子供电但要注意 ST-LINK 的供电能力有限带不动功耗大的板子。第二SWDIO 和 SWCLK 不要接反接反了通常表现为连不上或者时好时坏。第三线不要太长SWD 是高速信号杜邦线超过 20 厘米就容易出问题我实测过用 30 厘米的杜邦线连接成功率明显下降。还有一个隐蔽的坑有些开发板把 SWD 接口做成了 20 针的 JTAG 座你需要用转接板或者按引脚定义单独引线。这时候一定要对照板子的原理图确认 SWDIO、SWCLK、GND 的位置不要凭感觉插。2.3 目标芯片的供电与复位状态ST-LINK Utility 连接芯片时芯片必须处于可调试状态。如果芯片跑飞了、进了低功耗模式、或者被读保护锁死都可能连不上。这时候可以尝试两个办法一是按住复位键再点连接让芯片在复位状态下被识别二是把 BOOT0 拉高让芯片从系统存储器启动绕过用户程序。另外如果目标板上有外部看门狗或者电源管理芯片可能会在连接过程中干扰。我遇到过一次板子上有个电源监控芯片上电后延迟 200ms 才释放复位导致 ST-LINK Utility 连接超时。后来在连接设置里把复位模式改成 Connect Under Reset 就解决了。3. 连接配置Target 菜单里那几个选项到底在干什么3.1 连接模式Normal 与 Connect Under Reset 的区别打开 ST-LINK Utility点 Target - Connect默认用的是 Normal 模式。这个模式的逻辑是ST-LINK 直接通过 SWD 发送连接请求芯片正常响应就建立连接。它适用于芯片运行正常、没有进入特殊状态的情况。而 Connect Under Reset 模式是让 ST-LINK 先拉住芯片的复位引脚让芯片保持在复位状态然后建立连接连接成功后再释放复位。这个模式专门对付那些程序跑飞导致 SWD 被占用或者芯片一上电就进低功耗的情况。你可以这样理解Normal 是敲门等人开Connect Under Reset 是趁人还没反应过来先把门推开。实际操作中如果你用 Normal 连不上第一件事就是换 Connect Under Reset 试试。这个切换能解决大概一半的连不上问题。3.2 复位方式硬件复位与软件复位的选择在连接设置里还有一个 Reset Mode 选项通常有 Hardware Reset 和 Software Reset 两种。硬件复位是通过 ST-LINK 的复位引脚直接拉低芯片的 NRST软件复位是通过 SWD 协议发送复位命令。区别在于硬件复位需要你的 ST-LINK 复位引脚和芯片 NRST 连上。很多简易的 ST-LINK V2 只引出了 SWDIO、SWCLK、GND、VCC 四根线没有复位线这时候你只能选 Software Reset。而 Software Reset 在芯片完全死机的情况下可能无效因为它依赖芯片内部的调试逻辑还能响应。我的建议是如果你的 ST-LINK 有复位引脚尽量接上并且优先用 Hardware Reset。这样连接成功率最高尤其是在芯片状态不确定的时候。3.3 时钟频率不是越快越好ST-LINK Utility 里可以设置 SWD 的时钟频率默认一般是 4MHz 或者 1.8MHz。很多人觉得频率越高烧录越快就拉到最高。但实际上时钟频率受限于接线质量、线长、芯片型号。线长较长或者接线质量差的时候高频会导致通信错误表现为连接不稳定或者烧录校验失败。我一般的做法是先用默认频率连接如果稳定就不动如果出现连接断续或者烧录报错就把频率降到 1MHz 甚至更低再试。烧录一个几十 KB 的固件4MHz 和 1MHz 的差距也就一两秒没必要为了这点速度牺牲稳定性。4. 烧录文件Hex、Bin、ELF 到底该选哪个4.1 三种文件格式的本质区别ST-LINK Utility 支持烧录的文件格式主要有 .hex、.bin 和 .elf。很多新人拿到文件就直接打开烧根本不关心格式结果烧进去不运行又找不到原因。其实这三种格式的区别很关键格式是否含地址信息是否含调试信息典型来源.hex含不含Keil、IAR 输出.bin不含不含手动转换、部分工具输出.elf含含编译器直接输出关键点在于.bin 文件不包含地址信息。也就是说ST-LINK Utility 打开 .bin 文件时你必须手动指定烧录的起始地址。如果你不指定它默认从 0x08000000 开始烧对于大多数 STM32 应用这是对的但如果你的程序是从别的地址开始的比如带 Bootloader 的升级方案就会烧错位置。而 .hex 和 .elf 文件内部记录了每个数据段应该放在哪个地址ST-LINK Utility 会自动解析不需要你手动填地址。所以优先用 .hex 或 .elf能省掉地址填错的坑。4.2 打开文件后先别急着烧检查地址范围不管你用什么格式打开文件之后ST-LINK Utility 会显示文件的大小和地址范围。这时候一定要看一眼确认地址范围落在芯片的 Flash 区域内。比如 STM32F103C8T6 的 Flash 是 64KB地址范围是 0x08000000 到 0x0800FFFF。如果你打开的文件地址范围超出了这个区间烧录会报错或者烧进去不运行。我遇到过一个典型案例有人用 Keil 编译了一个工程输出文件地址范围是 0x08000000 到 0x0801FFFF也就是 128KB但他的芯片只有 64KB Flash。结果烧录时报错他以为是工具问题其实是芯片容量不够。这种情况要么换芯片要么优化代码减小体积。4.3 校验选项多花几秒省掉一堆麻烦ST-LINK Utility 在烧录时有一个 Verify after download 选项建议勾上。它的作用是在烧录完成后把芯片里的数据和文件内容逐字节比对确认烧录无误。多花的时间通常也就一两秒但能帮你排除掉因为通信干扰导致的烧录错误。我见过有人为了省时间不勾校验结果烧进去的程序偶尔跑飞查了半天才发现是烧录时某几个字节写错了。这种问题如果不开校验几乎不可能定位。5. 擦除策略全片擦除、扇区擦除与读保护解锁5.1 什么时候需要擦除烧录之前要不要擦除取决于你的操作场景。如果你只是更新程序而且新程序和旧程序占用的地址范围完全重叠ST-LINK Utility 在烧录时会自动覆盖对应区域理论上不擦也能烧。但现实中我建议每次烧录前都擦除原因有两个一是旧程序可能有残留数据在新程序范围之外导致运行时出现奇怪行为二是擦除后烧录能保证 Flash 状态干净避免因为 Flash 未擦除导致的写入失败。STM32 的 Flash 有个特性只能把 1 写成 0不能把 0 写成 1。擦除操作就是把整个扇区恢复成全 1 状态。如果你不擦除直接写而目标地址之前已经被写过有 0那写入就会失败或者数据错误。所以擦除是保证写入成功的前提。5.2 全片擦除与扇区擦除的取舍ST-LINK Utility 提供两种擦除方式Erase Chip全片擦除和 Erase Sectors扇区擦除。全片擦除是把整个 Flash 清空操作简单耗时取决于芯片容量一般几秒到十几秒。扇区擦除是让你选择擦除哪些扇区适合只想更新部分区域的场景比如你有 Bootloader 在 0x08000000 开始的扇区应用程序在后面的扇区升级时只想擦除应用程序区域保留 Bootloader。我的经验是开发阶段直接用全片擦除省心。到了量产或者带 Bootloader 的升级场景再用扇区擦除。因为扇区擦除需要你清楚知道每个扇区的地址范围填错了可能把 Bootloader 擦掉那就得不偿失了。5.3 读保护芯片被锁死后的解锁流程这是 ST-LINK Utility 最有价值的功能之一。STM32 有一个读保护Read Out Protection简称 RDP机制开启后芯片内部的 Flash 不能被外部调试器读取防止代码被抄。但如果你拿到一块开了读保护的芯片想重新烧录自己的程序就会连不上或者烧不进去。解锁流程是这样的在 ST-LINK Utility 里点 Target - Option Bytes找到 Read Out Protection 选项把它从 Enabled 改成 Disabled然后点 Apply。这时候工具会提示你解锁会触发全片擦除因为这是安全机制的要求——防止有人通过解锁读取原有代码。确认之后芯片会被擦除读保护解除你就可以正常烧录了。注意解锁读保护会丢失芯片内所有原有程序操作前确认你不需要保留原内容。另外有些芯片在解锁后需要断电重新上电才能正常连接。我遇到过一种情况芯片开了读保护用 Normal 模式连不上用 Connect Under Reset 也连不上。后来发现需要在连接设置里把复位方式改成 Hardware Reset并且 ST-LINK 的复位线必须接上才能进入解锁流程。所以如果你要处理读保护芯片提前把复位线接好能省很多事。6. 那些年我们踩过的连接与烧录报错6.1 No target connected从现象到根因的排查链路这个报错是新人遇到最多的。它的字面意思是没有连接目标但背后的原因可能有很多种。我一般按下面的顺序排查第一步看设备管理器。确认 ST-LINK 被系统识别没有黄色感叹号。如果这里就有问题后面不用查了先解决驱动。第二步看接线。确认 SWDIO、SWCLK、GND 三根线接对且接触良好。可以用万用表量一下通断排除杜邦线内部断裂的情况。我遇到过好几次是杜邦线看着插好了实际内部断了。第三步看供电。确认目标板有电且电压在芯片工作范围内。如果目标板由 ST-LINK 供电量一下 ST-LINK 的 3.3V 输出是否正常。第四步换连接模式。Normal 连不上就换 Connect Under ResetSoftware Reset 不行就换 Hardware Reset。第五步降时钟频率。把 SWD 频率降到 1MHz 甚至 500kHz 再试。第六步检查芯片状态。如果以上都不行可能是芯片进了读保护或者低功耗模式需要按前面说的解锁流程处理。这个排查顺序的逻辑是从外到内、从简单到复杂先排除电脑和驱动问题再排除线缆和供电问题最后才怀疑芯片本身。按这个顺序走大部分问题能在前三步解决。6.2 Cannot access memory 与 Flash 写保护这个报错通常出现在烧录阶段意思是工具能连上芯片但无法写入指定地址。常见原因是Flash 写保护Write Protection被开启了。STM32 的 Option Bytes 里可以对每个扇区单独设置写保护开启后该扇区不能被写入。解决办法同样是进 Option Bytes把对应的写保护取消然后 Apply。注意取消写保护也会触发擦除所以操作前确认数据不需要保留。还有一种可能是你烧录的地址超出了芯片 Flash 范围比如往 0x08010000 写数据但芯片只有 64KB Flash。这种情况工具会报 Cannot access memory因为那个地址根本不存在。6.3 Keil 能烧但 ST-LINK Utility 连不上反过来也一样这种一边行一边不行的情况特别让人抓狂。根本原因通常是两者的连接参数不一样。Keil 在下载时会用自己的连接配置可能用了 Connect Under Reset也可能用了不同的时钟频率。而 ST-LINK Utility 默认用 Normal 模式参数不匹配就连不上。解决办法很简单把 ST-LINK Utility 的连接参数调成和 Keil 一致。具体来说看看 Keil 的 Debug 设置里用的什么复位模式、什么频率然后在 ST-LINK Utility 里对应设置。我一般会把 ST-LINK Utility 设成 Connect Under Reset Hardware Reset 1MHz这个组合兼容性最好。反过来如果 ST-LINK Utility 能连但 Keil 烧录失败那问题可能在 Keil 的 Flash 算法配置或者工程设置上跟 ST-LINK Utility 无关。这时候可以用 ST-LINK Utility 烧一个已知能跑的 hex 文件确认硬件链路没问题再去查 Keil 的配置。7. 从 ST-LINK Utility 迁移到 STM32CubeProgrammer 的注意事项虽然这篇主要讲 ST-LINK Utility但现实是 ST 已经主推 STM32CubeProgrammer新项目和新芯片的支持都在那边。所以最后聊聊迁移的事。两者的核心逻辑是一样的连接、烧录、擦除。区别在于 CubeProgrammer 界面更现代支持更多芯片和更多协议比如 UART、USB DFU而且命令行工具更完善适合集成到自动化流程里。迁移时最容易出问题的地方是连接配置的默认值不同。CubeProgrammer 默认可能用 Normal 模式而你在 ST-LINK Utility 里习惯用 Connect Under Reset换过去之后发现连不上其实是模式没改。另外 CubeProgrammer 的擦除选项叫 Full chip erase位置和 ST-LINK Utility 不一样第一次用容易找不到。我的建议是如果你只是做简单的烧录和擦除ST-LINK Utility 完全够用没必要急着换。但如果你要用到 OTA 升级、批量烧录、或者新出的 STM32 系列那就尽早熟悉 CubeProgrammer。两者可以共存装在不同目录就行驱动是共用的。提示CubeProgrammer 的命令行版本STM32_Programmer_CLI非常适合做批量烧录脚本支持 -c 连接、-w 写文件、-e 擦除、-v 校验等参数配合批处理或者 Shell 脚本能实现一键烧录。这个在产线或者测试环节非常实用。8. 一些让烧录更稳的个人习惯聊了这么多操作和排查最后分享几个我自己养成的习惯都是踩坑之后总结出来的。第一固定一套接线和连接参数。我给自己常用的 ST-LINK 和开发板配了一套固定的杜邦线长度控制在 15 厘米以内连接参数固定为 Connect Under Reset Hardware Reset 1MHz。这样每次连接的成功率都很稳定不用每次都试来试去。第二烧录前先读一下芯片信息。ST-LINK Utility 连上之后Target - Option Bytes 里能看到芯片型号、Flash 大小、读保护状态。花几秒钟确认一下能避免很多烧错芯片的低级错误。我就见过有人把 F103 的程序烧到 F407 上然后纳闷为什么不跑。第三保留一份已知能跑的 hex 文件。当你怀疑是硬件问题还是软件问题时用这份文件烧进去测试。如果它能跑说明硬件链路没问题问题在你的程序如果它也不跑那就要查硬件了。这个技巧能帮你快速定位问题方向。第四读保护芯片单独放。开了读保护的芯片和普通芯片混在一起很容易在批量烧录时搞混。我一般会把它们分开放并且贴上标签处理的时候集中解锁避免在正常烧录流程中突然遇到连不上而浪费时间。第五记录每次报错和解决办法。嵌入式开发遇到的问题往往有重复性今天遇到的 No target connected 可能下个月又遇到。我习惯用一个文本文件记录报错信息、排查过程和最终解决办法积累下来就是自己的排查手册。这个习惯在带新人的时候特别有用直接把记录给他们比口头讲一遍高效得多。烧录这件事说简单也简单说复杂也复杂。简单在于它本质上就是把数据写进 Flash复杂在于连接链路涉及驱动、硬件、协议、芯片状态多个环节任何一个环节出问题都会表现为连不上或烧不进。ST-LINK Utility 作为一个轻量工具最大的价值就是帮你把这条链路拆开让你能一段一段地验证。把它的连接、烧录、擦除三个核心功能用熟再配合一套自己的排查习惯嵌入式开发里关于烧录的绝大多数问题你都能自己搞定。