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通信的主要内容,如果未能解决你的问题,请参考以下文章