1. 为什么值得花时间把JTAG电路吃透STM32的调试接口看着就是几根线的事但真到画板子的时候翻车的人一抓一大把。我自己就见过不少项目程序烧不进去第一反应是芯片坏了、JLINK坏了、驱动没装好折腾一整天最后发现是原理图上JTAG那几个上拉下拉电阻焊错了位置或者PCB走线拉得太长导致时序不稳。这类问题不复杂但特别耗时间而且一旦板子打样回来才发现改板成本就上去了。这篇内容就是把我这些年画STM32调试接口的经验完整梳理一遍。核心围绕STM32、JTAG、PCB、JLINK、原理图这几个关键词展开从JTAG和SWD的关系讲起到引脚定义、上拉下拉电阻怎么放、JLINK怎么接、PCB布局布线要注意什么最后再聊聊怎么在代码里把JTAG引脚释放出来当普通GPIO用。适合正在画第一块STM32板子的新手也适合做过几块板但调试接口偶尔抽风的老手。需要先说明一点STM32的调试接口有JTAG和SWD两种模式SWD是JTAG的精简版只用了两根信号线。现在实际项目里SWD用得更多因为引脚少、布线简单、速度也够用。但JTAG作为标准接口理解它的完整结构对排查问题很有帮助而且很多现成的JLINK仿真器都是20pin标准JTAG接口搞清楚每一根线的作用接线的时候心里才有底。下面讲的内容JTAG和SWD都会覆盖到因为它们在硬件设计上是共用引脚的。2. JTAG与SWD的关系拆解2.1 两种调试模式的本质区别JTAG全称Joint Test Action Group最早是为了做芯片边界扫描测试而制定的标准后来被扩展用来做程序下载和在线调试。它需要5根核心信号线TCK、TMS、TDI、TDO、TRST再加上电源和地一个完整的JTAG接口至少占7个引脚。SWD全称Serial Wire Debug是ARM公司推出的两线调试接口只保留SWCLK和SWDIO两根信号线本质上是对JTAG协议的一种精简封装。从硬件角度看STM32的JTAG和SWD是复用同一组引脚的。以常见的STM32F103C8T6为例PA13是SWDIO也是JTMSPA14是SWCLK也是JTCKPA15是JTDIPB3是JTDOPB4是JNTRST。也就是说当你用SWD模式时只需要PA13和PA14两根线PA15、PB3、PB4就可以释放出来当普通GPIO用。这个特性在实际项目中非常实用尤其是引脚资源紧张的时候。从调试体验上看JTAG支持多器件级联适合复杂的多芯片调试场景SWD结构简单抗干扰能力更强在长距离布线和高速下载时表现更稳定。我个人的习惯是板子上只留SWD接口但把JTAG的完整引脚都引出来做成测试点方便出问题时用示波器抓波形。2.2 为什么STM32默认启用JTAGSTM32上电复位后调试接口默认是JTAG和SWD都使能的。这是因为芯片出厂时不知道用户会用哪种模式所以把两种都打开保证任何标准仿真器都能连上。但这个默认状态会占用5个引脚对于引脚数量少的型号比如LQFP48封装的F103C8T6这5个引脚占了将近10%的资源有时候确实不够用。所以ST提供了复用重映射功能可以通过配置AFIO_MAPR寄存器来关闭JTAG、只保留SWD。具体操作后面会详细讲。这里先建立一个概念JTAG和SWD不是二选一的关系而是可以同时存在、也可以只留一个。硬件设计时要把两种模式都考虑进去软件配置时再根据实际需求决定释放哪些引脚。2.3 硬件设计时该选JTAG还是SWD这个问题没有标准答案取决于项目需求。如果板子空间充裕、引脚够用、调试环境复杂比如需要多芯片级联调试那就保留完整的JTAG接口用标准的20pin排针兼容性最好。如果板子紧凑、引脚紧张、只需要单芯片调试那SWD是更优选择4根线VCC、GND、SWDIO、SWCLK就能搞定。我自己的做法是折中PCB上放一个标准的20pin JTAG排针2.54mm间距但实际只用其中的SWD引脚其余引脚要么接地要么悬空。这样既兼容标准JLINK排线又不会浪费太多板子空间。而且万一以后需要用到JTAG的完整功能排针已经在那里了不用重新改板。3. JTAG引脚定义与JLINK连接详解3.1 标准20pin JTAG接口引脚定义JLINK仿真器最常用的接口是20pin的JTAG排针间距2.54mm。这个接口的定义是有标准的每一根线都有明确用途。下面这张表是我根据ARM标准整理出来的画原理图的时候可以直接对照。引脚编号信号名称方向说明1VTref输入目标板参考电压用于检测目标板是否上电2VCC输出JLINK输出的3.3V一般不用3nTRST输出JTAG复位信号低有效4GND-地5TDI输出测试数据输入6GND-地7TMS/SWDIO输出模式选择/串行数据8GND-地9TCK/SWCLK输出时钟/串行时钟10GND-地11RTCK输入返回时钟一般不用12GND-地13TDO/SWO输入测试数据输出14GND-地15nRESET输出目标板复位信号16GND-地17NC-未连接18GND-地19NC-未连接20GND-地这张表建议收藏画原理图的时候直接照着连。需要特别注意的是第1脚VTref这个引脚必须接到目标板的3.3V电源上JLINK通过它来检测目标板是否上电、电压是否正常。如果这个脚没接或者接错JLINK会报“无法识别目标板”或者“目标板电压异常”。3.2 最小系统下的SWD连接方案如果只用SWD模式接线可以大幅简化。只需要4根线VTref引脚1接目标板3.3VGND引脚4、6、8、10、12、14、16、18、20任选一个接目标板地SWDIO引脚7接STM32的PA13SWCLK引脚9接STM32的PA14nRESET引脚15可选接接了之后JLINK可以控制目标板复位调试更方便。不接也能用只是复位操作要靠软件或者手动按键。我实测下来SWD模式下这4根线只要连接可靠JLINK的识别率和下载速度都很稳。线长控制在15cm以内超过20cm就容易出现连接不稳定的情况。如果非要用长线建议在SWDIO和SWCLK上串联33Ω电阻做阻抗匹配同时降低SWD时钟频率。3.3 上拉下拉电阻的正确配置这是最容易出错的地方。STM32的JTAG引脚内部有弱上拉和弱下拉但为了信号完整性通常建议在外部再加电阻。具体怎么加要看引脚功能TCK/SWCLK建议加下拉电阻10kΩ到地保证时钟线在空闲时处于低电平避免误触发。TMS/SWDIO建议加上拉电阻10kΩ到3.3V保证模式选择线在空闲时处于高电平。TDI建议加上拉电阻10kΩ到3.3V因为TDI在JTAG模式下需要保持高电平。TDO一般不加它是输出引脚加了下拉反而可能影响驱动能力。nTRST建议加上拉电阻10kΩ到3.3V保证复位信号在空闲时为高电平不复位状态。nRESETSTM32内部已经有上拉外部可以不加但如果调试环境干扰大建议加一个100nF电容到地做滤波。这些电阻的阻值不是随便选的。10kΩ是经验值既能保证足够的驱动能力又不会在信号翻转时消耗太多电流。如果板子上有多个器件共用JTAG总线电阻值可以适当减小到4.7kΩ增强抗干扰能力。注意上拉电阻要接到3.3V不要接到5V。STM32的IO耐压是3.3V接5V上拉会损坏芯片。3.4 JLINK驱动安装与连接测试硬件连好之后需要在电脑上安装JLINK驱动。去JLINK官网下载最新的驱动包安装过程一路下一步就行。安装完成后把JLINK插到电脑USB口打开设备管理器应该能看到“J-Link driver”设备没有黄色感叹号就说明驱动正常。然后打开JLINK Commander驱动安装时会一起装上输入connect命令再输入?查看可用的芯片型号选择对应的STM32型号。如果连接成功会显示芯片的ID和电压信息。如果报错“Cannot connect to target”按这个顺序排查检查目标板是否上电VTref是否有3.3V检查SWDIO和SWCLK是否接反检查GND是否共地降低SWD时钟频率试试在Commander里输入speed 1000检查nRESET是否被拉低这套排查流程我用了很多次基本上90%的连接问题都能定位到。4. 原理图设计实操要点4.1 从STM32最小系统开始画原理图的时候我习惯先把STM32最小系统搭起来再往外扩。最小系统包括STM32主控、晶振电路、复位电路、电源电路、启动模式配置、调试接口。调试接口这部分就是把前面讲的JTAG/SWD引脚引出来加上上拉下拉电阻再接到排针上。以STM32F103C8T6为例具体连接如下PA13SWDIO→ 10kΩ上拉到3.3V → 接到排针引脚7PA14SWCLK→ 10kΩ下拉到GND → 接到排针引脚9PA15JTDI→ 10kΩ上拉到3.3V → 接到排针引脚5PB3JTDO→ 直接接到排针引脚13PB4JNTRST→ 10kΩ上拉到3.3V → 接到排针引脚33.3V → 接到排针引脚1GND → 接到排针引脚4、6、8、10、12、14、16、18、20NRST → 接到排针引脚15画的时候注意排针的引脚1要标注清楚通常用方形焊盘或者丝印标记。JLINK排线的红线对应引脚1插反了虽然一般不会烧但肯定连不上。4.2 电源与参考电压处理VTref引脚排针引脚1要接到目标板的3.3V电源上。这个3.3V应该是目标板的主电源不是JLINK输出的3.3V。JLINK的引脚2虽然也输出3.3V但那个电流能力很弱带不动目标板而且如果目标板有自己的电源两个电源冲突可能出问题。如果目标板有多个电源域比如3.3V和1.8VVTref要接调试接口所在的电源域。STM32的调试接口IO电压是跟着VDD走的所以VTref接VDD就行。另外建议在VTref和GND之间加一个100nF电容滤掉高频噪声。这个电容位置要靠近排针不要离太远。4.3 复位电路与调试接口的配合STM32的NRST引脚内部有上拉电阻典型值40kΩ左右。外部通常再加一个100nF电容到地构成RC复位电路时间常数约4ms足够芯片完成上电复位。调试接口的nRESET排针引脚15接到STM32的NRST上。这样JLINK可以通过拉低NRST来复位芯片下载程序后自动运行。如果不接这根线下载完程序需要手动按复位键比较麻烦。有个细节要注意如果目标板上NRST还接了其他复位源比如看门狗输出、复位按键要确保这些复位源不会在调试时干扰JLINK的复位控制。我遇到过复位按键卡住导致JLINK无法连接的情况排查了半天才发现是按键机械故障。4.4 原理图检查清单画完原理图后对照这个清单检查一遍能避免大部分低级错误[ ] VTref是否接到目标板3.3V[ ] GND是否全部连通[ ] SWDIO和SWCLK是否接对引脚[ ] 上拉下拉电阻是否焊在正确位置[ ] 排针引脚1是否标注清楚[ ] NRST是否接到排针引脚15[ ] 是否有100nF滤波电容[ ] 电源和地是否加了去耦电容这个清单看着简单但每一条我都见过有人踩坑。尤其是上拉下拉电阻画反了不会报错但调试就是连不上特别隐蔽。5. PCB布局布线实战5.1 元器件布局原则PCB布局的第一步是把调试接口相关的元器件摆好。我的习惯是把20pin排针放在板子边缘方便插拔JLINK排线。排针旁边放上拉下拉电阻和滤波电容尽量靠近排针走线越短越好。STM32主控和排针之间的距离也要控制。SWDIO和SWCLK这两根信号线走线长度最好控制在10cm以内。超过这个长度信号完整性会变差表现为下载速度上不去、偶尔连接失败。如果板子实在太大STM32离排针很远那就考虑把调试接口做成一个独立的测试点区域用短线连接。电阻和电容的摆放也有讲究。上拉电阻要靠近STM32引脚还是靠近排针我的经验是靠近STM32引脚更好因为上拉电阻的作用是在信号源端提供稳定的高电平靠近源端能更有效地抑制反射。滤波电容则要靠近排针因为它的作用是滤掉从排针引入的噪声。5.2 走线规则与阻抗控制SWDIO和SWCLK是高速信号线虽然SWD的时钟频率通常只有几MHz但边沿很陡谐波成分丰富。走线时要注意等长SWDIO和SWCLK尽量等长偏差控制在5mm以内。不等长会导致时序偏差高速下载时可能出错。包地如果板子空间允许在SWDIO和SWCLK两侧走地线或者铺地铜减少串扰。避免跨分割这两根线不要跨过电源分割区否则回流路径断裂信号质量会急剧下降。少打过孔每过一个过孔就多一个阻抗不连续点尽量在同一层走完。线宽方面普通信号线6mil到8mil就够了。如果走线较长超过10cm可以适当加宽到10mil减小直流电阻。阻抗方面SWD信号一般不做严格的50Ω阻抗控制因为频率不高但保持走线均匀、避免突变总是好的。5.3 地平面与回流路径调试接口的GND引脚很多这不是没有道理的。每一根信号线都需要一个干净的回流路径GND引脚越多回流路径越短信号质量越好。PCB上要保证排针下方有一个完整的地平面。如果排针在顶层底层就要铺地铜并且通过多个过孔把顶层的地和底层的地连起来。过孔数量建议每根GND引脚旁边至少放一个这样回流路径最短。我见过一些板子排针下面没有地平面GND引脚只靠一根细线连到主地结果调试时好时坏。后来在排针下面加了一块地铜问题就消失了。这个细节在低速电路里可能不明显但在调试接口这种对信号质量敏感的地方影响很大。5.4 丝印与标识排针的丝印标识很重要。引脚1要用特殊标记比如方形焊盘、丝印三角形、或者直接写“1”其他引脚可以标上信号名。这样接线的时候不容易插反排查问题也方便。我还会在排针旁边丝印上“SWD”或者“JTAG”字样标明这个接口的用途。如果板子上有多个调试接口比如主控一个、协处理器一个一定要用不同的丝印区分开否则很容易插错。另外建议在丝印上标注VTref的电压值比如“3.3V”提醒接线的人不要接错电压。虽然JLINK有电压检测但接错电压还是可能损坏器件。6. 软件配置关闭JTAG释放引脚6.1 为什么要关闭JTAG前面提到STM32默认启用JTAG和SWD占用了PA13、PA14、PA15、PB3、PB4五个引脚。对于引脚紧张的型号这五个引脚如果能释放出来当普通GPIO用能解决大问题。比如用STM32F103C8T6驱动一个LCD屏引脚本来就不够释放出PB3和PB4就能多控制两个信号。关闭JTAG的操作是通过配置AFIO_MAPR寄存器实现的。这个寄存器控制引脚复用和重映射其中SWJ_CFG位域控制调试接口的配置。具体配置如下SWJ_CFG值调试接口状态释放的引脚000全使能默认无001全关闭PA13、PA14、PA15、PB3、PB4010关闭JTAG使能SWDPA15、PB3、PB4100关闭JTAG使能SWDPA15、PB3、PB4实际使用中最常用的是010配置保留SWD用于调试和下载释放PA15、PB3、PB4三个引脚。这样既不影响调试又能多出三个GPIO。6.2 标准库下的配置代码用STM32标准外设库的话配置代码如下#include stm32f10x.h void JTAG_Disable(void) { // 使能AFIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 关闭JTAG保留SWD GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // 此时PA15、PB3、PB4已释放为普通GPIO // 可以继续配置这三个引脚的功能 }这段代码的关键是GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)它把SWJ_CFG配置为010关闭JTAG但保留SWD。执行完这段代码后PA15、PB3、PB4就可以像普通GPIO一样使用了。需要注意的是这个配置要在使用这三个引脚之前执行。如果先配置了GPIO再关闭JTAG可能会冲突。我通常把这段代码放在系统初始化函数的最前面确保调试接口配置优先完成。6.3 HAL库下的配置代码用HAL库的话配置方式略有不同#include stm32f1xx_hal.h void JTAG_Disable(void) { __HAL_RCC_AFIO_CLK_ENABLE(); // 关闭JTAG保留SWD __HAL_AFIO_REMAP_SWJ_NOJTAG(); // 释放PA15、PB3、PB4 }HAL库提供了宏__HAL_AFIO_REMAP_SWJ_NOJTAG()效果和标准库的GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)一样。如果连SWD也要关闭比如需要释放PA13和PA14可以用__HAL_AFIO_REMAP_SWJ_DISABLE()但这样就没法用SWD调试了只能通过串口或者USB下载程序要谨慎使用。6.4 关闭JTAG后的注意事项关闭JTAG后有几个坑要注意第一关闭操作是不可逆的至少在当前复位周期内不可逆。一旦执行了关闭JTAG的代码JLINK的JTAG模式就连不上了只能用SWD模式。所以调试的时候要确保SWD接口是通的。第二如果代码里关闭了JTAG但硬件上SWD接口没接或者接错了那就彻底连不上了只能通过BOOT模式或者串口下载程序来恢复。我建议在关闭JTAG之前先确认SWD连接正常。第三有些STM32型号的PB3和PB4还复用了其他功能比如SPI1的SCK和MISO关闭JTAG后如果要使用这些复用功能还需要额外配置AFIO的重映射寄存器。这个要根据具体型号的参考手册来操作。第四GD32系列比如GD32F4的JTAG关闭方式和STM32略有不同寄存器地址和位定义可能有差异。如果是从STM32移植到GD32这部分代码要重新核对。7. 常见问题与排查技巧实录7.1 JLINK连接失败排查表现象可能原因排查方法提示“Cannot connect to target”目标板未上电测量VTref是否有3.3V提示“Cannot connect to target”SWDIO/SWCLK接反交换两根线试试提示“Cannot connect to target”GND未共地测量JLINK和目标的GND是否连通提示“Target voltage too low”VTref电压不足检查目标板电源连接成功但下载失败SWD时钟太快降低时钟频率到1MHz连接成功但下载失败Flash被写保护用JLINK Commander解除保护偶尔连接成功偶尔失败走线太长或干扰大缩短排线加滤波电容提示“JTAG communication failure”JTAG被关闭改用SWD模式连接这张表是我这些年排查问题的经验总结基本上覆盖了90%以上的连接故障。遇到问题的时候按顺序排查能省很多时间。7.2 SWD/JTAG Communication Failure的典型原因这个报错信息很常见原因也很多。我遇到过的典型情况有第一种是芯片进入了低功耗模式。STM32在Stop或者Standby模式下调试接口会关闭JLINK连不上。解决办法是在JLINK Commander里选择“Connect under reset”让JLINK在芯片复位期间连接这时候调试接口还是使能的。第二种是代码里关闭了JTAG但没保留SWD。前面讲过如果SWJ_CFG配置为001JTAG和SWD都关闭了那就彻底连不上了。恢复方法是通过BOOT0拉高进入系统存储器启动模式用串口下载一个不关闭调试接口的程序。第三种是硬件上nRESET被拉低。如果复位电路有问题芯片一直处于复位状态调试接口也不工作。测量NRST引脚电压正常应该是3.3V左右如果是0V就是复位电路有问题。第四种是电源不稳定。STM32的调试接口对电源质量有一定要求如果电源纹波太大可能导致调试接口工作异常。用示波器看一下3.3V电源的纹波正常应该在50mV以内。7.3 关闭JTAG后引脚无法使用的排查有时候关闭了JTAG但PA15、PB3、PB4还是不能当普通GPIO用。常见原因有AFIO时钟没使能。配置AFIO_MAPR之前必须先使能AFIO时钟否则配置不生效。配置顺序不对。要先关闭JTAG再配置GPIO。如果先配置了GPIO的模式再关闭JTAGGPIO的状态可能被重置。引脚被其他外设占用。比如PB3复用了SPI1_SCK如果SPI1已经使能PB3就被SPI1控制了需要先关闭SPI1或者重映射SPI1的引脚。代码优化导致配置被跳过。有些编译器会把“看似无用”的寄存器配置优化掉建议在配置语句前加volatile关键字或者用调试器确认寄存器确实被写了。7.4 实操心得与避坑建议分享几个我踩过的坑和总结的经验坑一排针引脚1标反了。有一次画板子排针的引脚1丝印标在了右边但实际焊盘是左边是引脚1。结果JLINK排线插上去VTref接到了GNDSWDIO接到了SWCLK怎么都连不上。后来用万用表一个个量才发现的。教训是丝印和焊盘一定要对应画完PCB后仔细检查一遍。坑二上拉电阻焊成了下拉。有一次批量焊接的时候贴片电阻的料盘放错了10kΩ上拉电阻焊成了下拉。板子回来调试SWDIO一直被拉低JLINK连不上。排查了半天才想到量电阻。教训是焊接前确认料盘焊完后抽检几个关键电阻。坑三SWD走线太长导致下载不稳定。有一块板子STM32和排针分别在板子两端走线大概15cm。JLINK能连上但下载速度只能降到500kHz才稳定。后来在SWDIO和SWCLK上串联了33Ω电阻下载速度提到了2MHz。教训是调试接口走线尽量短长了就加匹配电阻。坑四忘记使能AFIO时钟。写代码的时候直接调用了GPIO_PinRemapConfig但忘了先使能AFIO时钟。结果配置不生效PA15还是不能当GPIO用。这个错误很隐蔽因为代码编译没问题运行也不报错就是功能不对。教训是配置AFIO之前先使能AFIO时钟。坑五JLINK驱动版本太老。有一次用了一个老版本的JLINK驱动连接新的STM32型号时提示“Unknown device”。去官网下载最新驱动后问题解决。教训是JLINK驱动要定期更新尤其是使用新型号芯片的时候。7.5 调试接口的测试与验证板子打样回来之后不要急着焊STM32先做几个基础测试第一步用万用表测量排针的VTref和GND之间的电阻应该是无穷大没有短路。如果电阻很小说明有短路要排查。第二步给板子上电测量VTref对GND的电压应该是3.3V。如果不对检查电源电路。第三步测量SWDIO和SWCLK对GND的电压。SWDIO应该有上拉电压接近3.3VSWCLK应该有下拉电压接近0V。如果不对检查上拉下拉电阻。第四步把JLINK插上打开JLINK Commander输入connect看能否识别到芯片。如果识别到了说明硬件没问题可以开始下载程序了。这套测试流程花不了几分钟但能提前发现大部分硬件问题避免焊完芯片才发现调试接口不通的尴尬。8. 从原理图到PCB的完整检查清单最后整理一份完整的检查清单画完板子后对照检查一遍能避开大部分坑。原理图检查项[ ] VTref接到目标板3.3V不是JLINK的3.3V[ ] GND全部连通没有悬空的GND引脚[ ] SWDIO接PA13SWCLK接PA14没有接反[ ] PA13上拉10kΩ到3.3VPA14下拉10kΩ到GND[ ] PA15上拉10kΩ到3.3VPB4上拉10kΩ到3.3V[ ] PB3JTDO不加上拉下拉[ ] NRST接到排针引脚15有100nF电容到地[ ] 排针引脚1有明确标识[ ] VTref和GND之间有100nF滤波电容PCB检查项[ ] 排针放在板子边缘方便插拔[ ] 上拉下拉电阻靠近STM32引脚[ ] 滤波电容靠近排针[ ] SWDIO和SWCLK走线尽量短控制在10cm以内[ ] SWDIO和SWCLK尽量等长偏差小于5mm[ ] SWDIO和SWCLK两侧有地线包地或铺地铜[ ] 排针下方有完整地平面[ ] 每根GND引脚旁边有至少一个过孔连接到地平面[ ] 丝印清晰标注引脚1和信号名[ ] 没有跨电源分割区走线软件检查项[ ] 配置AFIO之前使能了AFIO时钟[ ] 关闭JTAG的代码放在GPIO配置之前[ ] 关闭JTAG后确认SWD仍然可用[ ] 释放的引脚没有被其他外设占用[ ] 如果需要使用复用功能额外配置了重映射寄存器这份清单看着长但实际操作中花个十几分钟就能过一遍。比起板子打样回来发现问题的返工成本这点时间投入非常值得。我个人在实际操作中的体会是调试接口的硬件设计本身不复杂但细节特别多而且很多问题在原理图阶段看不出来非要到调试的时候才暴露。所以最好的办法就是严格按照标准来该加的电阻一个不少该走的线一根不省该检查的项目逐条过。这样虽然前期麻烦一点但后期调试会顺畅很多。另外建议第一次画板子的时候把JTAG和SWD都引出来用标准20pin排针兼容性最好等积累了一定经验再根据项目需求做精简。
阅读完成 · 觉得有帮助?