什么是 SPI

和上一篇文章的 I2C 总线一样,SPI(Serial Peripheral Interface,串行外设接口)也是设备与设备间通信方式的一种。SPI 是一种全双工(数据可以两个方向同时传输)的串行通信总线,由摩托罗拉于上个世纪 80 年代开发[1],用于短距离设备之间的通信。SPI 包含 4 根信号线,一根时钟线 SCK(Serial Clock,串行时钟),两根数据线 MOSI(Master Output Slave Input,主机输出从机输入)和 MISO(Master Input Slave Output,主机输入从机输出),以及一根片选信号 CS(Chip Select,或者叫 SS,Slave Select)。所谓的时钟线就是一种周期,两台设备数据传输不能各发各的,这样就没有意义,因此需要一种周期去对通信进行约束;数据线就是按照 MOSI 和 MISO 的中文翻译理解即可;片选信号用于主设备选择 SPI 上的从设备,I2C 是靠地址选择设备,而 SPI 靠的是片选信号,一般来说要选择哪个从设备只要将相应的 CS 线设置为低电平即可,特殊情况需要看数据手册。下图展示了一个 SPI 主设备和三个 SPI 从设备的示意图。

图1:SPI 设备

SPI 还有一个重要的概念就是时钟的极性(CPOL,Clock Polarity)和相位(CPHA,Clock Phase),对其这里不过多解释,我们只需要知道极性和相位的组合构成了 SPI 的传输模式(SPI Mode)。在数据手册中,只要是 SPI 通信协议的,一定会给出传输模式,我们根据数据手册进行设置即可。SPI 的传输模式是有固定编号的,下表给出了各个模式,常用的模式有 Mode0 和 Mode3。

SPI Mode CPOL CPHA
Mode0 0 0
Mode1 0 1
Mode2 1 0
Mode3 1 1

图2:该时序图显示了时钟的极性和相位

SPI 相比较 I2C 最大的优点就是传输速率高,并且数据在同一时间内可以双向传输,这都得益于它的两根输入和输出数据线。当然缺点也很明显,比 I2C 多了两根线,这就要多占用两个 IO 接口。而且 SPI 采用 CS 线去选择设备,不像 I2C 有寻址机制,如果你有很多个 SPI 设备需要连接的话 IO 接口的占用数量是相当高的。

在 Raspberry Pi 的引脚中,引出了两组 SPI 接口。但有意思的是,在 Raspbian 中 SPI-1 是被禁用的,你需要修改一些参数去启用 SPI-1。SPI 接口的引脚编号如下图所示。