ST-LINK Utility 烧录与排障实战:SWD/JTAG 接线、批量烧录及常见报错处理
2026/9/24 12:35:49 网站建设 项目流程

1. 为什么 ST-LINK Utility 依然是绕不开的一环

STM32 开发做到一定阶段,你迟早会遇到一个尴尬场景:Keil 里点下载按钮,弹出一行红字,告诉你找不到设备或者校验失败,但板子明明插着,灯也亮着。这时候大多数人的第一反应是重装驱动、换线、换电脑,折腾一圈下来问题还在。真正能让你快速定位问题的,往往不是 IDE 本身,而是那个看起来有点老旧的独立工具——ST-LINK Utility。

这个工具的核心价值在于它把“烧录”这件事从编译环境里剥离出来了。Keil、IAR 这些 IDE 在下载时其实做了很多你看不见的事情:复位芯片、暂停内核、擦除扇区、写入数据、校验、再复位运行。任何一个环节出问题,报错信息都会被 IDE 包装成一句含糊的提示。而 ST-LINK Utility 直接跟 ST-LINK 调试器对话,你能清楚看到芯片有没有被识别、Flash 里现在是什么内容、读写保护有没有被打开。对于做 STM32 项目的人来说,它既是烧录工具,也是排障工具。

我这些年用下来,ST-LINK Utility 最实用的三个场景分别是:批量烧录裸片、救砖(芯片被读保护锁死或者程序跑飞导致 IDE 连不上)、以及验证固件是否真的写进去了。尤其是做基于 STM32 的毕业设计或者小批量产品时,用 Keil 一个个下载效率太低,用 ST-LINK Utility 配合命令行可以做到一键烧录,省下来的时间相当可观。

这篇文章面向的是已经上手 STM32、但烧录环节还经常卡壳的开发者。不管你是用 SWD 还是 JTAG,用的是 ST-LINK V2 还是板载的 V2-1,下面这些内容都能直接拿去用。我会从工具安装讲到引脚接线,再到实际烧录和常见报错的处理,尽量把每个步骤背后的原因也说清楚,这样你遇到变种问题时能自己判断。

2. 工具安装与驱动配置的完整流程

2.1 ST-LINK Utility 的下载与版本选择

ST-LINK Utility 这个工具官方已经停止更新了,最后一个稳定版本是 4.6.0。虽然 ST 后来主推 STM32CubeProgrammer,但 ST-LINK Utility 胜在轻量、启动快、界面直观,很多老项目和老教程还在用它。下载的时候直接搜“ST-LINK Utility 4.6.0”就能找到安装包,注意区分 32 位和 64 位系统版本。

安装过程没什么坑,一路下一步就行。但有一个细节要注意:安装程序会同时安装 ST-LINK 的 USB 驱动。如果你电脑上之前装过 STM32CubeProgrammer 或者 Keil 的 ST-LINK 驱动包,可能会出现驱动版本冲突。我遇到过的情况是,装完 ST-LINK Utility 后 Keil 反而识别不到 ST-LINK 了,原因就是两个版本的驱动在系统里打架。

提示:安装前先把 Keil、STM32CubeProgrammer 都关掉,装完后重启一次电脑,让驱动重新枚举。如果之后 Keil 还是识别不到,去设备管理器里把 ST-LINK 设备卸载(勾选删除驱动),再重新插拔让系统自动装一次。

安装完成后,桌面会出现两个图标:一个是 ST-LINK Utility 主程序,另一个是 ST-LINK Upgrade。后者是用来给 ST-LINK 调试器本身升级固件的,一般不需要动,除非你的调试器固件太老导致新芯片不支持。

2.2 驱动安装失败的排查思路

驱动装不上是新手最常遇到的问题。表现是设备管理器里 ST-LINK 显示黄色感叹号,或者根本看不到 ST-LINK 设备。这里分几种情况处理。

第一种,设备管理器里能看到“STM32 STLink”但带感叹号。这说明驱动装了但没装对。右键更新驱动,手动指向 ST-LINK Utility 安装目录下的 Drivers 文件夹,里面有针对不同系统的 inf 文件。选对系统版本后强制安装。

第二种,插上 ST-LINK 后电脑完全没反应,设备管理器里连未知设备都不出现。这基本是硬件问题:USB 线是充电线不是数据线、ST-LINK 板子坏了、或者电脑 USB 口供电不足。换一根确定能传数据的线,换一个 USB 口再试。我踩过的坑是一根看着很粗的线其实是纯充电线,折腾了半小时才发现。

第三种,设备管理器里出现“未知 USB 设备(设备描述符请求失败)”。这种情况通常是 ST-LINK 固件损坏或者芯片进入异常状态。用 ST-LINK Upgrade 工具尝试重新升级固件,如果升级工具也认不到,那这个调试器基本可以换了。

2.3 与 Keil、CubeProgrammer 的共存配置

很多人电脑上同时装着 Keil MDK、STM32CubeProgrammer 和 ST-LINK Utility。这三个工具都会调用 ST-LINK 驱动,配置不当就会互相干扰。我的建议是:日常烧录和调试用 Keil,批量烧录和救砖用 ST-LINK Utility,CubeProgrammer 留着做选项字节和 OTA 相关操作。

如果 Keil 里下载报“No ST-LINK detected”,但 ST-LINK Utility 能正常连接,说明 Keil 的调试器配置选错了。在 Keil 的 Options for Target -> Debug 里,确认选的是 ST-Link Debugger,而不是 J-LINK/J-TRACE 或者 ULINK。点旁边的 Settings,在 Debug 标签页里能看到 ST-LINK 的序列号才算配置正确。

还有一个容易忽略的点:Keil5 如果要兼容 C51 和 STM32,安装路径和芯片包管理要分开处理。C51 的芯片包和 STM32 的 DFP 包不冲突,但如果你装的是 Keil4 和 Keil5 共存,注册表里的调试器配置可能会串。这种情况我一般建议直接用 ST-LINK Utility 烧录,绕开 IDE 的调试器配置问题。

3. SWD 与 JTAG 接口的接线与引脚定位

3.1 SWD 模式:四根线搞定绝大多数场景

SWD(Serial Wire Debug)是现在 STM32 开发的主流调试接口,原因是它只需要两根信号线加电源和地,总共四根线就能完成调试和烧录。相比 JTAG 的十几根线,SWD 在板子空间紧张的时候优势非常明显。

SWD 的四根线分别是:SWDIO(数据线)、SWCLK(时钟线)、GND(地)、VCC(电源参考)。注意 VCC 这根线的作用是让 ST-LINK 检测目标板的电压,从而调整 IO 电平。如果目标板自己供电,ST-LINK 的 VCC 可以不接,但 GND 必须接。我见过有人只接 SWDIO 和 SWCLK 就指望能烧录,结果一直报 communication failure,就是因为没有共地。

接线的时候,ST-LINK V2 的引脚定义是固定的:20 针接口里,第 7 脚是 SWDIO,第 9 脚是 SWCLK,第 1 脚和第 19 脚是 VCC,第 4、6、8、10 等偶数脚是 GND。如果你用的是那种几十块钱的 ST-LINK V2 小U盘,它引出的排针上通常标了 3.3V、SWDIO、SWCLK、GND,直接对应接就行。

注意:SWDIO 和 SWCLK 不要接反,接反了不会烧坏芯片,但肯定连不上。如果拿不准,先用万用表量一下 ST-LINK 排针上的 3.3V 和 GND,确定电源脚位置后再对应找信号脚。

3.2 JTAG 模式:14 针双排接口的定位方法

JTAG 接口在 STM32 上通常是 14 针双排(2x7)或者 20 针双排(2x10)。14 针双排 JTAG 的定位键位置很关键,它决定了你插线的方向。标准 14 针 JTAG 接口的第 1 脚通常靠近定位键或者用方形焊盘标记,第 2 脚在它对面。

JTAG 的引脚定义里,真正用于调试的信号是 TCK、TMS、TDI、TDO 这四根,加上 TRST(可选)和电源地。对应到 ST-LINK 的 20 针接口上,TCK 接第 9 脚(和 SWCLK 共用),TMS 接第 7 脚(和 SWDIO 共用),TDI 接第 5 脚,TDO 接第 13 脚。也就是说,ST-LINK 的同一个物理引脚在 SWD 和 JTAG 模式下承担不同功能,这也是为什么 ST-LINK Utility 里切换模式后接线不用动。

JTAG 相比 SWD 的优势在于支持边界扫描和多器件链,但在 STM32 单芯片开发中基本用不上。而且 JTAG 占用的引脚多,很多引脚和 GPIO 复用,如果板子上这些引脚被占用了,JTAG 就连不上。这也是为什么现在新项目基本都用 SWD。

3.3 引脚复用冲突:关闭 JTAG 保留 SWD 的正确姿势

STM32 的 JTAG 引脚(PA13、PA14、PA15、PB3、PB4)默认是调试功能,如果你想把它们当普通 GPIO 用,需要关闭 JTAG。但这里有个大坑:如果你把 SWD 也关了,下次就再也连不上了,只能靠 BOOT 模式或者复位时序来救。

正确的做法是只关闭 JTAG 功能,保留 SWD。在代码里调用__HAL_AFIO_REMAP_SWJ_NOJTAG()或者直接操作 AFIO_MAPR 寄存器,把 SWJ_CFG 位设成 010(JTAG 禁用,SWD 使能)。这样 PA15、PB3、PB4 就变成普通 GPIO 了,而 PA13、PA14 仍然是 SWD 接口,随时可以烧录。

对于 GD32F4 这类兼容 STM32 的芯片,关闭 JTAG 的寄存器操作类似,但要注意 GD32 的 AFIO 寄存器地址和 STM32 可能不同,直接照搬 STM32 的代码可能会出问题。我一般建议在 GD32 上先用 ST-LINK Utility 确认能连上,再改代码关闭 JTAG,改完立刻测试一次烧录,确认 SWD 还活着再继续开发。

提示:如果你不小心把 SWD 也关了导致连不上,别慌。把 BOOT0 拉高、BOOT1 拉低,让芯片从系统存储器启动,这时候调试接口是默认打开的,ST-LINK Utility 能连上,然后擦除 Flash 或者重新烧录正常程序即可。

4. 烧录实操:从连接到固件写入的完整过程

4.1 建立连接与芯片识别

打开 ST-LINK Utility,界面很朴素,左边是设备信息区,中间是 Flash 内容显示区,下面是日志区。第一步是点 Target -> Connect,或者直接点工具栏上的连接图标。如果接线正确、驱动正常,几秒钟内就能看到芯片信息:Device 栏显示芯片型号(比如 STM32F103C8),Device ID 显示唯一标识,Flash Size 显示容量。

如果连接失败,日志区会给出具体原因。常见的有“No target connected”和“SWD/JTAG communication failure”。前者通常是接线问题或者目标板没供电,后者多半是 SWD 引脚被占用或者芯片进入了低功耗模式。这时候可以尝试在 Connect 对话框里把 Reset Mode 改成“Connect Under Reset”,让 ST-LINK 在芯片复位期间强行建立连接。

芯片识别成功后,先别急着烧录,点 Target -> Option Bytes 看一眼读写保护状态。如果 RDP(Read Protection)不是 Level 0,说明芯片被读保护了,直接烧录会失败。需要先把 RDP 改回 Level 0,但注意这个操作会触发全片擦除,Flash 里的程序会丢。所以拿到一块二手板子或者别人用过的芯片时,先确认保护状态再动手。

4.2 加载固件与烧录参数设置

ST-LINK Utility 支持多种固件格式:.hex、.bin、.s19(Motorola S-record)等。.hex 和 .s19 文件里包含了地址信息,加载后会自动填到对应的 Flash 地址;.bin 是纯二进制,加载时需要手动指定起始地址,STM32 一般是 0x08000000。

加载固件的方式是 File -> Open File,选好文件后 Flash 内容区会显示要写入的数据。这时候可以点 Target -> Program & Verify 开始烧录。弹出的对话框里有几个选项值得注意:

  • Verify after programming:建议勾上,烧录完自动校验,确保数据写对了。
  • Skip Flash erase before programming:一般不勾,除非你确定目标区域已经擦除过。
  • Erase sectors before programming:如果只烧一部分,可以选这个,只擦除涉及的扇区,速度快。

烧录速度方面,ST-LINK V2 在 SWD 模式下大概 20-50KB/s,烧一个 100KB 的固件也就几秒钟。如果速度明显偏慢,检查 SWDCLK 频率设置,在 Target -> Settings 里可以调,默认 1.8MHz 一般够用,线太长或者干扰大的时候可以降到 950kHz 提高稳定性。

4.3 批量烧录与命令行自动化

做小批量生产或者需要反复烧录同一固件时,图形界面点来点去效率太低。ST-LINK Utility 提供了命令行版本 ST-LINK_CLI.exe,装在安装目录下,可以直接在 CMD 或者批处理里调用。

一个典型的烧录命令是这样的:

ST-LINK_CLI.exe -c SWD -p firmware.bin 0x08000000 -V -Rst

参数含义:-c SWD指定用 SWD 模式连接,-p指定烧录文件和起始地址,-V表示烧录后校验,-Rst表示烧录完复位运行。如果要擦除全片,加-ME;如果要读保护,加-OB RDP=1

批量烧录的时候,可以把多个 ST-LINK 插到 USB Hub 上,用-c SWD -S <序列号>指定具体调试器,写一个循环脚本依次烧录。我做过一个 20 片的批次,用批处理脚本配合三个 ST-LINK,十分钟内全部烧完并校验通过,比手动操作快了一个数量级。

注意:命令行烧录时如果目标板供电来自 ST-LINK,注意 USB 口的电流限制。STM32 全速运行加上外设可能超过 100mA,多个 ST-LINK 同时工作可能导致某个口供电不足,出现随机连接失败。稳妥的做法是目标板独立供电,ST-LINK 只接 SWDIO、SWCLK、GND 三根线。

5. 常见报错与排查技巧实录

5.1 SWD/JTAG Communication Failure 的六种原因

这个报错是烧录环节出现频率最高的,没有之一。它的字面意思是 ST-LINK 和目标芯片之间的通信断了,但具体原因可能有很多种。我整理了一个排查表,按出现概率从高到低排列:

排查项具体表现处理方法
接线错误SWDIO/SWCLK 接反或虚接重新插拔,用万用表通断档确认
目标板未供电ST-LINK 的 VCC 没接或目标板电源没开确认目标板 3.3V 正常,ST-LINK 检测到电压
SWD 引脚被占用代码里把 PA13/PA14 配成了 GPIO 或其他功能用 Connect Under Reset 模式连接,擦除后改代码
芯片进入低功耗程序里进了 Stop/Standby 模式同上,Connect Under Reset 或拉低复位脚
复位电路问题复位脚被拉低或电容太大导致复位不释放检查复位电路,必要时断开复位电容
ST-LINK 固件过旧新芯片(如 STM32H7、G0 系列)不支持用 ST-LINK Upgrade 升级固件

其中“SWD 引脚被占用”是最隐蔽的。我遇到过一次,代码里用 PA13 做 LED 输出,烧录后 LED 正常闪,但再也连不上了。原因就是 PA13 被配成推挽输出后,SWDIO 功能被覆盖了。解决办法就是 Connect Under Reset,在芯片复位后、程序运行前的那几毫秒内建立连接,然后赶紧擦除。

5.2 Could not stop Cortex-M device 的应对策略

这个报错比 communication failure 更具体,意思是 ST-LINK 能连上芯片,但无法暂停内核。通常发生在芯片正在运行一个看门狗喂狗程序、或者进入了异常中断死循环的时候。

处理思路分两步。第一步,在 ST-LINK Utility 的 Connect 设置里,把 Reset Mode 改成“Hardware Reset”或者“Connect Under Reset”,让 ST-LINK 通过硬件复位脚强制芯片停下来。第二步,如果硬件复位也不行,检查复位脚是不是被禁用了(有些代码里会把复位脚配成 GPIO),这时候只能靠上电时序:先按住复位键,点 Connect,再松开复位键。

还有一种情况是芯片的调试功能被选项字节禁用了。在 Option Bytes 里,有一个 DBG_STANDBY 和 DBG_STOP 位,如果设成了禁用,芯片进入低功耗后调试器就唤不醒它。这种情况需要用 BOOT0 拉高的方式从系统存储器启动,然后改选项字节。

5.3 烧录成功但程序不运行的排查

有时候 ST-LINK Utility 显示烧录和校验都通过了,但板子没反应。这种问题跟烧录工具无关,是程序本身或者启动配置的问题。排查顺序如下:

先确认 BOOT0 和 BOOT1 的电平。BOOT0 必须为低才能从主 Flash 启动,如果 BOOT0 被拉高,芯片会去系统存储器找程序,你烧到 Flash 里的代码根本不会执行。这个坑我在做基于 STM32 的毕业设计时踩过,板子上的 BOOT0 跳线帽忘了拔,烧录一切正常但程序死活不跑,查了一下午。

再确认中断向量表的偏移。如果你用了 IAP 或者 OTA 方案,APP 程序的起始地址不是 0x08000000,那在 APP 里必须设置SCB->VTOR = 0x08004000(假设偏移 16KB),否则中断会跳到错误的位置。STM32 的 OTA 升级尤其要注意这一点,Bootloader 和 APP 的向量表偏移必须匹配。

最后检查时钟配置。如果程序里把外部晶振配置成了 HSE,但板子上没焊晶振,程序会卡在时钟初始化里。用 ST-LINK Utility 连接后看 PC 指针停在哪里,能快速定位是不是卡在启动阶段。

5.4 读保护与写保护的解锁方法

拿到一块被读保护的芯片,ST-LINK Utility 连接后会提示“Read protection is enabled”。这时候 Flash 内容读不出来,烧录也会失败。解锁的方法是:Target -> Option Bytes,把 RDP 从 Level 1 改成 Level 0,点 Apply。芯片会自动全片擦除,然后读保护解除。

写保护(WRP)是另一个维度的保护,它只保护特定扇区不被写入,但不影响读取。如果烧录时报“Flash memory write protected”,去 Option Bytes 里看 WRP 设置,把对应的扇区取消保护即可。WRP 的解除不会触发全片擦除,只影响被保护的扇区。

提示:量产产品如果启用了读保护,一定要把解锁流程和密码(如果有)记录在案。我见过一个团队把读保护开了之后忘了怎么解,最后只能换芯片,损失不小。

6. 进阶话题:从 ST-LINK Utility 延伸到其他烧录方式

6.1 STM32CubeProgrammer 的替代与互补

ST 官方现在主推 STM32CubeProgrammer,功能比 ST-LINK Utility 更全,支持 UART、USB DFU、OTA 等多种烧录方式。但它的启动速度慢,界面也更复杂,日常调试我还是更愿意用 ST-LINK Utility。两者可以共存,驱动是同一套,不会冲突。

CubeProgrammer 的优势在于对新型号芯片的支持更好,比如 STM32U5、H5 这些新系列,ST-LINK Utility 可能认不到,但 CubeProgrammer 没问题。另外 CubeProgrammer 的命令行工具 STM32_Programmer_CLI 功能更强,支持外部 Flash 烧录和签名固件,做安全启动方案时绕不开。

6.2 JFlash、OpenOCD 等第三方工具的适用场景

JFlash 是 SEGGER 的工具,配合 J-LINK 调试器使用,烧录速度比 ST-LINK 快不少,尤其是大容量 Flash 的芯片。如果你手头有 J-LINK,用 JFlash 烧 STM32 是完全可行的,但要注意 J-LINK 的引脚定义和 ST-LINK 不同,接线要重新对应。

OpenOCD 是开源方案,配合各种调试器都能用,适合在 Linux 环境下做自动化烧录。它的配置文件里可以指定 SWD 频率、复位方式、Flash 驱动等,灵活性很高,但上手门槛也高。如果你在做持续集成,需要自动烧录测试,OpenOCD 配合脚本是个不错的选择。

6.3 串口烧录与 OTA 升级的补充

不是所有场景都能用 SWD。比如板子已经装进外壳,调试口没引出来,这时候只能靠串口烧录或者 OTA。STM32 的串口烧录依赖内置 Bootloader,通过 BOOT0 拉高进入系统存储器,然后用 Flash Loader Demonstrator 或者 CubeProgrammer 的 UART 模式烧录。

OTA 升级则是产品出厂后更新固件的标准做法。STM32 的 OTA 一般分两种:一种是基于 Bootloader 的 IAP,APP 通过串口、CAN 或者无线模块接收新固件,写入备份区,然后 Bootloader 搬运到运行区;另一种是利用芯片自带的双 Bank Flash,在 Bank1 运行时往 Bank2 写新固件,写完切换启动地址。不管哪种方式,烧录文件都要处理好地址偏移和向量表,否则升级完程序跑不起来。

6.4 不同芯片系列的烧录差异

STM32 家族很大,F0、F1、F4、H7、G0、L4 这些系列在烧录上大同小异,但有几个细节要注意。F1 系列的 Flash 扇区大小不均匀,前几个扇区小、后面大,擦除时要注意地址对齐。F4 和 F7 的扇区是统一大小,操作简单一些。H7 系列有双 Bank 和外部 Flash 映射,烧录时地址空间更复杂。

GD32、APM32 这些国产替代芯片,大部分兼容 STM32 的烧录协议,ST-LINK Utility 能直接认。但有些型号的 Device ID 不在 ST-LINK Utility 的数据库里,会提示未知设备。这时候可以手动选择相近的 STM32 型号,或者用厂商自己的烧录工具。我试过用 ST-LINK Utility 烧 GD32F103,选 STM32F103C8 就能正常烧录和运行,但 GD32F4 系列有时候需要降 SWD 频率才稳定。

7. 我个人的实操心得与避坑清单

烧录这件事,说简单也简单,四根线接上就能用;说复杂也复杂,各种报错能让人抓狂。我把自己这些年踩过的坑和总结的经验列在下面,都是文档里不会写的。

第一,永远先确认 GND 接好了。SWD 通信失败的原因里,至少三成是地线没接或者接触不良。尤其是用杜邦线的时候,GND 那根线经常松动。我现在养成习惯,插上线之后先用手轻轻拉一下每根线,确认都插紧了再上电。

第二,ST-LINK 的 3.3V 输出能力有限,不要用它给整个板子供电。如果板子上有电机、屏幕、无线模块这些耗电外设,ST-LINK 的 3.3V 会被拉垮,导致连接不稳定。正确做法是目标板独立供电,ST-LINK 只接信号线和地。

第三,烧录前先读一下芯片的 Option Bytes。尤其是拿到别人的板子或者拆机芯片,读保护、写保护、BOOT 配置都可能跟默认值不一样。花十秒钟看一眼,能省掉后面半小时的排查。

第四,Connect Under Reset 是万能钥匙。遇到连不上的情况,先别急着改代码或者换工具,把 Reset Mode 改成 Connect Under Reset 试一次。大部分因为程序跑飞或者引脚复用导致的连接问题,这一招都能解决。

第五,命令行烧录记得加校验。-V参数虽然会多花一点时间,但能确保数据真的写进去了。我遇到过 Flash 扇区老化导致写入失败的情况,图形界面显示成功但实际数据是错的,加了校验之后立刻就能发现。

第六,保留一份“救砖”流程。把 BOOT0 拉高、用 ST-LINK Utility 连接、全片擦除、恢复选项字节、烧录正常程序这一套步骤写成一个文档,放在项目仓库里。真到了芯片连不上的时候,照着做能快速恢复,不用临时翻教程。

第七,SWD 频率不是越高越好。线长超过 10cm 或者板子上有高频干扰源时,把 SWD 频率降到 950kHz 甚至更低,稳定性会明显提升。烧录速度慢一点无所谓,一次成功比反复重试快得多。

最后说一个容易被忽略的点:ST-LINK Utility 的日志区其实信息量很大。连接失败时不要只看弹窗,把日志区的完整信息复制出来搜一下,往往能直接定位到具体原因。比如“Cannot read memory”和“Cannot write memory”指向的问题完全不同,前者可能是读保护,后者可能是写保护或者 Flash 损坏。

这些经验都是实际项目中一点点积累的,希望对正在跟 STM32 烧录较劲的你有点帮助。工具本身不复杂,关键是理解每一步在做什么,遇到问题知道往哪个方向查。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询