STM32SPI模块


author: lunar
date: Wed 14 Oct 2020 09:22:03 AM CST

SPI (Serial Peripheral Interface)

串行外设接口概述

SPI即串行外围设备接口,SPI的内部非常简洁:

image-20201220232536984

从图中可以看出,主机和从机都有一个串行移位寄存器,主机通过向它的SPI移位寄存器写入一个字节来发起一次传输。寄存器通过MOSI线将数据传输给从机的移位寄存器,同时从机的移位寄存器中的数据通过MISO线传输给主机,这样双方就同步完成了一次数据交换。如果只想写入从机,则主机只需忽略从机传输的数据即可。

SPI 总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串
行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果
CPOL=0,串行同步时钟的空闲状态为低电平;如果 CPOL=1,串行同步时钟的空闲状态为高电
平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果
CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果 CPHA=1,在串
行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI 主模块和与之通信的外设备时钟
相位和极性应该一致。

STM32 主模式配置

  1. 配置相关引脚的复用功能,使能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
  1. 初始化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);

  1. 传输数据

void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t data);

uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);

  1. 查看SPI传输状态

可通过三个状态位查看SPI总线的状态

  1. Busy状态

    被设置时,表明SPI正忙于通信,且发送缓存其里有一个有效的数据字正在等待被发送。

  2. 发送缓冲器空闲表示(TXE)

    被置位时表示发送缓冲器为空

  3. 接收缓冲器非空(RXNE)

    被置位时表示接收缓冲器非空

获取标置位的函数:

SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE);

原文地址:https://www.cnblogs.com/lunar-ubuntu/p/14166103.html