SPI协议
目录
一、理解SPI的优越性
二、SPI总线结构编辑
三、关于SPI时序的理解
(1)极性
(2)相位
(3)4种时序模式
(4)比特位的传输顺序
(5)数据宽度
四、SPI模块
一、理解SPI的优越性
之前我们已经学习过了UART和IIC协议,本篇文章将会介绍一种新的协议SPI协议。最开始我们学习的是UART协议,这种协议比较简单方便,但是缺点就是受限于物理硬件,无法让一台住家挂载很多从机。所以创造了IIC协议,它仅仅需要两根线,理论上就可以连接127台设备(7地址模式),但正是由于他仅有两根线,所以他是半双工通信协议。UART和IIC可以说是互补的存在,一个可以全双工通信,但是无法多连;另一个可以多连但是却无法全双工通信。于是乎人们为了综合两者的优势,创造了一种新的协议SPI协议。
SPI通常有3+N根线(时钟线SCK、主机输出从机输入线MOSI、主机输入从机输出线MISO、片选线CS*N),其中三根主要的线用于实现全双工通信和时序传递。但仅仅有三根通信线却无法满足多从机情况,所以多出来N根线用于片选,其中每一根线都连接一个从机,只有到片选线被选中的时候,从机才会和主机进行通信。
所以SPI虽然受限于CS片选线的个数,就就好像UART受限于两根通信线的组数一样,但是由于片选线可以是任意GPIO口,所以这个限制在实际应用中并不明显。所以SPI就兼具了他们两者的优点。
此外SPI的通信效率远远高于UART和IIC。这是因为UART没有时钟线进行同步,所以天然的就需要让双方的波特率放慢一些,且添加停止位、起始位来区分每一帧数据,并且能修正双方时序的差异。而IIC由于需要在真正通信前进行地址匹配,如果频繁切换通信,则会把大量时间浪费在地址匹配过程。SPI采取CS片选线来进行通信路径选取,极大程度的降低了地址匹配的繁琐,从而提高了传输效率。故而SPI通常用于对效率要求高的设备中,如Flash中。
二、SPI总线结构
对该图中名字的解释:
以主机选取从机一作为通信方,观察时序结构:
可以看到NSS1片选线置低电平了,然后SCK由主机发送时钟信号,从机在时钟信号的驱动下和主机互发消息。
三、关于SPI时序的理解
(1)极性
无论是在UART还是IIC协议中,都从未提到过极性这个概念。为什么SPI需要有呢?因为我们说SPI的速率远比IIC高,更高的速率也就意味着需要更好的稳定性。当数据线的电平快速发生切换的时候,很容易收到外部噪音影响,导致数据抖动,从而采样错误。
可以看到极性的意思就是在空闲时候,SCK时钟是高电平还是低电平,是高电平则称之为高极性;低电平则称为低极性。而不同的极性导致在数据传输期间,SCK时钟线的电平出现完全相反的情况。不同设备对时序的要求不同,例如,某些Flash芯片可能要求在时钟下降沿采样,以避免上升沿噪声干扰;而某些传感器芯片可能更适合在上升沿采样,以优化信号完整性。这就要求我们正确的配置SPI主机的时序极性。
(2)相位
相位指的是在时钟信号的第一边沿还是第二边沿进行数据采集。
相位通常需要和极性搭配使用,当极性为低的时候,通信过程中第一次时钟信号将是上升沿,如果从设备在下降沿才采取数据,则会导致第一位数据丢失,然后主设备在时钟线下降的时候发送第二位数据,然后该从设备才开始采集数据,就会造成数据读取的不确定性,甚至于错误。
而相位如果设置为第二边沿采集则能延迟采集数据的时间点来达到稳定数据的效果。我们在IIC中也有类似的操作,我们利用占空比来设置了SCK在一个时钟周期内的变化节点,从而让数据有一段时间的稳定性。而SPI的相位也是这个道理,设置为第二边沿采集则给数据线电平变化充足的时间。
虽然我们说发送方和接收方会在第二边沿瞬间发送和采集数据,但实际上不是这样的,如果真的是同时瞬间操作,则会采集到亚稳态,无法保证数据的可靠性。真实操作中,通过时序裕量设计,将发送与接收解耦为“提前准备”与“延迟采样”的非同步协作,而非边沿瞬间的严格同步。
关于这个,我的理解也停留在此,还有更深刻的时序裕量,大家有兴趣的可以自行搜索一下相关资料。
(3)4种时序模式
将上述的两个参数排列组合就可以得到四种模式。但是我们往往推荐使用模式1、模式3、即在第二边沿读取数据。
其核心优势源于以下四方面:
- 发送方提前准备,消除信号切换冲突
- 接收方延迟采样,规避亚稳态风险
- 硬件时序裕量显著扩大
- 对信号完整性要求更宽松
但是这种优势主要体现在第一次双方还未建立通信的时候,采取第二边沿检测可以让是中共信号、数据信号更加稳定。但是建立通信之后的后续时钟已经足够稳定了,第一边沿检测和第二边沿检测的差别几乎没有。
上面主要推荐大家使用第二边沿模式,但是关于边沿的极性还是得看各自芯片的要求。
至于IIC为什么不需要配置相位和极性,完全是因为IIC好像一个霸权主义者,已经固定好了一切,强迫你必须要在SCL的上升沿读取数据。
(4)比特位的传输顺序
比特位的传输顺序和计算机的大小端概念类似,决定了对方如何解析你的二进制信息,毕竟二进制信息颠倒过来含义就可能完全不相关。而UART和IIC中本来也是要面临这个配置的,但是由于IIC和UART出现的时间比较早,大家都已经完全认可他们,所以已经是标准化的东西了,而SPI则需要兼容各个厂商的不同策略,所以提供了接口让我们开发者能灵活配置大小端传输顺序。
(5)数据宽度
尽管SPI通信中通常使用MOSI(主出从入)和MISO(主入从出)两根数据线进行全双工数据传输,但数据宽度(Data Width)的差异会通过影响通信效率、资源占用、硬件复杂度等维度,直接导致系统性能的显著变化。
SPI数据宽度的核心约束直接来源于接收方移位寄存器的位数,这一硬件限制决定了单次通信的最大数据承载能力。所以如果从设备的移位寄存器一次能读取16位,你最好就设置为16位,而不要设置为8位。因为对于上层应用而言,8位也是从寄存器中读一次,16位也是读一次,时间开销是一样的。
四、SPI模块
虽然我们在上面已经深刻理解到了SPI的时序特点,但是他一定是基于某些硬件才能做到的,我们来看看:
但是这个模块和之前学习过的UART、IIC模块几乎一样,所以不再赘述。大家配置SPI模块的时候就是在配置这些地方