串行通信三兄弟 · UART / I2C / SPI
嵌入式/工控里最常用的三种串行总线:原理、接线、时序、坑。写作用,边看边用。
⌕
输入关键词实时过滤下方章节。
★一句话总览
先记住各自最本质的区别。
- UART:点对点打电话,两根线,没有时钟,靠约定好的"语速"(波特率)对齐。
- I2C:一条总线挂一堆小弟,两根线,靠"地址"点名,速度慢但省线。
- SPI:老板直接喊名字发数据,四根线,全双工又最快,但线多。
一UART(异步串口)
最简单,点对点。
接线(交叉)
MCU_A TX ──── RX MCU_B MCU_A RX ──── TX MCU_B GND ─────────── GND (A 的发送接 B 的接收,TX/RX 交叉)
原理
- 没有时钟线,收发双方各自用自己的时钟,但"语速"必须一致(波特率,如 9600、115200)。这就是"异步"的含义。
- 空闲时 TX 保持高电平;发数据时先拉低一位(起始位),按位发数据(LSB 先发),最后拉高(停止位),可加校验位。
- 帧格式:起始位(0) + 数据位8 + 停止位(1),空闲 = 1。
- 全双工:TX/RX 独立,可同时收发。
特点
- 最少只要 2 根线 + GND;点对点为主(TTL 电平一般只连两个设备)。
- 速度:常见 9600 ~ 115200bps,快可达几 Mbps,距离越远越慢。
- 物理层可变形:RS232(±12V,电脑串口)、RS485(差分对,1200m,一主多从,工业最常用)。
- 没有寻址概念,485 总线靠"问一句答一句"的轮询协议(Modbus-RTU)实现多机。
典型应用
调试打印(printf 重定向)、GPS/蓝牙/4G 模块、AT 指令;工控里:触摸屏与 PLC、串口屏、扫码枪、RS485 仪表。
常用坑
- 两边波特率必须一致,误差最好 <2%。
- TX 接 RX,接反了没反应。
- STM32 HAL:HAL_UART_Transmit(&huart1, buf, len, timeout)
二I2C(IIC,两线串行)
线最少,一个总线挂一堆从机。
接线
5V ── 4.7k ──┬── SCL (上拉电阻,典型 4.7k,快速模式 2.2k/1k)
└── SDA
MCU SCL ──── SCL 从机1 从机2 从机3 ...
MCU SDA ──── SDA (每个从机有唯一 7 位地址)
原理
- 半双工:SCL 是主机产生的时钟,SDA 传数据,同一时刻只能一个方向。
- 开漏输出 + 上拉电阻:谁都不拉 = 高,想发 0 就拉低("线与"基础,必须有上拉电阻)。
- 时序要素:起始条件(SCL 高时 SDA 下降沿)→ 发地址+读写位 → 从机应答 ACK → 数据字节(每字节后从机拉低 ACK)→ 停止条件(SCL 高时 SDA 上升沿)。
- 多从机靠地址区分:主机广播地址,只有地址匹配的从机应答;一主多从最常见,也支持多主机(总线仲裁)。
特点
- 2 根线可挂几十个器件,地址寻址,加设备只并线不增线。
- 慢:标准 100kbps,快速 400kbps,高速 3.4Mbps。
- 距离最短(板内 1m 以内),线长/器件多会让波形变钝,速率上不去。
- 软件模拟容易(GPIO 翻转即可),对时序有一定要求。
典型应用
EEPROM(AT24C02/04)、RTC(DS3231/PCF8563)、温湿度/气压传感器、OLED 屏(SSD1306)、ADC/DAC、加速度计。
常用坑
- 忘加上拉电阻 → 通讯完全不通;上拉太小或器件太多 → 波形变钝。
- 地址冲突(两个器件同地址,如 0x50 的 EEPROM 和某传感器)。
- 从机忙时会回 NACK,软件要处理重试。
- STM32 HAL:HAL_I2C_Mem_Write(&hi2c1, addr, reg, size, buf, len, timeout)
三SPI(同步串行外设接口)
最快,全双工。
接线(一主一从)
MCU SCLK ──── SCLK 时钟(主机产生) MCU MOSI ──── MOSI 主机出→从机入 MCU MISO ──── MISO 从机出→主机入 MCU CS ──── CS 片选(低电平有效) GND ──── GND 一主多从:SCLK/MOSI/MISO 并联共享,每个从机单独一根 CS
原理
- 本质是"环形移位寄存器":主机发一位的同时从机也回一位,天然全双工。
- 同步:所有动作跟 SCLK 走,没有波特率概念,速度由主机决定。
- 4 种模式(CPOL 时钟极性 + CPHA 相位)决定数据在哪个边沿采样,主从必须一致(常用 Mode 0:空闲低、上升沿采样)。
- 从机完全被动:主机拉低 CS 并给时钟它才能收/发,不能主动说话。
- 没有标准应答/地址机制,数据格式全靠自己约定。
- 读操作套路:拉低 CS → 发"读命令+地址" → 发假数据顺便收数据 → 拉高 CS。
特点
- 快:轻松几十 Mbps(STM32 SPI 分频后 18~36Mbps),是 I2C 的百倍级。
- 全双工、协议开销最小(纯移位,想发啥发啥)。
- 线多(至少 4 根,多从机更多),距离短(板内 ~10cm~1m)。
- 从机数量受限于 CS 引脚(或用 GPIO 扩展 / 菊花链)。
典型应用
Flash(W25Q64 等)、SD 卡、TFT 屏、高速 ADC、热电偶(MAX6675)、CAN 控制器(MCP2515)、以太网芯片。
常用坑
- 模式不匹配(CPOL/CPHA 错)→ 数据全乱,检查主从 Mode 是否一致。
- CS 拉高/拉低顺序不对 → 从机不响应。
- 读数据要先发假字节"把时钟敲起来"才有 MISO 数据。
- STM32 HAL:HAL_SPI_TransmitReceive(&hspi1, tx, rx, len, timeout)
四三者对比
一张表记住差异。
| 项目 | UART | I2C | SPI |
|---|---|---|---|
| 线数 | 2+地 | 2+地(需上拉电阻) | 4+地(每从机多 1 根 CS) |
| 方向 | 全双工 | 半双工 | 全双工 |
| 时钟 | 无(异步,约定波特率) | SCL(主机产生) | SCLK(主机产生) |
| 速度 | 低~中 | 低(100k/400k/3.4M) | 高(几十 M) |
| 多设备 | 点对点(RS485 可多机) | 地址寻址,最多挂几十个 | 片选寻址,受 CS 引脚限制 |
| 距离 | TTL 短 / RS485 很长 | 最短(板内) | 短(板内) |
| 从机主动 | 可(全双工随时发) | 不可(等主机叫) | 不可(等主机拉 CS) |
| 应答机制 | 无 | 每字节 ACK/NACK | 无(自定义协议) |
| 典型场合 | 调试/模块/RS485 仪表 | 传感器/EEPROM/RTC/OLED | Flash/屏/SD/ADC |
五怎么选(嵌入式/工控角度)
按需求对号入座。
- 调试打印、和电脑/屏/模块对话 → UART
- 板上挂一堆慢速器件、想省引脚 → I2C(EEPROM、温湿度、RTC)
- 要速度、传大量数据、读写 Flash/屏 → SPI
- 工业现场长距离多机、抗干扰 → RS485(UART 物理层)或 CAN(带冲突仲裁,RS485 没有仲裁只能主问从答)
✅
一句话记忆。UART 靠"语速约定"点对点;I2C 靠"地址点名"省线;SPI 靠"片选点名 + 全双工"最快。
六注意事项
实战经验。
💡
波特率。UART 波特率误差最好 <2%,115200 配 115200,别配成 115200 对 9600。
✅
排查顺序。通讯不上先查:共地(GND 必须连)→ 接线(TX/RX 交叉、MOSI/MISO 别接反)→ 电平(3.3V 对 5V 是否要转换)→ 参数(波特率/模式/地址)。
⚠️
I2C 忘加上拉 = 全灭。新板子 I2C 不通,90% 是上拉电阻没焊或者焊错值。
⚠️
SPI 模式。CPOL/CPHA 主从不一致时数据"看起来对但全错",先确认从机数据手册要求的 Mode。
没有匹配的内容,换个关键词试试。