框架组成
IO
- 作用:提供时钟,将F进行分频
- SCK 线的时钟信号,由波特率发生器根据“控制寄存器 CR1”中的 BR[0:2]位控制
该位是对 f时钟的分频因子,对 f的分频结果就是 SCK 引脚的输出时钟频率。
数据控制逻辑
SPI 的 MOSI 及 MISO 都连接到数据移位寄存器上
- 数据移位寄存器的数据来源及目标接收、发送缓冲区以及 MISO、MOSI 线。
- 当向外发送数据的时候
- 数据移位寄存器以“发送缓冲区”为数据源,把数据一位一位地通过数据线发送出去;
当从外部接收数据的时候,
控制参数 :SPI模式、波特率、LSB先行、主从模式、单双向模式、产生 SPI 中断信号、DMA 请求及控制
- 读取状态:状态寄存器(SR)
通讯过程
- 控制 NSS 信号线,产生起始信号(图中没有画出);
- 把要发送的数据写入到“数据寄存器 DR”中,该数据会被存储到发送缓冲区;
- 通讯开始,SCK 时钟开始运行。
- MOSI 把发送缓冲区中的数据一位一位地传输出去;
- MISO 则把数据一位一位地存储进接收缓冲区中;
- 当发送完一帧数据的时候,“状态寄存器 SR”中的“TXE 标志位”会被置 1,表示传输完一帧,发送缓冲区已空;类似地,当接收完一帧数据的时候,“RXNE 标志位”会被置 1,表示传输完一帧,接收缓冲区非空;
- 等待到“TXE 标志位”为 1 时,若还要继续发送数据,则再次往“数据寄存器 DR”写入数据即可;
- 等待到“RXNE 标志位”为 1 时,通过读取“数据寄存器 DR”可以获取接收缓冲区中的内容
标准库结构体
typedef struct
{
uint16_t SPI_Direction; /*设置 SPI 的单双向模式 \*/
uint16_t SPI_Mode; /*设置 SPI 的主/从机端模式 \*/
uint16_t SPI_DataSize; /*设置 SPI 的数据帧长度,可选 8/16 位 \*/
uint16_t SPI_CPOL; /*设置时钟极性 CPOL,可选高/低电平\*/
uint16_t SPI_CPHA; /*设置时钟相位,可选奇/偶数边沿采样 \*/
uint16_t SPI_NSS; /*设置 NSS 引脚由 SPI 硬件控制还是软件控制\*/
uint16_t SPI_BaudRatePrescaler; /\*设置时钟分频因子,fpclk/分频数=fSCK \*/
uint16_t SPI_FirstBit; /\*设置 MSB/LSB 先行 \*/
uint16_t SPI_CRCPolynomial; /\*设置 CRC 校验的表达式 \*/
} SPI_InitTypeDef;
- (1) SPI_Direction 本成员设置 SPI 的通讯方向
- 双线全双工(SPI_Direction_2Lines_FullDuplex)
- 双线只接收(SPI_Direction_2Lines_RxOnly)
- 单线只接收(SPI_Direction_1Line_Rx)
- 单线只发送模式(SPI_Direction_1Line_Tx)。
- (2) SPI_Mode 设置SPI的工作模式
- 主机模式(SPI_Mode_Master)
- 从机模式(SPI_Mode_Slave ),
- 这两个模式的最大区别为 SPI 的 SCK 信号线的时序,SCK 的时序是由通讯中的主机产生的。
- 若被配置为从机模式,STM32 的 SPI 外设将接受外来的 SCK 信号。
- (3) SPI_DataSize 选择 SPI 通讯的数据帧大小
- 8 位(SPI_DataSize_8b)
- 16 位 (SPI_DataSize_16b)。
- (4) SPI_CPOL 和 SPI_CPHA 配置时钟极性和时钟相位
- 这两个成员配置 SPI 的时钟极性 CPOL 和时钟相位 CPHA,这两个配置影响到 SPI 的 通讯模式,关于 CPOL 和 CPHA 的说明参考前面“通讯模式”小节。
- 时钟极性 CPOL 成员,
- 高电平(SPI_CPOL_High)
- 低电平(SPI_CPOL_Low )。
- 时钟相位 CPHA 则可以设置为
- SPI_CPHA_1Edge(在 SCK 的奇数边沿采集数据)
- SPI_CPHA_2Edge (在 SCK 的偶数边沿采集数据) 。
- (5) SPI_NSS 本成员配置 NSS 引脚的使用模式
- 硬件模式(SPI_NSS_Hard )
- 在硬件模式中的 SPI 片选信号由 SPI 硬件自动产生
- 软件模式(SPI_NSS_Soft )
- 我们亲自把相应的 GPIO 端口拉高或置低产生非片选和片选信号。
- 实际中软件模式应用比较多。
- 硬件模式(SPI_NSS_Hard )
- (6) SPI_BaudRatePrescaler 波特率分频因子
- 本成员设置波特率分频因子,分频后的时钟即为 SPI 的 SCK 信号线的时钟频率。
- 这个成员参数可设置为 f的 2、4、6、8、16、32、64、128、256 分频。
- (7) SPI_FirstBit 数据位先行选择
- 所有串行的通讯协议都会有 MSB 先行(高位数据在前)还是 LSB 先行(低位数据在前)的问题
- 而 STM32 的 SPI 模块可以通过这个结构体成员,对这个特性编程控制。
- (8) SPI_CRCPolynomial SPI 的 CRC 校验中的多项式