SPI总线概述
1 基本概念
串行外设接口(Serial Peripheral Interface)的简称也叫做SPI,是一种高速、全双工同步通信的一种接口,串行外设接口一般是需要4根线来进行通信(NSS、MISO、MOSI、SCK),但是如果打算实现单向通信也可以只使用3根线(NSS、MISO/MOSI、SCK),就可以利用这种机制实现一对多或者一对一的通信。
2 引脚定义
通常SPI通过4个引脚与外部器件相连:
MISO (Master Input Slave Output):主设备输入/从设备输出引脚 。该引脚在从模式下发送数据,在主模式下接收数据。
MOSI (Master Output Slave Input):主设备输出/从设备输入引脚。 该引脚在主模式下发送数据,在从模式下接收数据。
SCK (Serial Clock):串行时钟 ,作为主设备的输出,从设备的输入.
NSS (Negative Slave Select):低电平有效的从器件选择。 这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。
SPI总线:单一主机对单一从机
SPI总线:单一主机对复合从机
SPI总线采用的 环形结构 ,利用的是主从模式(主机→从机)进行数据的传输,由于是同步通信,所以在主机发送数据的同时也会收到从机发送的数据。
MOSI脚相互连接,MISO脚相互连接。这样,数据在主和从之间串行地传输(MSB位在)。通信总是由主设备发起。主设备通过MOSI脚把数据发送给从设备,从设备通过MISO引脚回传数据。这意味全双工通信的数据输出和数据输入是用同一个时钟信号同步的;时钟信号由主设备通过SCK脚提供。
NSS的说明:主机的NSS引脚在空闲状态下应处于高电平(VDD),主机发送数据时,主机的NSS应为输出模式,从机的NSS为输入模式,当主机的NSS引脚拉低,从设备的NSS引脚可以检测到低电平,该设备被选中。
从SPI的结构框图中可以看到NSS也是外部引脚的名称,其实控制SPI收发数据是通过内部的NSS信号实现的,而这个内部的NSS信号源可以由SPI_CR1寄存器的SSM(Software slave management)位来配置。
软件NSS模式,SSM=1 :可以通过设置SPI_CR1寄存器的SSM位来使能这种模式。在这种模式下NSS引脚可以用作它用,而内部NSS信号电平可以通过写SPI_CR1的SSI位来驱动。
SSM :软件从设备管理。当SSM被置位时,NSS引脚上的电平由SSI位的值决定。
0:禁止软件从设备管理;
1:启用软件从设备管理。硬件NSS模式,SSM=0:内部NSS信号电平由NSS引脚电平决定。在这种“硬件模式”下要用SPI_CR2的SSOE(Software Save Output Enable)位来控制NSS作为输入还是输出,当SSOE=0时,NSS引脚被配置为输入;当SSOE=0时,NSS引脚被配置为输出。
3 工作模式
注意:由于SPI外设是 全双工同步通信 ,所以时钟信号就由SCK引脚来生成, SCK引脚只能由主设备控制,从设备是无法控制的 ,所以SCK引脚输出的脉冲信号的极性和相位就需要进行配置。
3.1 时钟信号的相位和极性
SPI_CR寄存器的CPOL(时钟极性位)和CPHA(时钟相位位),能够组合成四种可能的时序关系。
时钟极性CPOL :指的是在SPI总线空闲状态下(不传输任何数据)SCK引脚的默认的电平状态。SCK空闲状态下的电平可以由SPI_CR1寄存器的CPOL位来进行设置。主设备的时钟极性要根据从设备来设置。
如果CPOL被清‘0’,SCK引脚在空闲状态保持低电平;
如果CPOL被置’1’,SCK引脚在空闲状态保持高电平。
时钟相位CPHA :指的是在传输数据时选择脉冲信号的边沿(上升沿或者下降沿)来进行数据的采集或者修改。该位可以由SPI_CR1寄存器的CPHA位来进行设置。主设备的时钟相位要根据从设备来设置。
如果CPHA位被置’1’,SCK时钟的第二个边沿(CPOL位为0时就是下降沿,CPOL位为’1’时就是上升沿)进行数据位的采样,数据在第二个时钟边沿被锁存。
如果CPHA位被清’0’,SCK时钟的第一边沿(CPOL位为’0’时就是下降沿,CPOL位为’1’时就是上升沿)进行数据位采样,数据在第一个时钟边沿被锁存。
CPOL | CPHA | 模式说明 |
---|---|---|
0 | 0 | 该模式指的是SCK引脚在空闲状态下为低电平,并且在第一个时钟边沿(上升沿)采集数据,在第二个时钟边沿(下降沿)来修改数据。 |
0 | 1 | 该模式指的是SCK引脚在空闲状态下为低电平,并且在第二个时钟边沿(下降沿)采集数据,在第一个时钟边沿(上升沿)来修改数据。 |
1 | 0 | 该模式指的是SCK引脚在空闲状态下为高电平,并且在第一个时钟边沿(下降沿)采集数据,在第二个时钟边沿(上升沿)来修改数据。 |
1 | 1 | 该模式指的是SCK引脚在空闲状态下为高电平,并且在第二个时钟边沿(上升沿)采集数据,在第一个时钟边沿(下降沿)来修改数据。 |
通过这两位可以得到四种不同的组合,就被作为SPI总线的工作模式( 模式0~模式3 ),到底要选择哪种模式,主机的工作模式必须根据从设备的数据手册的说明进行设置。
在实际的开发过程中,使用最多是模式0和 模式3 ,比如2.4G无线通信模块NRF24L01采用模式0来通信。
3.2 数据帧格式
根据SPI_CR1寄存器中的LSBFIRST位,输出数据位时可以MSB(高位先出)在先也可以LSB(低位先出)在先。主机的数据格式必须要根据从机的数据格式进行设置。
根据SPI_CR1寄存器的DFF位,每个数据帧可以是8位或是16位。所选择的数据帧格式对发送和/或接收都有效。
DFF :数据帧格式 (Data frame format)
0:使用8位数据帧格式进行发送/接收;
1:使用16位数据帧格式进行发送/接收。
注:只有当SPI禁止(SPE=0)时,才能写该位,否则出错
LSBFIRST :帧格式 (Frame format)
0:先发送MSB;
1:先发送LSB。
注:当通信在进行时不能改变该位的值。
4 通信速率
】
5 使用流程
The SPI HAL driver can be used as follows:
(#) **Declare a SPI_HandleTypeDef handle structure**, for example:
`SPI_HandleTypeDef hspi`;
(#)**Initialize the SPI low level resources** by implementing the `HAL_SPI_MspInit()` API:
(##) **Enable the SPIx interface clock**
(##) **SPI pins configuration**
(+++) Enable the clock for the SPI GPIOs
(+++) Configure these SPI pins as alternate function push-pull
(##) **NVIC configuration if you need to use interrupt process**
(+++) Configure the SPIx interrupt priority
(+++) Enable the NVIC SPI IRQ handle
(##) **DMA Configuration if you need to use DMA process**
(+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel
(+++) Enable the DMAx clock
(+++) Configure the DMA handle parameters
(+++) Configure the DMA Tx or Rx Stream/Channel
(+++) Associate the initialized hdma_tx(or _rx) handle to the hspi DMA Tx or Rx handle
(+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream/Channel
(#) **Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.**
(#) **Initialize the SPI registers by calling the** `HAL_SPI_Init() API`:
(++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
by calling the customized HAL_SPI_MspInit() API.
简述如下:
声明一个 SPI_HandleTypeDef 句柄结;
通过 HAL_SPI_MspInit() 初始化 SPI 低级资源;
使能 SPIx 接口时钟
SPI 引脚配置
如果需要使用中断进程,配置NVIC
如果需要使用DMA进程,配置DMA
在hspi初始化结构体中配置Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS, management, Clock polarity and phase, FirstBit and CRC
通过调用 HAL_SPI_Init()初始化 SPI 寄存器: