资讯动态

STM32 SWD调试口被禁用?三种实用方法恢复ST-Link连接

发布时间:2026/9/28 8:03:00 来源:尧图企业网站定制
做嵌入式这几年最怕看到的报错不是编译 error而是调试器弹出来的那行红字SWD/JTAG Communication Failure。尤其当你为了省两个引脚在代码里把 SWJ 调试口整个禁用掉之后第一次发现 ST-Link 死活连不上心里多半会慌完了片子是不是废了其实绝大多数情况都没到废的地步。STM32 的调试口禁用分好几个层次有的是软件运行后改了几行寄存器有的是烧录时把选项字节Option Bytes弄成了读保护有的是干脆把引脚复用到普通 GPIO 上。不同层级的“锁”有不同的开锁方法。这篇就把我自己调过的板子、踩过的坑整理成 3 套可复现的复活流程从 SWD 原理讲起一直讲到实际接线和操作适合手里有“砖”的开发板、正在研究 SWD 连接失败原因的爱好者也适合被 ST-Link 报错劝退的入门选手。1. 先搞清 SWD 为什么不理你了1.1 SWD 只有两条线凭什么能调试SWD 全称 Serial Wire Debug是 ARM 定义的串行调试接口。跟传统的 JTAG 相比它只需要两根线SWDIO 负责数据输入输出SWCLK 负责时钟。在绝大多数 STM32 上这两个信号默认映射到 PA13 和 PA14再加上电源、地、复位线一共四五根就能完成下载、在线调试、变量观察、Flash 读写。很多新手会问JTAG 有 TMS、TCK、TDI、TDO、nJTRST 这么多线SWD 就两根凭什么能干活其实 JTAG 的 TDI/TDO 是数据输入和输出分开的SWD 则把收发合并到一根双向线 SWDIO 上通过 ARM 的串行线调试协议做时分复用。对嵌入式开发来说节省的那几个引脚经常是决定性的这就是为什么现在新板子几乎全走 SWD而不是传统 JTAG。SWD 引脚和 JTAG 引脚在 STM32 上是有对应关系的PA13 既是 JTAG-TMS也是 SWDIOPA14 既是 JTAG-TCK也是 SWCLKPA15 对应 JTDIPB3 对应 JTDOPB4 对应 JNTRST。这组引脚由片上调试接口控制默认就是调试功能。注意这里有个特别容易混淆的地方调试功能是默认的但代码跑起来之后可以做 GPIO 重映射把这一组引脚全部改成普通 IO。1.2 别把责任全推给硬件先看代码我见过特别多的“下载口被禁用”案例最后查出来都是代码里一行重映射函数导致的。最常见的是这两类写法标准库风格RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);或者是 HAL 库风格__HAL_RCC_AFIO_CLK_ENABLE(); __HAL_AFIO_REMAP_SWJ_DISABLE();这两段代码的含义都是把整个 SWJ 调试接口关掉释放 PA13、PA14、PA15、PB3、PB4 五根引脚。释放之后PA13 和 PA14 就可以当作普通 GPIO 使用比如接按键、接 LED、接传感器中断。看起来很划算对吧但代价就是一旦程序烧进去开始运行ST-Link 再想通过 SWD 连接芯片根本不回应IDE 直接报SWD/JTAG Communication Failure。还有一类没那么极端的情况是只关 JTAG、保留 SWDGPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);这个操作只释放 PA15、PB3、PB4PA13/PA14 仍然是 SWD 功能。如果你遇到的是这种“还能连上但少了几个引脚”的报错其实不算砖不需要救。真正需要救的是那种“连 IDCODE 都读不到”的情况。1.3 关键结论复位不是终点是起点搞清楚原理之后你才会发现“救砖”这件事其实没那么玄。SWD 引脚的功能是芯片复位时默认有效的除非已经在 Option Bytes 层面做了永久修改否则用户程序对调试口的“禁用”本质上只是运行期的动态状态。换句话说只要能让芯片在复位状态下保持住不让用户程序继续跑调试口就有机会恢复默认功能。你需要的不是拆芯片、不是换芯片而是想办法让 CPU 停在一个“用户代码还没执行到禁用调试口那一步”的状态或者干脆绕开用户 Flash从其他启动通道把芯片擦干净。2. 复活技巧一把 BOOT0 拉高用串口 Loader 全片擦除2.1 原理系统内存里的工厂 BootloaderSTM32 内部有一块独立的系统内存System Memory出厂时预烧了一段 Bootloader专门用来通过串口、USB、CAN 等接口读写芯片。这段程序在正常情况下不会执行只有上电启动时ROM 根据 BOOT0/BOOT1 引脚的电平来选择启动地址才会进入系统内存模式。以最常见的 STM32F103 为例BOOT10、BOOT01 时芯片从 System Memory 启动运行里面的官方 Bootloader。这个 Bootloader 会通过 USART1 接收上位机命令实现读芯片、擦除 Flash、烧写固件、修改选项字节等操作。关键是整个过程里用户 Flash 里的程序根本不会运行所以你在程序里写的那些禁用 SWJ 的代码也就不会执行。一句话总结这个思路:既然 SWD 正门进不去了那就从后门进先把 Flash 擦干净再把 BOOT0 拨回来SWD 自然恢复。2.2 实操步骤从接线到擦除第一步确认启动电平。把 BOOT0 接到 3.3VBOOT1 接到 GND。不少 STM32F103 最小系统板上都有两个跳线帽通常标注为 BOOT0 和 BOOT1直接改跳线即可。如果板子上没有 BOOT1 跳线一般默认已经下拉到 GND这种情况只需要管 BOOT0。第二步连接串口。F103 的系统 Bootloader 默认走 USART1对应引脚是 PA9TX和 PA10RX。USB 转 TTL 模块跟板子之间要交叉连接也就是板子 PA9 接模块的 RX板子 PA10 接模块的 TX两边 GND 必须共地。这一步最容易翻车很多新手把 RX/TX 接反导致上位机提示无法握手。第三步给芯片复位并进入 Bootloader。最稳妥的方式是先把 BOOT0 设为高电平再给板子重新上电或者按住复位键再松开。不要带电状态下频繁切换 BOOT0有些板子电容放电不彻底容易出现切换无效的情况。第四步用软件连接。推荐使用 STM32CubeProgrammer这是 ST 官方工具比老旧的 Flash Loader Demonstrator 好用得多。打开软件选择 UART 接口配置好串口编号和波特率常见选择 115200。点击 Connect如果串口接线无误软件会识别到芯片型号和 Flash 大小整个连接流程大概几秒钟。第五步执行全片擦除。在左侧菜单进入 Erase Programming选择 Full chip erase 或者 Manual Erase 里全选扇区点击 Start。擦除过程中不要拔串口、不要断电耐心等进度条走完。擦除完成后用户 Flash 里已经没有任何用户程序也就不会再禁用 SWD 了。第六步恢复启动方式并重新连接 ST-Link。断电把 BOOT0 跳回 GND接回 ST-Link重新上电打开 STM32CubeProgrammer 的 ST-LINK 模式。正常情况下马上就能看到 MCU ID识别出芯片型号SWD 下载口已经恢复直接重新烧录正常固件即可。2.3 实操翻车点这个方案最大的坑不是擦除本身而是串口 Bootloader 根本连不上。我遇到过的情况有几种USB 转 TTL 模块供电不足BOOT0 跳线接触不良PA9/PA10 被外部电路拉死还有板子上 PA9/PA10 和 USB 转串口共用一个排针但没接 GND。排查顺序建议是先量 BOOT 引脚电平再量 RX/TX 波形最后确认工具里选择的串口号对不对。另外要注意老版本的 Flash Loader Demonstrator 对 Windows 10/11 兼容性比较差经常出现打开就崩溃或者识别不了串口的问题。如果你还在用这个古董工具直接换 STM32CubeProgrammer省去一堆环境折腾。提示如果是 STM32F4、H7 等较新的系列系统 Bootloader 除了 USART1可能还支持 USART3、USB DFU 等多个启动通道。具体支持哪个外设查对应型号的 AN2606 文档别只盯着 USART1。3. 复活技巧二Connect Under Reset趁芯片还没“翻脸”抓住它3.1 为什么要在复位状态下连接软件在 Boot0 之前就禁用了 SWJ难道 SWD 就完全没有任何机会吗不是的。嵌入式调试口有一个很反直觉的特性引脚默认功能在复位后立即生效用户程序需要先经过启动文件、SystemInit、时钟初始化真正执行到 GPIO 重映射那一行时才把调试口让出去。问题在于芯片每次复位到这个“禁用调试口”的指令之间窗口非常短。如果你的代码开头就写了GPIO_Remap_SWJ_Disable那这个窗口可能只有几十微秒。手动按键复位根本赶不上这个速度。所以要用工具自带的 Connect Under Reset 功能让调试器在芯片复位的时候直接建立连接并且把 CPU 停在复位向量处不让用户程序往下执行。用生活里的例子来理解就像一个门禁系统刷卡后门会短暂打开几毫秒之后立刻锁死。手动按复位键就像你在门外等待时机但人反应不够快Connect Under Reset 相当于在刷卡之前就把手伸到了门缝里门一开就卡住。3.2 接线方式和 CubeProgrammer 配置要在复位状态下连接调试器必须能控制目标芯片的复位引脚。ST-Link 的接口里一般会引出一根 NRST 信号需要跟板子的复位脚相连。很多 ST-Link Mini 或山寨 ST-Link 只有 SWDIO、SWCLK、GND、3.3V 四个引脚没有 NRST这时候就得单独飞线把 ST-Link 上预留的 RST 针脚接到目标板的复位网络。连线确认没问题后打开 STM32CubeProgrammer在 ST-LINK 页面的 Mode 下拉框里选择 Under reset。Frequency 建议先选低一点比如 1MHz 或 800kHz等连接稳定了再升到 4MHz这样能避开杜邦线过长带来的信号质量问题。点击 Connect如果配置正确且接线可靠软件会显示识别到芯片 IDCode 和 Flash 信息。Keil MDK 里也是一样的思路。打开 Options for Target → Debug → Settings把 Connect 选项从 Normal 改成 under Reset。改完后重新点击 Load 或 Start Debug SessionKeil 会自动先拉低复位线尝试在复位状态下连接目标芯片。J-Link 用户也可以在 J-Flash 里开启 Connect under Reset 选项把 interface 改成 SWD再把 speed 调到低速。J-Link 对复位时序的支持通常比 ST-Link 更好如果你手头有 J-Link优先试它。3.3 什么时候这个方法会失效Connect Under Reset 不是万能的。如果你的固件在启动文件阶段比如 Reset_Handler 里就极快地关闭了 SWJ或者芯片的调试接口已经被选项字节锁死那即使芯片停在复位状态SWD 也可能建立不了连接。更常见的原因是硬件接线问题NRST 线没接、目标板复位电路有大电容导致复位波形不干净、ST-Link 的复位信号驱动能力不够。最土但有效的办法是“手动配合法”按住开发板复位按钮在 CubeProgrammer 点击连接等到程序提示正在建立连接时立刻松开复位。这招对老式调试器特别管用因为它绕过了调试器对复位脚的控制直接用物理按键制造复位窗口。虽然成功率看脸但经常能救回来。提示Connect Under Reset 只适合“软件运行后动态禁用了 SWD”的情况。如果你在烧录配置里勾选了读保护或者 Option Bytes 被改动过SWD 在非常底层的地方就不会响应这时候必须先走串口 Bootloader 或者其他启动通道。4. 复活技巧三选项字节和读保护处理锁得最死的那类4.1 选项字节这个坑比代码禁用更深有些板子“死”得比代码禁用更彻底连 Connect Under Reset 都救不回来。这时候你看到的不一定是SWD/JTAG Communication Failure更可能是Error: No STM32 target found或者连接后提示Protection error、Access denied。这种情况十有八九是选项字节Option Bytes出问题了。选项字节是独立于主 Flash 的一块配置区里面保存着读保护级别、硬件看门狗选项、启动模式选择、BOR 复位阈值等信息。其中跟调试最相关的是 RDP 读保护位分三个级别Level 0默认状态调试口完全开放。Level 1限制通过调试口读取 Flash连接时经常报保护错误。Level 2永久性最高保护调试口直接禁用芯片基本上无法再通过 SWD 访问属于不可逆操作。很多朋友烧录时喜欢在配置里勾选“设置读保护”或者用的是别人做好的烧录脚本里面默认带上了保护选项。烧完之后程序本身没死但你再也连不上调试口了。这种情况下SWD 正门已经彻底被底层拦死必须走系统 Bootloader 才能把它解开。4.2 操作流程通过串口 Bootloader 复位 RDP选中选项字节的恢复方案前提是芯片还能进系统内存 Bootloader。具体流程跟技巧一很像但操作目的完全不同。第一步还是 BOOT0 拉高、BOOT1 拉低进入 System Memory 模式通过 USART1 连接 STM32CubeProgrammer。第二步连接成功后菜单栏进入 Option Bytes 页面。这里能看到当前 RDP Level 是多少。如果显示 Level 1你只需要把 RDP 改回 Level 0然后点击 Apply。第三步软件会弹窗警告“将自动执行整片擦除”这是解除 Level 1 保护的标准动作确认即可。等待擦除完成再重新上电这时 RDP 已经回到 Level 0SWD 调试口会重新开放。需要强调一点整个操作只改选项字节不用往 Flash 里烧任何内容。解保护之后你可以直接拔掉串口接上 ST-Link 正常下载。如果你的板子 BOOT0 不方便改跳线也可以用串口 Bootloader 进入后先烧一个“临时的、不关闭 SWD 的干净固件”再恢复启动方式效果也是殊途同归。4.3 三种复活方式怎么选我把三种方案的适用场景整理成了一张表方便你遇到问题时第一时间定位表现最有效方案思路代码里调用了 SWJ 禁用ST-Link 连不上技巧二Connect Under Reset最快不用改硬件跳线板子 BOOT0 方便改串口模块现成技巧一BOOT0 拉高后全片擦除最稳通杀所有软件级禁用提示 Protection error / Access denied技巧三通过 Bootloader 复位 RDP必须走系统 BootloaderSWD 正门已被锁有 J-Link也有 NRST 线技巧二优先J-Link 复位时序支持更好手里只有 ST-Link没有 USB 转串口技巧二优先不用额外硬件多数情况下技巧一和技巧二能解决 80% 的问题。技巧三作为深层兜底处理的是“读保护被误开”这种更隐蔽的情况。5. 常见问题与排查速查5.1 连接失败的硬件排查清单SWD 连不上不一定是固件锁了。我见过不少板子代码完全正常但 ST-Link 就是报错。先检查这几个基础项供电VDD 和 GND 是否正常3.3V 是否稳定重点量 ST-Link 插头附近的电压。共地ST-Link 和目标板必须共地不然 SWD 信号根本没有参考电压。接线顺序推荐先接 GND再接 SWDIO 和 SWCLK最后接复位信号避免热插拔造成触点抖动。复位电路如果 NRST 被外部电容拉死或者被其他芯片拉低处理器可能一直卡在复位状态SWD 自然连不上。时钟芯片如果没有外部晶振而固件又配置成了 HSE 启动程序可能根本跑不起来调试口同样不工作。5.2 降低 SWD 频率能解决不少怪问题ST-Link 默认连接频率可能高达 4MHz但杜邦线、面包板、长引脚的分布电容非常大高速信号很容易变形。遇到偶尔能连上、经常失败或者“第一次成功、第二次失败”的情况先把频率降到 1MHz 甚至 800kHz。很多看似玄学的连接问题实际上就是信号完整性问题。我刷过一块老开发板只有把频率调到 1MHz 以下才能稳定连上。5.3 全片擦除后还是连不上怎么回事如果走完技巧一确认 Flash 已经被擦除但 ST-Link 仍识别不到芯片就要怀疑两点一是你擦除的并不是目标芯片串口号选错了擦了个寂寞二是芯片的 RDP 已经不是 Level 0而是 Level 2。Level 2 一旦设置调试口和系统 Bootloader 都会永久失效除非换芯片否则没法恢复。这也是我一直强调不要乱碰 RDP0xCC 的原因。5.4 预防比救砖更重要说说我的习惯做法救砖多了之后我现在写代码前就先留后路。第一除非极端缺引脚否则不在程序里禁用 SWJ最多只关 JTAG 保留 SWD这样 PA15/PB3/PB4 能省出来但 PA13/PA14 还能调试。第二所有自己画的最小系统板都留出一组 BOOT0 跳线方便随时走串口 Bootloader。第三量产固件里绝不设置 RDP Level 1如果客户有保护需求也只用 STM32 的读保护 Level 1并且严格测试能否全片擦除恢复绝不碰 Level 2。还有一个非常实用的小偏方如果板子上的 BOOT0 被固定到了 GND短接起来很麻烦可以在复位脚上接一个轻触开关同时用 J-Link 的 Connect Under Reset 模式反复按复位尝试。只要程序里禁用 SWD 的指令不是特别靠前多试几次就能抓到窗口。这套东西我前前后后帮同事和自己救了不少板子最快的一次只用了一分钟最慢的一次折腾了半天最后发现是杜邦线接触不良。希望大家遇到SWD/JTAG Communication Failure的时候别急着把板子扔了先按这篇文章的顺序试试大概率能救回来。最后再给大家留一句话别轻易追求“彻底关闭调试口”的干净爽快保住下载口比省掉两根引脚重要得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑