3. 烧录协议基础:UART、SPI、I2C、SWD/JTAG

烧录这件事,说白了就是上位机跟芯片里的 Bootloader 或调试接口「对话」。对话得用双方都懂的语言,这就是协议。我见过不少工程师,日志报错看不懂,其实根子是不清楚底层协议在干什么。

这一章,咱们把四种最常见的烧录协议过一遍。不扯太深的理论,重点讲清楚:它长什么样、怎么传数据、烧录时容易在哪翻车。

核心观点:烧录日志里 80% 的「通信超时」「校验失败」「ACK 错误」,追到物理层都能找到答案。协议基础越扎实,看日志越像看剧本。

烧录协议知识体系 烧录协议 UART 异步串行,3 线 SPI 同步串行,4 线 I2C 同步串行,2 线 SWD / JTAG 调试接口,2~5 线 烧录器选协议,协议选硬件引脚。日志里报的错,往往就是这几根线上出了问题。

3.1 UART 协议基础

UART 是异步串行通信。什么叫异步?就是没有单独的时钟线。收发双方得事先约好一个「节奏」——波特率。我遇到过有人把 115200 配成 9600,日志全是乱码,还以为是芯片坏了。

UART 烧录一般只用三根线:TX、RX、GND。有些板子还要加上 DTR/RTS 做自动复位和 Boot 模式切换。

参数常见值烧录时的坑
波特率9600 / 115200 / 921600两边不一致 → 乱码或超时
数据位8极少用 7 位,别乱改
停止位12 停止位偶尔用,但烧录器默认 1
校验位None开了校验但芯片不支持 → 无响应
流控None硬件流控没接对应引脚 → 卡死

我的习惯:调试阶段先用 115200 8N1,这是最通用的配置。如果日志出现连续相同的 0x00 或 0xFF,先量 TX 引脚电平——大概率是线没接对或者芯片没上电。

UART 烧录的典型流程:上位机发特定同步头(比如 0x7F),芯片 Bootloader 收到后回 ACK,然后开始传固件数据。日志里看到 Sync OK 说明握手过了,后面再报错就是数据帧的问题。

3.2 SPI 协议基础

SPI 是同步串行,有专门的时钟线(SCLK)。主设备产生时钟,从设备跟着节奏走。SPI 烧录通常用四根线:SCLK、MOSI、MISO、CS(片选)。

SPI 比 UART 快得多,适合大固件。但它的坑也不少。

  • 极性和相位(CPOL / CPHA):模式 0 到模式 3,烧录器和芯片必须匹配。我见过最离谱的一次,两边都是模式 0,但 CS 拉低时机差了半个时钟周期,数据全错位。
  • 片选控制:CS 必须在整个数据包传输期间保持低电平。有些上位机驱动在每字节之间拉高了 CS,芯片直接复位接收状态机。
  • 时钟频率:芯片 Bootloader 的 SPI 时钟通常有限制,不是主设备能跑多快就设多快。超过 20 MHz 经常丢数据。

我曾经踩过的坑:用 SPI 烧录一块新板子,日志报 CRC Error。查了两天,最后用示波器一看,MISO 线上的数据在时钟下降沿跳变,但芯片是在上升沿采样的。CPHA 差了一拍,所有字节都右移了一位。

3.3 I2C 协议基础

I2C 也是同步串行,但只用两根线:SCL(时钟)和 SDA(数据)。它是半双工的,主设备通过设备地址选择从机。

I2C 烧录在 EEPROM、传感器类芯片里很常见。它的特点是有 ACK/NACK 机制——每个字节后面接收方都要回一个应答位。

日志里常见的 I2C 错误:

  • NACK on address:芯片没响应。地址错了,或者芯片处于复位状态。
  • NACK on data:芯片收到了数据但没法处理。可能是写保护、忙状态、或者不支持该命令。
  • Clock stretching timeout:芯片拉低 SCL 表示「我还没准备好」,但主设备等太久了。
I2C 速度模式时钟频率适用场景
标准模式100 kHz兼容性最好,烧录首选
快速模式400 kHz大部分芯片支持,注意上拉电阻
高速模式3.4 MHz烧录器很少支持,别轻易用

我建议:I2C 烧录遇到问题,先量 SCL 和 SDA 的上拉电压。很多开发板忘了焊上拉电阻,或者上拉电阻太大导致信号上升沿太缓。100 kHz 下 4.7 kΩ 通常没问题。

3.4 SWD / JTAG 协议基础

这两种是调试接口,烧录只是它们的功能之一。JTAG 用 5 根线(TMS、TCK、TDI、TDO、nTRST),SWD 用 2 根线(SWDIO、SWCLK)。

SWD 是 ARM 公司搞的简化版,现在主流 Cortex-M 芯片都支持。JTAG 更通用,FPGA、DSP 也用它。

SWD 烧录的核心是 DP(Debug Port)和 AP(Access Port)。DP 负责协议层,AP 负责访问芯片内部的总线和存储器。日志里看到 DP IDR 读出来是 0x2BA01477 之类的值,说明 SWD 通信已经通了。

JTAG 的边界扫描(Boundary Scan)在烧录时用得不多,但调试断点、单步执行全靠它。我遇到过 JTAG 链上有多个器件,IDCODE 读出来全是 0xFFFFFFFF——原来是 TDI 到 TDO 的链路断了。

注意:SWD 和 JTAG 的引脚通常和 GPIO 复用。如果芯片固件把 SWDIO 配成了普通输出,调试器就连不上了。解决办法是拉高 nRESET 的同时发送 SWD 连接序列,或者用硬件复位让芯片回到默认状态。

3.5 协议对比与选型建议

协议线数速度典型烧录场景日志常见报错
UART3慢(~1 Mbps)MCU Bootloader超时、乱码、Sync 失败
SPI4快(~50 Mbps)Flash、大固件CRC 错误、片选异常
I2C2中(~400 kbps)EEPROM、小固件NACK、时钟拉伸超时
SWD2快(~10 Mbps)ARM MCU 调试烧录IDR 读不到、连接失败
JTAG5快(~50 Mbps)FPGA、DSP、多器件链IDCODE 异常、TDO 无输出

选协议其实看芯片和工具链。ST 的芯片用 UART 串口烧录最方便,但速度慢;用 SWD 快,但需要调试器。我个人习惯:开发阶段用 SWD,量产用 UART 或 SPI,因为 SWD 引脚少、速度快,量产时 UART 的线更少、成本更低。

总结一下:协议基础是烧录日志分析的「底层语言」。你看到 Timeout,脑子里要立刻反应——是波特率不对?时钟极性反了?还是地址没对上?这些判断都来自对协议细节的理解。下一层,我们就要拿着这些知识去读真正的烧录日志了。