尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

STM32C031调试报错Target is not responding排查

STM32C031调试报错Target is not responding排查 前阵子调一块 STM32C031 的板子想把它从默认的 24MHz 提到标称的 48MHz。改完时钟树编译下载STM32CubeProgrammer 的日志区就开始刷一行字Target is not responding, retrying...。第一次碰到这个报错的人十个里有九个会觉得自己把板子烧了但真相往往没这么贵。这个报错在 STM32 官方工具链里非常常见尤其在折腾时钟配置的时候。它不是说芯片物理损坏而是调试器和目标芯片之间“失联”了——你改了 48MHz结果把芯片弄到了一个没法正常响应调试请求的状态。这篇文章我按自己实际排查的顺序写下来从最基础的硬件检查到Connect under reset再到Full chip erase每一步都讲清楚为什么这样做、成功了说明什么、失败了又指向什么问题。最后给出 C031 上 48MHz 时钟配置的正确姿势以及几个我从这次经历里总结出的防再犯习惯。看完你大概能明白这类“Target is not responding”问题本质上就三类原因——时钟乱、调试口被占、供电不足。绕不开这三点。1. 报错现场与第一判断先别急着怀疑板子坏了1.1 这个报错到底是怎么出现的我用的是 ST-LINK/V2 加一块 C031 的最小系统板场景很典型在 STM32CubeIDE 里改完时钟配置点 Debug控制台开始输出连接信息紧接着就是一行Target is not responding, retrying...然后进度条卡住反复重试几次后连接失败。这里要先区分一个关键点No ST-LINK detected和Target is not responding是完全不同的两件事。前者是 PC 端根本没找到调试器问题在 USB 线、驱动或 ST-LINK 固件后者是 ST-LINK 本身工作正常但和目标芯片的 SWD 握手失败。看到retrying的时候基本可以确定 ST-LINK 已经被系统识别了问题出在目标板一侧。我当时的第一反应是检查杜邦线——因为这种小封装板子的 SWD 只有四根线接触不良是很常见的事。但重新插拔之后问题依旧。这时候我意识到大概率是刚才的固件把芯片“搞死”了。1.2 第一反应先拆掉“硬件坏了”这个选项遇到这种报错不要急着下结论说板子坏了。先做两个快速检查在 STM32CubeProgrammer 的“Port”下拉框里看能不能枚举出 ST-LINK 的信息。能枚举出来说明 USB、驱动、ST-LINK 固件都没问题。用万用表量目标板的 VDD 引脚确认供电电压是 3.3V 左右。如果电压正常硬件基本盘是稳的。很多新手会直接重新上电再连一次但这通常没用只要 Flash 里那段“搞事”的固件还在上电就会再次执行再次把芯片带偏。这就是为什么后面要用Connect under reset和Full chip erase而不是一上来就换芯片。1.3 根因分类一张表看清可能性排查这类问题前先在心里摆一张表可以避免瞎试可能原因典型表现判断方法接线/接触不良偶尔能连上重新插拔后变化重新插拔、换杜邦线、量通断供电不足/电压跌落上电后 VDD 不稳定万用表量 VDD 和 NRSTSWD 引脚被复用成普通 IO改完 GPIO 初始化后出现Connect under reset Full erase系统时钟配置错误芯片跑飞改时钟树后出现Connect under reset Full eraseSWD 频率过高长杜邦线时出现降低 SWD 速度后再试读保护 RDP 级别异常突然无法连接检查选项字节必要时 Mass eraseST-LINK 硬件老化换一块板子也一样换调试器验证这张表里的每一项后面都有对应的具体操作。排查顺序一般从硬件往软件走因为硬件检查成本最低。2. 为什么改 48MHz 会把调试口弄没SWD 和系统时钟的底层关系2.1 C031 的时钟树没有 PLLHSI48 才是主角STM32C031 属于 C0 系列时钟树比 F1、F4 简单得多。很多从 F103 转过来的人会踩同一个坑下意识地在代码里找 PLL 配置。但 C031 内部没有 PLL系统时钟最高就是 48MHz而且这个 48MHz 直接来自内部的高速 RC 振荡器 HSI48。C031 的时钟路径大概是这样的HSI48 作为内部 RC 振荡器输出 48MHz经过配置后成为系统时钟源。开发者要做的只是把它选作 SYSCLK并保证总线分频器设置正确没有倍频、没有外部晶振的必要也不需要像 F1 那样去折腾 PLL 的 N、P、Q 参数。这个“简单”反而是坑的来源。因为很多人的习惯是“我要超频到 48MHz”然后疯狂找 PLL 相关的寄存器最后在一个不存在 PLL 的芯片上写了些意义不明的配置。C031 上跑 48MHz 的正确做法就是选 HSI48 作为时钟源AHB 分频 1APB 分频 1完事。2.2 配置 48MHz 时最容易踩的代码坑我见过几种典型的配置错误每一种都能让芯片直接失联第一切换系统时钟源之前没有等待 HSI48 起振完成。内部 RC 振荡器从使能到稳定需要几十微秒如果不检查就绪标志位就直接切换时钟树可能处于中间状态内核直接失去可靠时钟跑飞。第二分频器设置顺序不对。在 Cortex-M0 上切换 SYSCLK 源和设置总线分频器的顺序会影响 Flash 访问时序。如果你先提高了 SYSCLK 频率、却没有同步调整 Flash 等待状态或总线分频CPU 取指就可能出错表现为程序跑飞、调试口无响应。第三从别的工程复制代码却不改芯片型号。比如从 F0 或 G0 复制了一段 SystemClock_Config里面的寄存器位定义可能跟 C031 不兼容。C031 的 RCC 寄存器结构有自己的布局直接搬过来的代码往往会把某个保留位写成未知值结果就是芯片行为不可预期。这些都是典型的“把调试口搞没”的方式。道理很简单CPU 失去正确时钟后调试接口上的请求就没人处理了。2.3 SWD 调试口需要“活着的内核”来应答SWD 调试协议本身是异步的调试器通过 SWCLK 发送请求目标芯片在约定的时序窗口里返回应答。如果芯片内核还在正常运行调试接口就能正常响应如果内核因为时钟异常而停止、跑飞或陷入 HardFault 之外的状态SWD 请求就得不到有效应答。你看到的Target is not responding, retrying...本质上是调试器发出了读取 IDCODE 的请求但目标芯片没有在超时时间内返回正确的 ACK 响应所以只能反复重试。我习惯用一个电话类比来解释调试器和目标芯片之间就像两个人打电话。你一边打电话一边把对方的电话线剪了那对方自然不可能再回应你。这里“电话线”就是系统时钟“应答”就是 SWD 的 ACK。所以当你在代码里把时钟配置成错误状态相当于亲手剪断了电话线。这里要额外说一句有人会拿 FPGA 或数字 IC 设计里的“时钟约束”“异步时钟域”“clock data race”这些概念来套 MCU 场景但 MCU 这边的逻辑要朴素得多。C031 的目标就是确保 SYSCLK 稳定、内核能取指SWD 就能响应。不存在什么复杂的时序收敛问题就是一个简单的“时钟有没有稳”的问题。2.4 比时钟更常见的坑PA13/PA14 被复用成普通 IO还有一种高发原因跟时钟没关系但同样表现为Target is not responding你的代码把 SWD 引脚 PA13SWDIO和 PA14SWCLK复用成了普通 GPIO。STM32 的 SWD 引脚在复位后默认是调试功能但只要你初始化 GPIO 时把 PA13/PA14 配置成推挽输出或某个外设的复用功能调试口就被占用了。从这一刻起ST-LINK 发出去的 SWD 请求全都会被当成普通 GPIO 电平变化自然没有应答。这个坑比时钟错误更隐蔽因为代码本身是好的时钟也正常只是调试口被“抢”了。要判断是不是这个原因最直接的办法就是后面要讲的Full chip erase——把 Flash 清空后SWD 引脚恢复默认功能就能连上了。3. 六步排查链路从按下复位到擦除 Flash3.1 第一步量供电、量复位、查接线排查第一步永远是硬件。不要觉得这个板子已经验证过了就跳过杜邦线氧化、接触不良、面包板虚接的情况我见过太多次。接线检查清单如下SWDIO连接 ST-LINK 的 SWDIO目标芯片 PA13SWCLK连接 ST-LINK 的 SWCLK目标芯片 PA14GND两端必须共地这是 SWD 通信的前提3.3V如果使用 ST-LINK 供电注意其输出电流有限如果外接电源确保 ST-LINK 和目标板不冲突用万用表量两个关键点VDD 对地电压应该在数据手册标称范围内C031 一般是 1.7V~3.6V具体以手册为准。如果电压低于 2V芯片内部逻辑可能处于不可靠状态。NRST 引脚电压正常空闲时应该接近 VDD。如果被外部电路拉低芯片会一直处于复位状态。还有一个容易被忽略的如果板子上有独立的 VDDA 和 VSSA 引脚记得检查它们是否正确接到了 VDD 和 GND。有些手工焊的小板子只接了主电源导致内部模拟电路异常芯片的表现可能是上电后完全不跑。3.2 第二步把 SWD 频率降下来再试硬件检查没发现问题后下一步不是急着擦 Flash而是先降低 SWD 通信速率。在 STM32CubeProgrammer 里右上角设置区域有频率选项。默认可能是 Auto 或较高的频率。你可以手动改成 1.8MHz甚至降到 480kHz。SWD 不是越快越好尤其是在杜邦线、面包板、飞线这种环境下高频率很容易因为信号反射和寄生电容导致握手失败。我实测的情况是用 10cm 左右的杜邦线连 SWD频率 Auto 模式下偶尔失败降到 1MHz 之后一次成功。如果你的板子是手工焊接、飞线比较多这一步能救回很多“看起来坏了”的板子。降频后如果正常连接说明硬件链路没有问题问题就在固件或时序上。3.3 第三步Connect under reset 硬连如果降频后在 Normal 模式下还是连不上那就轮到Connect under reset上场了。操作位置在 STM32CubeProgrammer 的连接设置里连接方式选择Under reset。ST-LINK 会在烧录或连接时先把 NRST 拉低让目标芯片保持在复位状态然后在复位释放前完成 SWD 连接初始化最后再释放复位。这样做的好处是芯片在复位状态下不会执行 Flash 里的用户代码那些把时钟搞乱、把 SWD 口占用的程序都暂时“冻结”了调试器可以趁这个窗口接管芯片。使用这个模式有一个前提ST-LINK 的 NRST 引脚必须连到目标芯片的 NRST。如果之前飞线时只连了 SWDIO、SWCLK、GND没有连 NRST那 Connect under reset 就不起作用需要补一根线。另外提醒一下如果你之前动过选项字节把 NRST 引脚配置成了普通 GPIO 功能这个模式也会失效。这种属于比较老的坑但确实存在。3.4 第四步Full chip erase 直接擦掉问题固件Connect under reset能连上之后第一件事不是改代码烧录而是做一次Full chip erase。在 STM32CubeProgrammer 的 “Erasing Programming” 页面选择Full chip erase点击执行。这会把 Flash 里的用户代码全部擦空同时也会把选项字节恢复默认包括将 RDP 读保护级别恢复到 Level 0。这一步成功了基本就能断定芯片本身没坏问题出在 Flash 里的固件上。擦除之后PA13/PA14 恢复默认的 SWD 功能芯片也不再执行那段搞坏时钟的代码后续再用 Normal 模式连接基本都能成功。如果你连Connect under reset都连不上那 Full chip erase 也执行不了这时候看下一步。3.5 第五步检查读保护和 BOOT 引脚擦不掉、连不上还有一个可能性芯片被设置了读保护。STM32 的读保护分为 Level 0、Level 1、Level 2。Level 1 下调试器能识别到目标但无法读写 Flash表现就可能是连接异常或读写超时Level 2 则直接锁死任何调试接口都无法访问。如果是 Level 1在 STM32CubeProgrammer 的选项字节页面把 RDP 设置回 Level 0通常写入 0xAA芯片会自动触发 Mass erase。这时候数据会全部清空但芯片就回来了。如果显示的是 Level 2那这块芯片基本可以宣告——它的调试接口永久失效了只能换芯片。这也是为什么量产固件不要随意启用 RDP Level 2一旦锁死就是物理报废。BOOT 引脚也要看一眼。大部分 C031 应用场景下 BOOT0 保持默认低电平即可。如果 BOOT 引脚被拉到了异常电平芯片可能不会从 Flash 启动调试器同样可能找不到正确的执行现场。3.6 第六步换口、换线、换调试器走到这一步还没解决的话就该考虑调试器本身了。ST-LINK/V2 这类调试
返回列表