SPI基础
一、SPI 的一些基础概念
1.1 SPI 是什么
SPI(Serial Peripheral Interface,串行外设接口)是一种同步串行通信协议,主要用于嵌入式系统中微控制器与各种外设之间的短距离高速通信。
SPI 由 Motorola 公司在 1983 年开发,最初用于其 6805 系列 8 位微控制器。
Motorola 设计 SPI 的初衷,是为了解决微控制器与外围设备(如存储器、显示屏、ADC/DAC 等)之间的高效、可靠、同步数据传输需求。
Motorola 最初在 1983 年发布的 6805 系列微控制器手册中描述了 SPI 的基本功能。
随后,Motorola 于 1987 年发布了应用笔记 AN991《Using the Serial Peripheral Interface to Communicate Between Multiple Microcomputers》,这份文档长期被业界视为 SPI 的“非正式官方定义”。
在这之后,SPI 总线并没有像 I²C、USB 等总线那样建立一个正式的、由标准化组织维护的协议标准,而是成为了一个事实标准(De facto Standard)。
这意味着两点:
(1)SPI 没有官方的国际标准化组织(如 ISO、IEC、JEDEC 等)对 SPI 进行正式标准化。
(2)各芯片厂商和开发者根据 Motorola 最初的技术文档和应用笔记,可以实现 SPI 接口兼容,但细节上可能略有差异。
现在应用广泛的 SPI LCD 接口,SPI camera 接口,就是原始 SPI 接口的变种。
合宙 780EPM 模组,支持 2 路标准 SPI,还支持一路 SPI LCD,以及一路 SPI Camera,一共 4 路 SPI。
1.2 SPI 和 GPIO 的关系
SPI 本质上也是一种 GPIO 的应用。
标准的 SPI 有 4 跟信号线:
(1)片选(CS 或者 SS);
(2)时钟,SCLK;
(3)主发从收(MOSI);
(4)主收从发(MISO)。
图1 SPI 总线的4根信号线
和 onewire 和 I2C 总线把 GPIO 作为开漏输出不同的是, SPI 的这四个信号线,都使用推挽输出,在支持推挽输出的同时,又支持高阻态模式,这也被称为三态输出。
把 GPIO 作为三态输出,好处是 GPIO 的通信速度比开漏输出更快,同时从设备处于高阻态模式下,可以避免干扰总线。
因为不需要做信号线的抢占和仲裁,所以 SPI 总线,不需要使用开漏输出。
1.3 串行通信和并行通信
电子设备通过物理连接的导线以位(bit)的形式传输数据。
位类似于单词中的字母,但不是 26 个字母,而是二进制数字,仅能表示 1 或 0。
数据位通过快速电压变化从一个设备传输到另一个设备。
在工作电压为 5V 的系统中,0 位用 0V 的短脉冲表示,1 位用 5V 的短脉冲表示。
数据可以以并行或串行形式传输:
(1)并行通信:数据位同时通过独立导线传输。
如图 2 所示。
并行通信的有点是同时传输多个数据,通信的速率很高;
缺点是需要的信号线数量多,电路设计复杂,对抗干扰的要求有比较高。
高分辨率摄像头,高分辨率的屏,大容量存储,一般都采用同步通信方式。
(2)串行通信:数据位逐个通过单根导线传输。
如图 3 所示。
串行通信的优点是需要的信号线数量少,缺点是通信速率不如并行通信。
所以串行通信一般适用于小分辨率的屏,小分辨率的摄像头,小尺寸的存储器等。
图2 并行通信
图3 串行通信
1.4 同步通信和异步通信
1.4.1 同步通信
任何使用时钟信号,给数据传输的信号做时序参考的通信协议都称为同步协议,例如 SPI。
在同步通信的系统里面,通信的各方根据时钟信号的波形变化的时间,再去取样信号线的值,从而拿到有效的数据;
额外花费一根信号线做时钟信号,使得同步通信系统的可靠性有了保障,通信双方的信息不容易乱序。
1.4.2 异步通信
不使用时钟信号的方法则称为异步协议,例如 UART。
在异步通信系统里面, 首先要根据预先约定的波特率,直接判断信号线的取样时间点,对信号线进行抽样,得到有效的数据;
其次,因为没有信号线,所以信号线的取样会有偏差的风险,所以会往往会在通信的过程中,引入帧或者包的概念,把若干个 bit 组成一帧,把帧作为通信的最小单元,每一帧加上起始信息,结束信息,以及校验信息,方便通信的双方进行解码和纠错。
二、SPI 通信的基本原理
2.1 SPI 的主从设备关系
SPI 的通信是主从架构,一个主设备,跟多个从设备通信。
SPI 协议层面没有总线仲裁、冲突检测等机制,所以 SPI 系统不适合存在多个主设备。
2.1.1 从设备的数量
(1)双向收发的场景 对于 SPI 双向通信的场景,主设备和从设备之间,可以共享同一个 SCK,共享同一个 MOSI,共享同一个 MISO,但是需要有单独的 CS 片选信号线。 也就是说,主设备同时驱动多个 CS 线,对接多个从设备。
图 4 独立的连接方式
这种场景,由于主设备往往不太可能有非常多的信号线,所以一个双向通信的的 SPI 系统,从设备的数量往往不超过 4 个。 (2)只发不收的场景 对于仅仅需要主设备发送数据不接收数据的场景,可以采用菊花链的链接方式,如图 5 所示
图5 菊花链的连接方式
这种连接方式,可以连接更多的从设备,一般会接入 10-63 个从设备,极限情况下可以上百个从设备。
本文介绍的主要是双向收发,独立做片选连接的场景。
菊花链的连接方式,本文不做介绍。
2.1.2 从设备的地址
SPI 系统里面,由于是通过片选线来直接控制从设备,所以不需要从设备的地址。
2.2 SPI 的信号线介绍
SPI 有 4 个信号线,如图 6 所示。
图6 SPI 的4个信号线
2.2.1 片选线 CS
CS 全称为 Chip Select,在有些场合也称为 SS(Slave Select)。
在空闲的时候,主设备把所有 CS 线拉高,同时,所有的设备的 MISO 保持高阻态。
主设备需要跟哪个设备通信的话,就把哪一台从设备的 CS 线拉低,这样从设备就知道自己被选中了。
当某个从设备的 CS 被拉低,该设备的 MISO 才能够输出高电平或者低电平进行通信,CS 没有被拉低的设备的 MISO 依然保持高阻态。
同一个时间,只会有一个从设备的 CS 会被拉低。
对从设备来说,CS 只能是输入状态。
2.2.2 时钟线 SCLK
SCLK 线只能由主设备驱动,对从设备来说,SCLK 只能是输入状态。
空闲状态下,主设备把SCLK 保持高电平,或者保持低电平,这取决于 SPI 系统的 CPOL 参数(2.4.1节介绍)的配置。
2.2.3 主发从收 MOSI
MOSI 信号线用于主设备向从设备发送数据。
所以从设备共享同一个MOSI信号线。
由于只有一个主设备,没有总线冲突的风险,所以MOSI在空闲的时候,无需设置为高阻态,只需要保持为上一个通信的状态即可。
2.2.4 主收从发 MISO
在空闲状态下,所有从设备把 MISO 置为高阻态;
当某个从设备被选中后,该从设备开始用MISO进行高电平或者低电平的输出,向主设备发送数据。
2.3 SPI 总线的通信速率
SPI 总线的通信速率范围很广,通常在 1 MHz 到 100 MHz 之间,常见速率为 1 MHz、5 MHz、10 MHz、20 MHz。
SPI 总线的通信速率,由主设备通过在 SCLK 体现,从设备通过读取 SCLK 的电平变化,从而遵守同样的通信速率。
合宙 Air780EPM 模组,最高支持 25.6Mbps 的 SPI 速率。
2.4 SPI 通信的模式
SPI 通信共有四种工作模式,分别是模式 0,模式 1,模式 2,模式 3。
这四种模式,是由“时钟极性(CPOL)”和“时钟相位(CPHA)”两个参数组合决定的,具体定义如下:
2.4.1 时钟极性(CPOL)
CPOL 是 Clock Polarity 的缩写;
CPOL 决定时钟SCK在空闲时的电平状态:
2.4.2 时钟相位(CPHA)
CPHA 是 Clock Phase 的缩写。
CPHA 定数据采样的时钟边沿:
2.4.3 SPI 四种模式详解
SPI 的四种模式的解释,参见下表:
模式号 | CPOL | CPHA | SCK空闲电平 | 采样时刻 | 说明 |
0 | 0 | 0 | 低电平 | 上升沿(第1边沿) | 数据在SCK上升沿采样,下降沿切换。常用,许多外设默认模式。 |
1 | 0 | 1 | 低电平 | 下降沿(第2边沿) | 数据在SCK下降沿采样,上升沿切换。 |
2 | 1 | 0 | 高电平 | 下降沿(第1边沿) | 数据在SCK下降沿采样,上升沿切换。 |
3 | 1 | 1 | 高电平 | 上升沿(第2边沿) | 数据在SCK上升沿采样,下降沿切换。常用,部分外设默认模式。 |
第一个边沿:指片选有效后,SCK 从空闲电平跳变的第一个边沿(CPOL=0 为上升沿,CPOL=1 为下降沿)。
第二个边沿:指片选有效后,SCK 从空闲电平跳变的第二个边沿。
2.4.4 总结
这四种模式用于适配不同外设对时序的要求,确保数据在主从设备间可靠传输。
主从设备必须工作在相同模式下,否则数据会采样错误。
常用模式为模式 0(CPOL=0, CPHA=0)和模式 3(CPOL=1, CPHA=1),但具体以外设手册为准。
SPI 模式的选择通常在软件初始化时配置。
CPOL 和 CPHA 参数,是在 SPI 系统初始化的时候,预先设定的参数。
三、SPI 通信的过程
3.1 主设备生成时钟信号
2.2 主设备将 SS/CS 引脚切换到低电压状态,激活目标从设备
2.3 主设备通过 MOSI 一次发送一位数据,从设备逐位读取
2.4 如果需要响应,从设备通过 MISO 一次返回一位数据,主设备逐位读取
四、SPI 总线的典型电路
SPI 总线的电路设计,参见如下链接:
http://docs.openluat.com/air780epm/luatos/hardware/design/spi/。
五、SPI 的供电方式
SPI 不提供总线供电方式,主设备和从设备,都需要单独的电源供电。