SPI 通信协议详解:从四线制到 ADXL345

嵌入式面试高频考点: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 协议,转载请附原文出处链接。

相关推荐
纯音乐sjc2 小时前
嵌入式面试复习准备
面试·嵌入式
ShineWinsu2 小时前
对于Git:基础操作的超详细保姆级解析
linux·c++·git·面试·备份·管理·版本控制器
晚安日记wanna3 小时前
Redis 持久化RDB 和 AOF 到底该怎么选
redis·面试·架构
潘潘的嵌入式日记5 小时前
位操作怎么写才不出错?置位、清位、翻转、取位一次讲清
c语言·嵌入式·寄存器·位操作
金士顿5 小时前
ASP.NET Core BackgroundService 深度解析:设备后台任务到底应该怎么设计
linux·嵌入式·asp.net core·arm64
嵌入式阿蔡6 小时前
CRA合规的工程化落地:SBOM、24小时响应与攻击面分析
嵌入式
小刘在重生~6 小时前
十六(3)、《集合扩充》CopyOnWriteArrayList 超详细解析(线程安全集合)
java·笔记·面试·职场和发展
嵌入式阿蔡7 小时前
工业物理AI 2026:从巡检机器人到AI原生工厂
嵌入式
XuCoder7 小时前
LangChain 模型调用:invoke、stream、batch 到底该怎么选?
面试