SPI通信

Posted 是光哥呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPI通信相关的知识,希望对你有一定的参考价值。

目录

一、SPI接口原理

SPI是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。

SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省了空间,提供方便,主要应用在EEPROM,FLASH,实时时钟,AD转换器还有数字信号处理直接。

SPI接口一般使用四根线:
MISO,主设备数据输入,从设备数据输出
MOSI,主设备数据输出,从设备数据输入
SCLK,时钟信号,由主设备产生
CS,从设备片选信号,由主设备控制。

二、SPI接口框图

三、SPI工作原理

①硬件为四根线
②主机和从机都有一个串行移位寄存器,主机通过SPI的串行移位寄存器写入一个字节发送一次传输。
③串行移位寄存器通过MOSI信号线将字节发送给从机,从机将自己的串行移位寄存器的内容通过MISO返回给主机,这样两个移位寄存器的内容被交换。
④外设的读写操作同步完成,只进行写操作,则忽略读操作;主机只进行从机的读操作,则主机须发送一个空字节给从机引发传输。

四、SPI特征

STM32 的SPI接口可以配置为支持SPI协议或者支持IIS
音频协议,默认是SPI协议,也可以通过软件方式切换称IIS方式 

五、从设备引脚管理(NSS)

1、软件模式:

    可以设置SPI_CR1寄存器的SSM位来使能这种模式,在这种模式下NSS引脚可以用作它用,而内部NSS信号电平可以通过写SPI_CR1的SSI位来驱动。

2、硬件模式:

 第一种情况:NSS输出使能,当STM32工作为SPI模式的时,NSS输出已经通过SPI_CR2寄存器的SSOE位使能,这时NSS引脚被拉低,所有NSS引脚与这个主SPI的NSS引脚相连并配置为硬件NSS的SPI设备,将自动变成从的SPI设备。	
 第二种情况:NSS输出被关闭:允许操作于多主环境。

六、时钟信号的相位和极性

SPI_CR寄存器的CPOL和CPHA位,能够组合成四种可能的时序关系,CPOL(时钟极性)位控制在没有数据传输时时钟的空闲状态电平,此位对主模式和从模式下的设备都有效。如果CPOL被清’0’,SCK引脚在空闲状态下保持低电平;如果CPOL被置‘1’,SCK引脚在空闲状态保持高电平。

如果CPHA(时钟相位)位被置‘1’,SCK时钟的第二个边沿(0为下降沿,1为上升沿)进行数据位的采样,数据在第二个时钟边沿被锁存。

如果CPHA位被清0,SCK时钟的第一个边沿(0为下降沿,1为上升沿)进行数据位采集,数据在第一个时钟边沿被锁存。

CPOL时钟极性和CPHA时钟相位的组合选择数据捕捉的时钟边沿。

七、时钟信号的相位和极性


八、SPI接口原理

1、数据帧格式

根据SPI_CR1寄存器的LSBFIRST位,输出数据可以选择MSB(高位)先或者LSB(低位)先。
根据SPI_CR1寄存器的DFF位,可以选择数据帧是8位或者16位,对发送和接收都有效。

2、状态标志

通过三个标志可以完全监控SPI总线的状态

发送缓存器空闲标志(TXE):
此标志为1的时候,表示发送缓冲寄存器为空,可以写入下一个待发送数据进入缓冲器中,当写入SPI_DR(数据寄存器)时,TXE标志被清除。

接收缓冲器非空(RXNE):
此标志为1表明接收缓冲器中包含有效数据,读SPI数据寄存器可以清楚此标志

忙BUSY标志:
BSY标志由硬件设置与清楚,此标志表明SPI通信层的状态

九、SPI中断

十、SPI引脚配置

十一、SPI结构体

typedef struct

  uint16_t SPI_Direction;           //方向   
  uint16_t SPI_Mode;                //模式
  uint16_t SPI_DataSize;           //数据大小
  uint16_t SPI_CPOL;                //时钟极性
  uint16_t SPI_CPHA;                //时钟相位
  uint16_t SPI_NSS;                  //NSS位
  uint16_t SPI_BaudRatePrescaler;    uint16_t SPI_FirstBit;      //波特率    
  uint16_t SPI_CRCPolynomial;                                            //CRC校验位
SPI_InitTypeDef;

十二、SPI相关库函数

void SPI_I2S_DeInit(SPI_TypeDef* SPIx);
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize);
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);

十三、SPI配置过程

①配置引脚,使能时钟
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
②初始化SPI,设置工作模式
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
③使能SPIx
void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);SPI传输数据
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
⑤查看SPI传输状态
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);

以上是关于SPI通信的主要内容,如果未能解决你的问题,请参考以下文章

SPI通信

详解SPI中的极性CPOL和相位CPHA

SPI总线传输的4种模式

一文搞懂SPI通信协议

一文搞懂SPI通信协议

一文搞懂SPI通信协议