第1章:SPI协议概述——什么是SPI?它的起源与特点
说起SPI,搞嵌入式的人没有不知道的。说白了,它就是一块主芯片和几个外设之间的“传话筒”。我最早接触SPI是十几年前调试一个MCP3204 ADC芯片,那时刚入行,看着示波器上四条信号线来回跳,死活不明白为什么数据会错位。后来才知道,原来是时钟极性和相位没配好——嗯,这坑我至今记忆犹新。
1.1 什么是SPI
SPI 的全名是 Serial Peripheral Interface,串行外设接口。它是个同步串行通信协议,专门用来让微控制器和传感器、存储器、显示屏这类外设交换数据。
你想想看,为什么叫“接口”不叫“总线”?因为 SPI 通常是主从一对一的连接,不需要地址寻址——当然,也可以挂多个从机,靠片选线切换。我个人习惯把 SPI 理解成“四根绳子拉的通信”:时钟线、两根数据线和一根片选线,主设备拉着绳头,从设备跟着节奏走。
1.2 SPI 的起源
SPI 是 Motorola 在上世纪 80 年代推出的,最初用在 MC68HC11 系列单片机里。那时芯片引脚贵啊,Motorola 的设计师想找个比 8 位并行更省引脚、但速度又够快的方案。于是 SPI 诞生了——只占四根线,却能跑到数兆赫兹。后来这个接口被各芯片厂商广泛采纳,成了事实标准。
我记得读一份上世纪的老手册时看到,Motorola 当时还专门写了一份应用笔记,里面画了完整的 SPI 时序图。那时候没有逻辑分析仪,全靠看示波器波形数时钟。现在我们有各种调试工具,但原理还是那些原理。
1.3 SPI 的核心特点
| 特点 | 说明 |
|---|---|
| 全双工 | 发送和接收可以同时进行,不浪费时钟周期 |
| 主从架构 | 只有一个主设备主动控制时钟,从设备被动响应 |
| 同步 | 所有操作由主设备提供的时钟信号驱动 |
| 无应答机制 | 发送方不保证接收方“读到了”,可靠性靠协议上层处理 |
| 高速率 | 典型时钟频率可达 10 MHz 以上,远快于 I²C 和 UART |
跟 I²C 和 UART 比,SPI 的优势是速度。但缺点也很明显——没有流控,没有确认,多从机时每加一个设备就要多一根片选线。我在一个项目中曾经挂了四个传感器,结果主芯片的 GPIO 被片选占掉好几个,布线时真头疼。
1.4 信号线与连接方式
SPI 用四根信号线:
- SCLK(串行时钟):由主设备产生,控制数据移位的节奏。
- MOSI(主出从入):主设备发送数据给从设备。
- MISO(主入从出):从设备发送数据给主设备。
- SS(从设备选择,也叫 CS):低电平有效,选中哪个从设备,哪个就工作。
连接方式很简单:主设备的 MOSI 连所有从设备的 MOSI,MISO 同理,SCLK 共享,SS 分别接主设备的 GPIO 引脚。每个从设备独占一根片选线。
// 一个简单的 SPI 初始化示例(基于 STM32 HAL 库)
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL = 0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA = 0
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
HAL_SPI_Init(&hspi1);
}
小技巧: 我个人的习惯是先用逻辑分析仪抓 CS 信号看有没有正常拉低,再对比手册上的时序图检查极性和相位。如果从设备数据手册里给了时序参数,直接在示波器上测量建立时间(tsu)和保持时间(th)有没有满足。省事又靠谱。
警告——我曾经踩过的坑: 有一次我在 SPI 通信里没有处理好 CS 信号的释放时机。主设备发送完最后一个字节后,CS 立刻拉高,结果从设备内部的移位寄存器还没完成数据锁存,整个通信得重来。后来我加了几个 NOP 的延时,确保最后一个时钟沿之后留够时间再拉高 CS。切记:CS 的释放时序跟 CPHA 配置有直接关系,一定要卡准。
1.5 典型应用场景
- SD 卡/MMC 卡: 通过 SPI 模式读取文件系统。
- OLED 显示屏: 很多小屏驱动芯片(如 SSD1306)支持 SPI 接口,速度快于 I²C。
- 射频模块(RFID、WiFi、BLE): SPI 是芯片间高速数据交换的首选。
- ADC/DAC: 高精度模数/数模转换器常用 SPI 输出采样值。
- 存储器(EEPROM、Flash): 几乎所有的 SPI Flash 都是四线制,读写速度达几十 MHz。
你想想看,SPI 之所以用在这么多场景,核心原因就是一个字:快。而且实现简单——主设备给时钟,数据就乖乖移位。但简单不等于容易,调试时常常因为时序细节翻车。
1.6 SPI 协议知识图谱
下面这张图把本章的核心知识串起来了:SPI 的起源、特点、信号线、四种模式和应用场景,画个框架方便你脑子里有个整体印象。
这张图里,起源、核心特点、四根信号线、时钟相位/极性的四种组合、典型应用和调试要点都画在了一起。你在学习后续章节时随时可以回头看看,想想每个知识点在图上处于哪个分支。
1.7 小结
- SPI 是同步、全双工、主从串行接口,由 Motorola 在 80 年代提出。
- 核心四线:SCLK、MOSI、MISO、SS(CS)。
- CPOL/CPHA 决定时钟空闲电平和采样边沿,四种组合必须配对。
- 无内置应答机制,上层协议需要自行保证数据完整性。
- 调试时优先看 CS 时序,再对极性和相位,最后量建立/保持时间。