嵌入式面试高频考点:SPI 为什么比 I2C 快?CPOL/CPHA 到底怎么定?ADXL345 的"写即是读"是什么意思?本文基于一份 SPI 学习笔记整理,把协议原理和传感器驱动串起来。
一、SPI 是什么:四线制、全双工、同步
SPI(Serial Peripheral Interface)是一种串行、同步、全双工的通信总线,标准接法为四线制:
- SCLK:时钟线,由主机产生
- MOSI:Master Output Slave Input,主出从入
- MISO:Master Input Slave Output,主入从出
- CS/SS:片选线,拉低代表选中某个从机
对比 I2C:
| 维度 | I2C | SPI |
|---|---|---|
| 速率 | 100 kHz / 400 kHz | 几 M ~ 几十 M |
| 双工 | 半双工 | 全双工 |
| 寻址 | 从机地址 | CS 拉低选中 |
| 线数 | 2(SCL/SDA) | 4(SCLK/MOSI/MISO/CS) |
SPI 没有 ACK 机制,靠硬件时序保证;主机写 1 字节的同时必然从 MISO 收回 1 字节,这就是常说的"写即是读,读即是写"。
二、CPOL 与 CPHA:四种工作模式
SPI 时序由两个条件决定:
- CPOL(Clock Polarity)时钟极性 :空闲时 SCLK 是高还是低
- CPOL=0:空闲低电平
- CPOL=1:空闲高电平
- CPHA(Clock Phase)时钟相位 :接收方在第几个边沿采样
- CPHA=0:第一个边沿采样(注意:第一个边沿是上升还是下降,取决于 CPOL)
- CPHA=1:第二个边沿采样
四种组合:
| 模式 | CPOL | CPHA | 空闲电平 | 采样边沿 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低 | 上升沿(第一个边沿) |
| Mode 1 | 0 | 1 | 低 | 下降沿(第二个边沿) |
| Mode 2 | 1 | 0 | 高 | 下降沿(第一个边沿) |
| Mode 3 | 1 | 1 | 高 | 上升沿(第二个边沿) |
主机模式必须与从机芯片手册一致,否则采样错位、通信乱码。
三、以 ADXL345 为例看 SPI 读写
ADXL345 是三轴数字加速度传感器,支持 I2C 和 SPI,作从机时 SPI 要求 CPOL=1, CPHA=1(Mode 3),即空闲 SCLK 为高,上升沿采样。
引脚连接(笔记记录):
- P417 → CS
- P418 → SCL(即 SCLK)
- P419 → SDO(MISO)
- P420 → SDA(MOSI,4 线制下作 SDI)
关键参数:
- 分辨率:13 位(0 ~ 8191)
- 加速度范围:±16 g(1 g ≈ 9.8 m/s²)
- 工作电压:2 V ~ 3.6 V
- 灵敏度:32 g / (2¹³−1) ≈ 0.0039 g / LSB
- 例:原始值 123 → 123 × 0.0039 ≈ 0.48 g
写操作
拉低 CS → 通过 MOSI 发寄存器地址(MSB=0 表示写)→ 继续发数据字节。
例如写寄存器 0x23:00100011 = 0x23,从机同时在 MISO 回数据(可忽略)。
读操作
拉低 CS → 通过 MOSI 发寄存器地址(MSB=1 表示读)。
例如读 0x23:10100011 = 0xA3 → 主机继续发 dummy(0x00 或 0xFF)提供时钟 → 从机通过 MISO 回传感器数据。
这就是"写即是读,读即是写":每个 SCLK 周期主从各移 1 位,主机发地址/哑元的同时,从机把数据移出来。
四、SPI 调试小贴士
- 通信全 0xFF:多半 CPOL/CPHA 不匹配,逻辑分析仪抓 SCLK 与 MOSI 比对手册时序图。
- ADXL345 上电后、改 CPOL/CPHA 前,CS 应先拉高,避免进入错误时序。
- 多字节读写:设 MB 位后连续给时钟,指针自动移到下一寄存器;换不连续寄存器须先拉高 CS 重新寻址。
- SPI 时钟上限看器件,ADXL345 最大 5 MHz。
结语
SPI 本身不复杂,坑几乎都在"模式匹配"和"全双工交换"这两件事上。把 CPOL/CPHA 四种模式画一遍,再用 ADXL345 的 0x23 写、0xA3 读走一遍流程,面试被问 SPI 就不会虚。
版权声明:本文基于 SPI 学习笔记整理,遵循 CC 4.0 BY-SA 协议,转载请附原文出处链接。