SWD与JTAG接口详解:调试接口选型与实战

调试接口,说白了就是你和芯片沟通的桥梁。没有它,你写的代码烧不进去,出了问题也抓不到现场。STM32F103支持两种调试接口:JTAG和SWD。我个人习惯,只要不是必须用JTAG的场景,一律用SWD。为什么?往下看你就明白了。

JTAG接口:老牌标准,但引脚多

JTAG是IEEE 1149.1标准,最早是用来做边界扫描测试的。STM32F103上的JTAG占用5个引脚:

引脚 功能 对应GPIO
TCK 测试时钟 PA14
TMS 测试模式选择 PA13
TDI 测试数据输入 PA15
TDO 测试数据输出 PB3
nTRST 测试复位(可选) PB4

我在项目中遇到过一件事:有个同事把PA15和PB3复用成了普通GPIO,结果JTAG死活连不上。排查了半天才发现,这两个引脚默认就是JTAG功能,你得先禁用JTAG才能当GPIO用。嗯,这个坑很多人踩过。

SWD接口:两线制,省引脚才是王道

SWD(Serial Wire Debug)是ARM公司搞的简化版调试接口。它只用了JTAG 5根线里的2根:

  • SWCLK —— 对应JTAG的TCK,PA14
  • SWDIO —— 对应JTAG的TMS,PA13

剩下的PA15、PB3、PB4全部解放出来,可以当普通GPIO用。你想想看,对于引脚紧张的STM32F103项目,省下3个IO口意味着什么?可以多接一个传感器,或者多控制一个LED灯带。

核心结论:除非你需要用JTAG做边界扫描测试,否则优先选SWD。省引脚、接线简单、调试速度也不差。

调试时钟(SWCLK)与数据线(SWDIO)的电气特性

这两根线看着简单,但电气特性搞不清楚,调试器照样连不上。我刚开始做嵌入式那会儿,就吃过这个亏。

SWCLK:时钟线,主机驱动

  • 由调试器(如J-Link、ST-Link)驱动输出
  • 最大频率:STM32F103支持最高4MHz(实际建议用2MHz以下,更稳定)
  • 电平:3.3V,与STM32F103的VDD一致
  • 上升沿采样数据,下降沿切换数据

SWDIO:数据线,双向传输

  • 调试器发送数据时,SWDIO为输出
  • 调试器接收数据时,SWDIO为输入
  • 需要上拉电阻(4.7kΩ~10kΩ,接3.3V)
  • 数据在SWCLK的上升沿被采样

我的经验:SWDIO的上拉电阻不是必须的,但加上会更稳定。我曾经在一条长排线上调试,没加上拉电阻,SWDIO波形边沿很缓,偶尔会通信失败。焊上10kΩ上拉电阻后,问题消失。

常见连接错误:这些坑我替你踩过了

调试器连不上芯片,80%的原因是接线问题。下面这几个错误,我几乎都见过,有些自己还犯过。

错误一:SWDIO和SWCLK接反

这个错误太常见了。排线颜色一样,插上去就反了。调试器会报错:No target connected。解决办法:用万用表量一下,或者换回来试试。

错误二:GND没接

调试器和目标板必须共地。不接GND,信号电平没有参考点,通信肯定失败。我见过有人只接了SWCLK和SWDIO两根线,结果怎么都连不上。接上GND,一次成功。

错误三:复位引脚被拉低

STM32F103的NRST引脚如果被外部电路拉低,芯片一直处于复位状态,调试器无法连接。检查一下复位电路,确保NRST是高电平。

错误四:芯片进入低功耗模式

如果代码里进了STOP或STANDBY模式,调试接口会被关闭。解决办法:在进入低功耗前加个延时,或者用Bootloader方式擦除芯片。

警告:千万不要在调试接口上带电插拔!我有个同事,调试器连着板子,直接拔了SWD线,结果芯片的PA13引脚烧了。正确的做法是:先断开调试器电源,再拔线。

SWD与JTAG接口对比总结

对比项 JTAG SWD
引脚数 5(含可选nTRST) 2
占用GPIO PA13、PA14、PA15、PB3、PB4 PA13、PA14
调试速度 最高4MHz 最高4MHz
边界扫描 支持 不支持
接线复杂度 高 低
推荐场景 需要边界扫描测试 日常调试、引脚紧张

SWD调试接口连接示意图

下面这张图,是我画的一个标准SWD连接方式。调试器端和目标板端一一对应,别接反了。

SWD调试接口连接示意图 调试器 (J-Link / ST-Link) SWCLK SWDIO GND 目标板 (STM32F103) SWCLK (PA14) SWDIO (PA13) GND 注意:SWDIO建议加4.7kΩ~10kΩ上拉电阻到3.3V

调试接口的初始化配置

STM32F103上电后,默认启用JTAG+SWD功能。如果你想释放PA15、PB3、PB4做GPIO,需要在代码里配置一下:

// 禁用JTAG,保留SWD
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

// 此时PA15、PB3、PB4可以当普通GPIO使用
// PA13(SWDIO)和PA14(SWCLK)仍保留调试功能

如果你连SWD也想禁用(比如为了省电),可以用:

// 完全禁用JTAG和SWD
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

注意:一旦完全禁用调试接口,你就没法再用调试器连接芯片了。除非你通过Bootloader或串口ISP擦除芯片。所以,调试阶段千万别这么干!

调试接口的电气连接检查清单

每次调试器连不上,我都会按这个清单排查一遍。你也试试:

  1. 检查接线:SWCLK、SWDIO、GND三根线都接了吗?有没有接反?
  2. 检查电平:调试器和目标板的电压一致吗?都是3.3V?
  3. 检查复位:NRST引脚是高电平吗?有没有被拉低?
  4. 检查上拉:SWDIO有没有加上拉电阻?
  5. 检查时钟:调试器设置的SWCLK频率是不是太高?降到1MHz试试。
  6. 检查供电:目标板供电正常吗?VDD有没有3.3V?

嗯,基本上这六步走完,90%的连接问题都能解决。剩下的10%,可能是芯片本身坏了,或者调试器固件需要升级。