SPI协议详解
摘要
SPI(Serial Peripheral Interface)是一种同步串行通信协议,用于微控制器(MCU)和它们的外围设备(外设IC)之间或两个微控制器(MCU)之间的通信。
SPI通信是全双工的,意味着它可以同时发送和接收数据。,以其全双工、高速率和简单硬件结构优于UART。
SPI通信通常需要四根线:SCLK(时钟线)、CS/SS(片选线)、MOSI(主设备数据输出线)、MISO(主设备数据输入线),通过时钟极性和相位配置实现不同模式的通信。
SPI支持多从机模式,如多NSS或菊花链连接,但缺乏硬件级别的错误检查协议,并且通常仅支持一个主设备。在STM32等微控制器中,通过HAL库可以方便地实现SPI编程。
串口
UART是通用串行异步通信协议。
因为UART没有时钟信号,无法控制何时发送数据,也无法保证双发按照完全相同的速度接收数据。因此,双方以不同的速度进行数据接收和发送,就会出现问题。
如果要解决这个问题,UART为每个字节添加额外的起始位和停止位,以帮助接收器在数据到达时进行同步;
双方还必须事先就传输速度达成共识(设置相同的波特率,例如每秒9600位)。
传输速率如果有微小差异不是问题,因为接收器会在每个字节的开头重新同步。相应的协议如下图所示;
如果您注意到上图中的 11801010
不等于0x53
,这是一个细节。
串口协议通常会首先发送最低有效位,因此最小位在最左边 LSB
。低四位字节实际上是0011=0x3
,高四位字节是0101=0x5
。
异步串行工作得很好,但是在每个字节发送的时候都需要额外的起始位和停止位以及在发送和接收数据所需的复杂硬件方面都有很多开销。
不难发现,如果接收端和发送端设置的速度都不一致,那么接收到的数据将是垃圾(乱码)。
下面开始讲一下SPI协议,会有哪些优点。
SPI通信协议
于是我们想有没有更好一点的串行通信方式:相比较于 UART
,SPI
的工作方式略有不同。
SPI
是一个同步的数据总线,也就是说它是用单独的数据线和一个单独的时钟信号来保证发送端和接收端的完美同步。
时钟是一个振荡信号,它告诉接收端在确切的时机对数据线上的信号进行采样。
产生时钟的一侧称为主机,另一侧称为从机。总是只有一个主机(一般来说可以是微控制器/MCU),但是可以有多个从机(后面详细介绍);
数据的采集时机可能是时钟信号的上升沿(从低到高)或下降沿(从高到低),具体要看对SPI的配置;
整体的传输大概可以分为以下几个过程:
-
主机先将
NSS
信号拉低,这样保证开始接收数据; -
当接收端检测到时钟的边沿信号时,它将立即读取数据线上的信号,这样就得到了一位数据(1 bit);
由于时钟是随数据一起发送的,因此指定数据的传输速度并不重要,尽管设备将具有可以运行的最高速度(稍后我们将讨论选择合适的时钟边沿和速度)。 -
主机发送到从机时:主机产生相应的时钟信号,然后数据一位一位地将从
MOSI
信号线上进行发送到从机; -
主机接收从机数据:如果从机需要将数据发送回主机,则主机将继续生成预定数量的时钟信号,并且从机会将数据通过 MIS0 信号线发送;
具体如下图所示;
注意,SPI是“全双工”(具有单独的发送和接收线路),因此可以在同一时间发送和接收数据,另外SPI的接收硬件可以是一个简单的移位寄存器。这比异步串行通信所需的完整UART要简单得多,并且更加便宜;
数据在传输中,高位在先还是低位在先,SPI协议并无明确规定,但是数据要在主从机中正确传输,自然双方要先约定好,一般会采用高位在先(MSB)方式传输。
图中可能会产生歧义,关于0x53,这里要表达的意思是右边到左边是字节高位到低位。
SPI特性
SPI总线包括4条逻辑线,定义如下:
-
MISO:
Master input slave output
主机输入,从机输出(数据来自从机); -
MOSl:
Master output slave input
主机输出,从机输入(数据来自主机); -
SCLK:
Seria1 clock
串行时钟信号,由主机产生发送给从机; -
SS:
Slave select
片选信号,由主机发送,以控制与哪个从机通信,通常是低电平有效。
其他制造商可能会遵循其他命名规则,但是最终他们指的相同的含义。以下是一些常用术语:
-
MISO也可以是
SIMO
,DOUT
,DO
,SDO
或SO
(在主机端); -
MOSI也可以是
SOMI
,DIN
,DI
,SDI
或SI
(在主机端); -
NSS也可以是
CE
,CS
或SSEL
; -
SCLK也可以是
SCK
;
本文将按照以下命名进行讲解 [MISO,MOSI,SCK,NSS
]
下图显示了单个主机和单个从机,之间的典型SPI连接。
时钟频率
SPI总线上的主机必须在通信开始时候配置并生成相应的时钟信号。在每个SPI时钟周期内,都会发生全双工数据传输。
主机在 MOSI
线上发送一位数据,从机读取它,而从机在 MIS0
线上发送一位数据,主机读取它。
就算只进行单向的数据传输,也要保持这样的顺序。这就意味着无论接收任何数据,必须实际发送一些东西!在这种情况下,我们称其为虚拟数据;
从理论上讲,只要实际可行,时钟速率就可以是您想要的任何速率,当然这个速率受限于每个系统能提供多大的系统时钟频率,以及最大的SPI传输速率。
时钟极性 CKP/Clock Polarity
除了配置串行时钟速率(频率)外,SPI主设备还需要配置时钟极性。
根据硬件制造商的命名规则不同,时钟极性通常写为CKP或CPOL。时钟极性和相位共同决定读取数据的方式,比如信号上升沿读取数据还是信号下降沿读取数据;
CKP可以配置为1或0。这意味着您可以根据需要将时钟的默认状态(IDLE)设置为高或低。极性反转可以通过简单的逻辑逆变器实现。您必须参考设备的数据手册才能正确设置CKP和CKE。
-
CKP = 0
:时钟空闲IDLE
为低电平0
; -
CKP = 1
:时钟空闲IDLE
为高电平1
;
时钟相位 CKE /Clock Phase(Edge)
除配置串行时钟速率和极性外,SPI主设备还应配置时钟相位(或边沿)。根据硬件制造商的不同,时钟相位通常写为CKE或CPHA;
顾名思义,时钟相位/边沿,也就是采集数据时是在时钟信号的具体相位或者边沿;
-
CKE = 0
:在时钟信号SCK
的第一个跳变沿采样; -
CKE = 1
:在时钟信号SCK
的第二个跳变沿采样;
时钟配置总结
综上几种情况,下图总结了所有时钟配置组合,并突出显示了实际采样数据的时刻;
其中黑色线为采样数据的时刻;
蓝色线为SCK时钟信号;
具体如下图所示;
模式编号
SPI的时钟极性和相位的配置通常称为 SPI模式,所有可能的模式都遵循以下约定;具体如下表所示;
除此之外,我们还应该仔细检查微控制器数据手册中包含的模式表,以确保一切正常。
多从机模式
前面说到SPI总线必须有一个主机,可以有多个从机,那么具体连接到SPI总线的方法有以下两种:
第一种方法:多NSS
1.通常,每个从机都需要一条单独的SS线。
2.如果要和特定的从机进行通信,可以将相应的 NSS
信号线拉低,并保持其他 NSS
信号线的状态为高电平;如果同时将两个 NSS
信号线拉低,则可能会出现乱码,因为从机可能都试图在同一条 MISO
线上传输数据,最终导致接收数据乱码。
具体连接方式如下图所示;
第二种方法:菊花链
在数字通信世界中,在设备信号(总线信号或中断信号)以串行的方式从一个设备依次传到下一个设备,不断循环直到数据到达目标设备的方式被称为菊花链。
1.菊花链的最大缺点是因为是信号串行传输,所以一旦数据链路中的某设备发生故障的时候,它下面优先级较低的设备就不可能得到服务了;
2.另一方面,距离主机越远的从机,获得服务的优先级越低,所以需要安排好从机的优先级,并且设置总线检测器,如果某个从机超时,则对该从机进行短路,防止单个从机损坏造成整个链路崩溃的情况;
具体的连接如下图所示;
其中红线加粗为数据的流向;
所以最终的数据流向图可以表示为:
SCK为时钟信号,8clks表示8个边沿信号;
其中D为数据,X为无效数据;
所以不难发现,菊花链模式充分使用了SPI其移位寄存器的功能,整个链充当通信移位寄存器,每个从机在下一个时钟周期将输入数据复制到输出。
SPI通信的优缺点
SPI通信的优势
使SPI作为串行通信接口脱颖而出的原因很多;
-
全双工串行通信;
-
高速数据传输速率;
-
简单的软件配置;
-
极其灵活的数据传输,不限于8位,它可以是任意大小的字;
-
非常简单的硬件结构。从站不需要唯一地址(与12C不同)。从机使用主机时钟,不需要精密时钟振荡器/晶振(与UART不同)。不需要收发器(与CAN不同)。
SPI的缺点
没有硬件从机应答信号(主机可能在不知情的情况下无处发送);
通常仅支持一个主设备;
需要更多的引脚(与12C不同);
没有定义硬件级别的错误检查协议;
与RS-232和CAN总线相比,只能支持非常短的距离;
编程实现
下面是通过STM32的cubemx自动生成的HAL库代码,比较简单,截取了其中一部分,具体如下;
static 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; //数据位为8位
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; //CPOL=0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; //CPHA为数据线的第一个变化沿
hspi1.Init.NSS = SPI_NSS_SOFT; //软件控制NSS
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;//2分频,32M/2=16MHz
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; //最高位先发送
hspi1.Init.TIMode = SPI_TIMODE_DISABLE; //TIMODE模式关闭
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//CRC关闭
hspi1.Init.CRCPolynomial = 10; //默认值,无效
if (HAL_SPI_Init(&hspi1) != HAL_OK) //初始化
{
_Error_Handler(__FILE__, __LINE__);
}
}
//发送数据
HAL_StatusTypeDef
HAL_SPI_Transmit(SPI_HandleTypeDef *hspi,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
//接收数据
HAL_StatusTypeDef
HAL_SPI_Receive(SPI_HandleTypeDef *hspi,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
SPI通信的相关特点
SPI通信的主要特点
- 全双工通信:可以同时发送和接收数据。
- 高速数据传输:比I2C等其他串行通信协议快。
- 主从模式:有一个主设备(Master)和多个从设备(Slave)。
- 同步通信:使用时钟信号(SCLK)来同步数据传输。
- 数据帧格式:通常为8位或16位,可以配置为MSB(高位在前)或LSB(低位在前)。
- 连接简单:只需要4根线:SCLK、MOSI(主设备数据输出,从设备数据输入线)、MISO(主设备数据输入,从设备数据输出线)、CS(片选信号线)。
SPI的通信特性
- 设备选择:SPI是单主设备通信协议,主设备通过拉低CS/SS信号来选择从设备进行通信。
- 设备时钟:SPI的时钟信号由主设备产生,数据传输速率取决于时钟频率,且具有可编程性。
- 四种模式:SPI有四种工作模式,由CPOL(时钟极性)和CPHA(时钟相位)定义,这决定了数据采样和发送的时钟边沿。
SPI的数据传输方式特点
- 无起始位和停止位,数据位连续传输,提高了传输效率。
- 支持更高的数据传输速率,通常能达到甚至超过10M/bps。
- 灵活的数据传输宽度,不限于8位,可以是任意大小的字。
- 简单的硬件结构,易于实现。
然而,SPI也有一些局限性:
- 需要更多的信号线,相比I2C和UART使用四根信号线。
- 没有像I2C那样的从设备寻址系统,也没有硬件从机应答信号。
- 无法确认数据是否已成功接收,没有错误检查机制如UART中的奇偶校验位。
SPI的测试标准
SPI通信的测试通常遵循一些通用的电气和协议标准,以确保通信的可靠性和兼容性。虽然没有一个统一的“SPI测试标准”,但是一些通用的测试准则包括:
- 时钟频率测试:验证SPI通信在不同时钟频率下的性能。
- 数据完整性测试:确保数据在传输过程中没有错误。
- 通信距离测试:测试SPI总线在不同长度下的信号完整性。
- 负载测试:测试SPI总线在连接多个从设备时的性能。
- 噪声和抗干扰测试:评估SPI总线对电磁干扰的抵抗能力。
- 电源稳定性测试:确保SPI总线在不同电源条件下的稳定性。
SPI的板级测试
SPI的板级测试步骤
板级测试通常包括以下步骤:
- 硬件连接:确保SPI总线上的所有设备正确连接。
- 信号完整性测试:使用示波器等工具测试SCLK、MOSI、MISO线上的信号质量。
- 通信测试:通过软件发送数据并接收,验证数据的正确性。
- 时序测试:确保数据传输的时序符合SPI协议要求。
- 故障模拟:模拟一些故障情况,如断线、短路等,测试系统的容错能力。
SPI的板级测试标准
SPI总线的测试标准主要围绕信号质量和信号完整性展开,以确保通信的可靠性和稳定性。以下是一些关键的测试原则和标准:
- 信号幅度测试:确保SPI总线上信号的幅度在规定的范围内,满足设备的要求。这包括信号的最大电平、最小电平、幅度以及高低电平的平均值等。
- 时序测试:测试信号的时序是否满足规定的时钟频率和数据传输速率要求,保证信号的传输速度和时钟同步。时序测试包括SCLK频率、数据的建立时间和保持时间等。
- 噪声测试:检查SPI总线上是否存在干扰信号或电磁噪声,确保信号的清晰度和稳定性。
- 电平测试:测试包括幅值、过冲和下冲等。规格书一般会在首页列出SPI通信协议的电平范围,结合逻辑低电平的最大值和高电平的最小值等标准,判断所测数据是否满足要求。
- 信号完整性测试:包括信号线的高低电平脉宽、频率、建立时间和保持时间。测量时序时取信号中间点,以避免引入不必要的误差。
- 硬件和软件配置:在硬件层面,SPI接口的配置包括时钟极性(CPOL)、时钟相位(CPHA)、主从模式、数据线的配置等 。软件层面,需要编写相应的驱动程序来控制SPI通信,包括初始化配置和数据交换函数。
- 实际波形测试:使用示波器等设备捕获SPI通信的实际波形,分析信号的稳定性和时序准确性,确保与数据手册中定义的标准一致。
在进行SPI通信测试时,应严格参照产品数据手册中的规格要求,包括信号幅度、时序要求等,以确保SPI总线通信的准确性和稳定性。
SPI协议的升级版,如Dual SPI、Quad SPI和QPI,通过增加数据线位数来提高数据传输效率,已经被许多Flash厂家支持。此外,SPI接口也支持多从机模式,可以通过多片选或菊花链方式连接多个从设备,但需要注意信号的优先级和链路的稳定性。
总的来说,SPI是一种灵活、高效的通信协议,适用于多种应用场景,但设计者需要根据具体的应用需求和设备特性来选择合适的SPI模式和配置。
标签:协议,测试,SPI,从机,详解,信号,数据,时钟 From: https://www.cnblogs.com/bujidao1128/p/18371160