SPI外设
SPI(Serial Peripheral Interface–串行外设接口)
- 可选 8 或 16 位传输帧格式
- 主或从操作
- 支持多主模式
- 可触发中断的专用发送和接收标志
- 支持可靠通信的硬件CRC
- 支持DMA功能的1字节发送和接收缓冲器:产生发送和接受请求
- 兼容I2S协议
SPI结构
SPI_CR2寄存器:其中标志位与中断有关。
TXE和RXNE:发送寄存器空,接收寄存器非空。
BR0/1/2:波特率计算相关。
CPOL和CPHA:选择发送方式高低电平。
NSS:偏向于实现多主机模式,所以ss引脚用GPIO模拟。
发送寄存器移入数据后,置TXE标志位。
移位寄存器将数据传入接收寄存器后,置RXNE标志位。
SPI数据发送流程
- 等待TXE位置1。
- 写入待发送的数据至发送寄存器。
- 等待RXNE为1。
- 读取接收数据寄存器接受到的数据。
- 重复发送下一个数据。
SPI结构简图
初始化流程
- RCC时钟:GPIO 和 SPIx
- GPIO初始化:MISO(GPIO_Mode_IPU)SS(GPIO_Mode_Out_PP)SCK/MOSI(GPIO_Mode_AF_PP)
- SPI初始化结构体:SPI_InitTypeDef
- SPI_Mode = SPI_Mode_Master;//主从模式选择
- SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线全双工
- SPI_DataSize = SPI_DataSize_8b;//数据帧长度(8/16)
- SPI_FirstBit = SPI_FirstBit_MSB;//高位先行
- SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//波特率预分频器
- SPI_CPOL = SPI_CPOL_Low;//SPI模式
- SPI_CPHA = SPI_CPHA_1Edge;//
- SPI_NSS = SPI_NSS_Soft;//NSS软硬件选择
- SPI_CRCPolynomial = 7;//CRC校验
- SPI初始化函数:SPI_Init(SPI1, &SPI_InitStructure);
- SPI使能:SPI_Cmd()
- NVIC初始化
- DMA初始化
标准库函数使用模板
SPI初始化
void SPI_Init() {
RCC_APB2PeriphClockCmd(RCC_APB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//SS
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;//SCK & MOSI
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//MISO
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主从模式选择
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线全双工
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//数据帧长度(8/16)
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//高位先行
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//波特率预分频器
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//SPI模式
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS软硬件选择
SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC校验
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
SPI_W_SS(1);//默认不选中从机
}
void SPI_W_SS(uint8_t BitValue)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}
void SPI_Start(void)
{
SPI_W_SS(0);
}
void SPI_Stop(void)
{
SPI_W_SS(1);
}
数据收发寄存器函数
/* SPI_I2S_SendData 写数据寄存器
* @ param1 选择SPIx
* @ param2 待发送的值
* @ retval None
*/
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
/* SPI_I2S_ReceiveData 读数据寄存器
* @ param1 选择SPIx
* @ retva2 接收到的值
*/
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
SPI标志位函数
/* SPI_I2S_GetFlagStatus 读标志位
* @ param1 选择SPIx
* @ param2 选择标志位事件
* @ retval 标志位状态(SET/RESET)
*/
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
/* SPI_I2S_ClearFlag 清标志位
* @ param1 选择SPIx
* @ param2 选择标志位事件
* @ retval None
*/
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
SPI_NVIC中断函数
/* SPI_I2S_ITConfig NVIC中断配制
* @ param1 选择SPIx
* @ param2 选择用来产生中断的标志位事件
* @ param3 使能/失能
* @ retval None
*/
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
// 获取中断标志位
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_DMA函数
/* SPI_I2S_DMACmd
* @ param1 选择SPIx
* @ param2 选择DMA的通道
* @ param3 使能/失能
* @ retval None
*/
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
流程图
+------------+
SPI外设 |波特率发生器 +------->GPIO----->SCK
+------------+
+---------------------+
| +-----------+ |
| |接收数据RDR| |
| +-----+-----+ |
+----------+ | | |
|数据控制器 +-------------------->| +--<<移位寄存器<<---+----GPIO<-----MISO
+----------+ | | | |
| +--------|----------+--->GPIO----->MOSI
| +-----+-----+ |
| |发送数据TDR | |
| +-----------+ | GPIO----->SS
+---------------------+
------ BY Flier
2023.9.22
Reference:江协科技、《stm32f10x用户手册》、《stm32库开发实战指南教程》