通信协议基础:串口通信(UART)、SPI协议、I2C协议、USB协议(HID/CDC)、协议选择策略
做烧录工具开发,说白了就是跟各种通信协议打交道。你想想看,芯片不会说话,你得通过某种方式把固件数据塞进去。这个「方式」就是通信协议。我这些年折腾下来,发现很多新手上来就纠结「哪个协议最好」,其实这是个伪命题。没有最好的协议,只有最合适的协议。
今天咱们就把烧录开发中常见的几种协议捋一遍。我会结合自己踩过的坑,给你讲讲它们各自的门道。
一、串口通信(UART)—— 最通用的后门
UART 这玩意儿,我估计你闭着眼睛都能说出个大概。但我要说的是,它在烧录场景下的特殊地位。
为什么烧录离不开 UART?
很多芯片出厂时,内部 Flash 是空的,这时候 SPI 或 I2C 接口还没初始化。但 UART 不一样,它往往是芯片 BootROM 里默认开启的接口。说白了,UART 是芯片留给你的「后门」。
核心要点:UART 烧录通常依赖芯片内置的 Bootloader。你只需要三根线:TX、RX、GND。波特率一般用 115200 或 921600。
我在项目中遇到过的问题:
- 波特率匹配问题:上位机设了 115200,但芯片内部晶振不准,实际跑出来可能是 115000 左右。结果就是数据错位。我的解决办法是:先发一个同步握手包,让双方校准时钟。
- 流控问题:有些芯片的 Bootloader 不支持硬件流控(RTS/CTS),但你上位机开了,就会导致数据发不出去。嗯,这里要注意,烧录场景下尽量用软件 XON/XOFF 流控,或者干脆不用。
避坑指南:我曾经因为 USB 转串口线质量太差,导致烧录成功率只有 60%。后来换了 FT232 芯片的线,问题就解决了。别小看这根线,它可能是你调试一整天都找不到原因的罪魁祸首。
二、SPI 协议 —— 速度与简洁的平衡
SPI 是我个人比较偏爱的协议。为什么?因为它简单粗暴,没有复杂的地址帧、应答机制。四根线(MOSI、MISO、SCLK、CS)搞定一切。
SPI 烧录的典型场景:
- 外挂 Flash 芯片(如 W25Q64)的烧录
- FPGA 配置数据的加载
- 某些 MCU 的 SWD 接口其实也是 SPI 的变种
你想想看,SPI 是全双工的,发送和接收可以同时进行。这意味着什么?意味着你可以在发送命令的同时,读取上一条命令的返回结果。这在烧录大数据量固件时,效率提升非常明显。
关键参数:时钟极性(CPOL)和时钟相位(CPHA)。这两个参数搞错了,数据读出来全是乱的。我建议你在代码里预留配置接口,方便调试时切换模式。
我曾经踩过的坑:有一次调试 SPI Flash 烧录,数据写进去读出来总是少几个字节。查了两天才发现,是 CS 片选信号的拉高时机不对。Flash 要求在最后一个时钟沿之后保持 CS 高电平至少 100ns,我代码里没加这个延时。嗯,细节决定成败。
三、I2C 协议 —— 两根线的艺术
I2C 只有两根线:SCL 和 SDA。但它比 SPI 复杂得多。为什么?因为它有地址、有应答、有起始条件和停止条件。
I2C 烧录的特点:
- 适合短距离、低速场景(通常 100kHz 或 400kHz)
- 支持多设备挂载,通过地址区分
- 硬件开销小,很多传感器和 EEPROM 都用它
我个人习惯在 I2C 烧录时,把速率降到 100kHz 以下。为什么?因为很多芯片的 I2C 接口在烧录模式下,时钟频率支持得不高。你强行跑 400kHz,可能就出现应答超时。
注意事项:I2C 的上拉电阻很关键。我见过有人用 10kΩ 上拉,结果总线电容太大,信号上升沿变缓,导致数据错误。一般建议 4.7kΩ,如果总线长度超过 20cm,可以考虑 2.2kΩ。
四、USB 协议(HID/CDC)—— 免驱的诱惑
USB 协议本身很复杂,但好在有现成的类驱动帮我们封装好了。烧录工具开发中,最常用的是 HID 和 CDC 两种。
| 特性 | HID | CDC(虚拟串口) |
|---|---|---|
| 驱动需求 | 免驱(系统自带) | Windows 需驱动,Linux/macOS 免驱 |
| 传输速度 | 低速(64 字节/包) | 中速(可达 1MB/s) |
| 可靠性 | 有握手,可靠 | 依赖底层,可能丢包 |
| 适用场景 | 小数据量、配置类 | 大数据量固件升级 |
我的选择建议:
- 如果产品需要跨平台(Windows/Linux/macOS),且不想折腾驱动签名,选 HID。
- 如果烧录的固件超过 100KB,且对速度有要求,选 CDC。
- 我最近的一个项目用了 HID,因为客户要求插上就能用,不能装任何驱动。虽然速度慢了点,但用户体验好。
避坑指南:我曾经用 CDC 做固件升级,发现 Windows 下每次拔插 USB 后,COM 口号会变。后来我在代码里加入了通过 USB 序列号(SerialNumber)来匹配设备,而不是依赖 COM 口号。这个问题就解决了。
五、协议选择策略 —— 怎么选才不后悔?
好了,四种协议都讲完了。你可能会问:「那我到底该用哪个?」
我总结了一个简单的决策流程,你可以参考:
- 看芯片支持什么:先查芯片手册,看它的 Bootloader 支持哪些接口。有些芯片只支持 UART,那就没得选。
- 看速度要求:固件小于 64KB?UART 或 I2C 都行。大于 1MB?上 SPI 或 USB CDC。
- 看线缆数量:产品空间有限,只能留两根线?I2C 或 UART。能留四根线?SPI 更稳。
- 看驱动要求:不想装驱动?HID 或 UART(系统自带串口驱动)。
- 看可靠性:烧录过程不能出错?加校验和重传机制,协议本身只是载体。
核心原则:不要为了用某个协议而用某个协议。我见过有人非要在 I2C 上跑 1MHz 时钟,结果信号都变形了。协议选择要综合考虑硬件能力、成本、开发周期。
六、知识体系总览
下面这张图,是我梳理的本章知识结构。你可以把它当作一个快速索引,以后遇到协议选择问题,回来看看这张图就行。
这张图把四种协议的核心特征和选择因素都串起来了。你以后做方案选型时,可以对着这张图快速过一遍,基本不会漏掉关键点。
好了,通信协议这块就讲到这里。每种协议都有它的脾气,摸透了就好办了。记住我一句话:协议是工具,不是目的。你的目的是把固件可靠地烧进去。