烧录协议基础:SPI、I2C、SWD 详解与选择策略

做烧录工具开发,绕不开的就是通信协议。你想想看,芯片不会说话,你得通过某种方式把固件塞进去。这个「方式」就是烧录协议。我个人习惯把协议分成两类:一类是芯片出厂自带的调试接口,比如 SWD;另一类是通用总线协议,比如 SPI 和 I2C,很多芯片的 Bootloader 都跑在这上面。

这一章咱们就把这三个协议掰开揉碎,讲清楚它们的时序、优缺点,以及什么时候该用哪个。

SPI 协议详解

SPI,全称 Serial Peripheral Interface,摩托罗拉发明的。说白了就是四根线搞定一切:SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)、CS(片选)。

它的核心特点就一个字——快。我做过一个项目,用 SPI 烧录 8MB 的固件,时钟跑到 40MHz,十几秒就完事了。换成 I2C 的话,同样的数据量得等好几分钟。

SPI 的关键参数:

  • 时钟极性(CPOL):空闲时时钟是高电平还是低电平
  • 时钟相位(CPHA):数据在时钟的上升沿还是下降沿采样
  • 片选极性:低电平有效还是高电平有效

这里有个坑。我曾经调试一块 Flash 芯片,怎么都读不到 ID。折腾了半天,发现是 CPOL 和 CPHA 没对上。芯片手册写的是 Mode 3(CPOL=1, CPHA=1),我默认用了 Mode 0。嗯,从那以后我每次都会先确认 SPI 模式。

SPI 模式 CPOL CPHA 采样沿 常见设备
Mode 0 0 0 上升沿 多数 Flash、SD 卡
Mode 1 0 1 下降沿 部分 ADC
Mode 2 1 0 上升沿 某些传感器
Mode 3 1 1 下降沿 多数 SPI Flash

小技巧:写烧录脚本时,建议把 SPI 模式做成可配置参数。不同批次、不同厂家的 Flash,模式可能不一样。硬编码会让你后期很痛苦。

I2C 协议详解

I2C 是 Philips 搞出来的,只有两根线:SCL(时钟)和 SDA(数据)。它比 SPI 慢,但胜在连线少,而且支持多设备挂载在同一总线上。

I2C 的通信过程很有意思。每次传输以 START 条件开始,以 STOP 条件结束。中间是地址+读写位,然后是数据。每个字节后面跟一个 ACK 应答位。

我记得第一次用 I2C 烧录 EEPROM 时,死活收不到 ACK。查了半天,发现是地址写错了。7 位地址左移了一位,加上读写位后整个就不对了。这种低级错误,犯过一次就再也不会犯了。

注意:I2C 的速率通常有 100kHz(标准模式)、400kHz(快速模式)和 1MHz(高速模式)。烧录场景下,建议用 400kHz 以下,稳定性更好。我曾经试过 1MHz 烧录,结果数据经常出错,降速后就稳了。

I2C 还有一个特点:它是开漏输出,需要外部上拉电阻。这个电阻值选不好,波形就会变形。我一般用 4.7kΩ,总线电容大的时候换成 2.2kΩ。

SWD 协议详解

SWD 是 ARM 公司搞的调试接口,全称 Serial Wire Debug。它只有两根线:SWDIO(数据)和 SWCLK(时钟)。相比传统的 JTAG(需要 5 根线),SWD 省了 3 根线,但功能一点没少。

SWD 协议的核心是 AP(访问端口)和 DP(调试端口)。DP 负责协议层,AP 负责访问芯片内部资源。烧录时,我们通过 DP 发送命令,通过 AP 读写 Flash 控制器寄存器。

SWD 烧录的基本流程:

  1. 连接目标芯片(发送 50 个时钟周期的线复位序列)
  2. 读取 DP-IDR 寄存器,确认芯片处于调试模式
  3. 配置 AP,选择要访问的 Flash 控制器
  4. 解锁 Flash(写入解锁序列)
  5. 擦除扇区
  6. 写入数据(按页写入)
  7. 校验数据
  8. 锁定 Flash

这里有个关键点:SWD 的时序非常敏感。我曾经在一条长线上跑 SWD,结果经常连接失败。后来加了 33Ω 的串联电阻,波形干净多了。嗯,做硬件调试就是这样,细节决定成败。

协议选择策略

三种协议各有千秋,选哪个得看具体场景。我整理了一张对比表,方便你快速决策。

对比维度 SPI I2C SWD
线数 4 根(含片选) 2 根 2 根
最大速率 50MHz+ 1MHz(高速模式) 10MHz+
多设备支持 需独立片选 地址寻址 单点对点
适用场景 大容量 Flash 烧录 小容量 EEPROM、传感器 ARM 芯片调试与烧录
协议复杂度 低 中 高

我的选择原则是这样的:

  • 如果芯片有 SWD 接口,优先用 SWD。它最稳定,功能最全,还能做调试。
  • 如果芯片只有 Bootloader,看 Bootloader 支持什么。多数芯片的 Bootloader 支持 SPI 或 I2C。
  • 如果追求速度,选 SPI。40MHz 的 SPI 比 400kHz 的 I2C 快 100 倍。
  • 如果引脚紧张,选 I2C 或 SWD。两根线搞定一切。

我的建议:做烧录工具时,最好三种协议都支持。用配置文件指定协议类型和参数,这样换芯片时只需要改配置文件,不用改代码。我现在的烧录框架就是这种设计,支持了 50 多种芯片,维护成本很低。

最后说一句,协议只是手段,不是目的。你的目标是稳定、快速地把固件烧进去。选协议时,多看看芯片手册,多测测波形,别想当然。

烧录协议选择决策流程 开始选择协议 芯片是否有 SWD 接口? 是 使用 SWD 协议 否 需要高速烧录? (>1MB 固件) 是 使用 SPI 协议 否 引脚紧张? (只能出 2 根线) 是 使用 I2C 协议 否 使用 SPI 协议 说明:实际选择还需考虑芯片手册、Bootloader 支持情况、硬件设计等因素