author: lunar
date: Wed 14 Oct 2020 09:22:03 AM CST
SPI (Serial Peripheral Interface)
串行外设接口概述
SPI即串行外围设备接口,SPI的内部非常简洁:
从图中可以看出,主机和从机都有一个串行移位寄存器,主机通过向它的SPI移位寄存器写入一个字节来发起一次传输。寄存器通过MOSI线将数据传输给从机的移位寄存器,同时从机的移位寄存器中的数据通过MISO线传输给主机,这样双方就同步完成了一次数据交换。如果只想写入从机,则主机只需忽略从机传输的数据即可。
SPI 总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串
行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果
CPOL=0,串行同步时钟的空闲状态为低电平;如果 CPOL=1,串行同步时钟的空闲状态为高电
平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果
CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果 CPHA=1,在串
行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI 主模块和与之通信的外设备时钟
相位和极性应该一致。
STM32 主模式配置
- 配置相关引脚的复用功能,使能SPI2时钟
使用GPIO的复用功能:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOB, ENABLE );//PORTB 时钟使能
RCC_APB1PeriphClockCmd(
RCC_APB1Periph_SPI2, ENABLE );//SPI2 时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 GPIOB
- 初始化SPI2,设置SPI2工作模式
SPI的初始化函数为
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
SPI_TypeDef
是SPI标号
typedef struct
{
uint16_t SPI_Direction;//通信方式:半双工、全双工、串行发、串行收
uint16_t SPI_Mode;//主从模式
uint16_t SPI_DataSize;//8位传输还是16位传输
uint16_t SPI_CPOL;//时钟极性
uint16_t SPI_CPHA;//时钟相位
uint16_t SPI_NSS;//NSS信号由软件控制还是硬件控制
uint16_t SPI_BaudRatePrescaler;//设置SPI波特率预分频值
uint16_t SPI_FirstBit;//MSB在前还是LSB在前
uint16_t SPI_CRCPolynomial;//设置CRCR校验方式
}SPI_InitTypeDef;
3)使能SPI2
SPI_Cmd(SPI2, ENABLE);
- 传输数据
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
- 查看SPI传输状态
可通过三个状态位查看SPI总线的状态
-
Busy状态
被设置时,表明SPI正忙于通信,且发送缓存其里有一个有效的数据字正在等待被发送。
-
发送缓冲器空闲表示(TXE)
被置位时表示发送缓冲器为空
-
接收缓冲器非空(RXNE)
被置位时表示接收缓冲器非空
获取标置位的函数:
SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE);