问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32H7串行外设接口(SPI)主从全双工通信模式的用法

创作时间:
作者:
@小白创作中心

STM32H7串行外设接口(SPI)主从全双工通信模式的用法

引用
CSDN
1.
https://blog.csdn.net/mftang/article/details/137606083

本文主要介绍STM32H7系列微控制器的SPI(串行外设接口)相关应用方法,包括SPI的实现原理、寄存器配置、使用STM32Cube工具进行参数配置,以及STM32 HAL库中与主从全双工通信模式相关的接口函数。文章详细介绍了SPI的基本概念、主要特性、功能说明、通信模式、重要寄存器等内容,并提供了具体的代码示例。

概述

本文主要介绍STM32H7系列微控制器的SPI(串行外设接口)相关应用方法,包括SPI的实现原理、寄存器配置、使用STM32Cube工具进行参数配置,以及STM32 HAL库中与主从全双工通信模式相关的接口函数。文章详细介绍了SPI的基本概念、主要特性、功能说明、通信模式、重要寄存器等内容,并提供了具体的代码示例。

1 认识SPI

1.1 SPI 的概念

串行外设接口 (SPI) 可使用特定同步协议与外部器件进行通信。SPI 接口支持与外部器件进行半双工、全双工和单工同步串行通信。该接口可配置为主模式或从模式,并且能够在多从或多主配置中运行。

在配置为主器件时,它为外部从器件提供通信时钟 (SCK)。从器件选择信号可以由主器件提供,也可以选择由从器件接收。默认情况下使用 Motorola 数据格式,但也支持某些其他特定模式。

1.2 SPI 主要特性

  • 传输总线选择

  • 基于三条线的全双工同步传输

  • 基于双线的半双工同步传输,其中一条可作为双向数据线

  • 基于双线的单工同步传输,其中一条可作为单向数据线

  • 模式选择:

  • 数据大小可从 4 位到 32 位

  • 多主或多从模式功能

  • 双时钟域,外设内核时钟可以独立于 PCLK

  • 8 个主模式波特率预分频器,可达内核频率的一半

  • 从模式频率可达 IP 内核频率的一半

  • 可控配置:

  • 保护配置和设置

  • 对于主模式和从模式都可以通过硬件或者软件进行 SS 管理

  • 数据之间的最小延时,以及 SS 与数据流之间的最小延时均可调

  • 可配置的 SS 信号极性和时序, MISO x MOSI 交换功能

  • 可调节的主器件接收器采样时间

  • 可编程的时钟极性和相位

  • 可编程的数据顺序,最先移位 MSB 或 LSB

  • 可以对传输的数据量进行编程,以控制 SS 和 CRC

  • 可触发中断的专用发送和接收标志

  • 停止模式(未向外设 IP 提供时钟)下从器件发送和/或接收功能,以及唤醒功能

  • 数据格式、DMA和CRC:

  • SPI Motorola 和 TI 格式支持

  • 用于确保可靠通信的硬件 CRC 功能:

  • 在发送模式下可以添加 CRC 校验值

  • 在接收模式下,自动进行 CRC 错误校验

  • 可触发中断的主模式故障、上溢或下溢标志以及 CRC 错误检测

  • 具有 DMA 功能的两个 16x 或 8x 8 位的内置 Rx 和 Tx FIFO

  • 可编程的传输数据量

  • 可配置的 FIFO 阈值(数据打包)

  • 从模式下,下溢条件可配置(支持级联循环缓冲区)

1.3 STM32F7xx SPI 特性

2 SPI 功能说明

2.1 SPI 框图

SPI 支持在 MCU 与外部器件之间进行同步串行通信。应用软件可通过轮询状态标志或使用专用 SPI 中断对通信进行管理。 SPI 的主要组件及其交互方式如以下框图所示:

2.2 SPI 信号

四个 I/O 引脚专用于与外部器件进行 SPI 通信。

引脚定义
说明
MISO
主输入/从输出数据。通常情况下,此引脚用于在从模式下发送数据和在主模式 下接收数据。
MOSI
主输出/从输入数据。通常情况下,此引脚用于在主模式下发送数据和在从模式 下接收数据。
SCK
SPI 主器件的串行时钟输出引脚以及 SPI 从器件的串行时钟输入引脚。
SS
从器件选择引脚。根据 SPI 和 SS 设置,该引脚可用于: 1)选择单个从器件以进行通信 2)同步数据帧 3) 检测多个主器件之间是否存在冲突

SPI 总线支持一个主器件与一个或多个从器件之间进行通信。该总线至少由两条线构成:一条用于时钟信号,另一条用于同步数据传输。其它信号可以根据 SPI 节点间的数据交换及其从器件选择信号管理进行添加。 MOSI 和 MISO 引脚之间的功能可以在任意 SPI 模式下反相。

3 主从通信模式

通信流可使用以下 3 种模式之一:全双工( 3 线)、半双工( 2 线)或单工( 2 线)。 SS 信号在单一主从器件配置下是可选信号,并且一般不使用。不过, SS 信号在此配置下可有助于同步数据流,并在默认情况下用于某些特定 SPI 模式(例如, TI 模式)。

本文主要介绍全双工( 3 线)通信模式的用法。

3.1 全双工通信模式

默认情况下, SPI 配置为全双工通信( SPI_CFG2 寄存器中的位 COMM[1:0] = 00)。在这种配置下,主器件和从器件的移位寄存器通过 MOSI 和 MISO 引脚之间的两条单向线连接。在 SPI 通信过程中,数据随主器件提供的 SCK 时钟边沿同步移位。主器件通过 MOSI 线将待发送的数据发送给从器件,同时通过 MISO 线从从器件接收数据。当数据帧传输完成时(所有位均移出),主器件和从器件之间即完成信息交换。

3.2 全双工通信模式框图

3.3 标准多从器件通信

在具有两个或多个独立从器件的配置下,主器件使用星型拓扑和专用的 GPIO 引脚来分别管理每个从器件的片选线。主器件必须通过拉低与从器件 SS 输入相连的GPIO 的电平来单独选择一个从器件(在同一时刻,只有一个从器件可以控制共用 MISO 线上的数据)。完成上述操作后,随即会在主器件和所选从器件之间建立通信。这种拓扑除了具有简便性优势外,还支持对各个从器件应用特定 SPI 配置,因为所有通信会话均在一个主器件-从器件对内单独进行。此外,如果无需从从器件中读取任何信息,主器件可以将相同的信息发送到多个从器件。

4 几个重要的SPI寄存器

STM32H7和SPI相关的寄存器有很多个,这里只介绍和主从全双工通信模式相关的寄存器。

4.1 SPI 配置寄存器 2 (SPI_CFG2)

偏移地址: 0x0C

复位值: 0x0000 0000

SPI 使能或 SPI2S_CR1 寄存器中的 IOLOCK 位置 1 时,该寄存器的内容受写保护。

  • 位 25 CPOL:时钟极性 (Clock Polarity)

  • 0:空闲时 SCK 信号为低电平

  • 1:空闲时 SCK 信号为高电平

  • 位 24 CPHA:时钟相位 (Clock phase)

  • 0:从第一个时钟边沿开始采样数据

  • 1:从第二个时钟边沿开始采样数据

  • 位 23 LSBFRST:数据帧格式 (Data frame format)

  • 0:先发送 MSB

  • 1:先发送 LSB

  • 位 22 MASTER:SPI 主模式 (SPI Master)

  • 0: SPI 从模式

  • 1: SPI 主模式

  • 位 21:19 SP[2:0]:串行协议 (Serial Protocol)

  • 000: SPI Motorola

  • 001: SPI(TI)

  • 位 18:17 COMM:SPI 通信模式 (SPI Communication Mode)

  • 00:全双工

  • 01:单工发送器

  • 10:单工接收器

  • 11:半双工

4.2 SPI 中断使能寄存器 (SPI2S_IER)

偏移地址: 0x10

复位值: 0x0000 0000

  • 位 5 UDRIE:UDR 中断使能 (UDR interrupt enable)

  • 0:禁止 UDR 中断

  • 1:使能 UDR 中断

  • 位 4 TXTFIE:TXTFIE 中断使能 (TXTFIE interrupt enable)

  • 0:禁止 TXTF 中断

  • 1:使能 TXTF 中断

  • 位 1 TXPIE:TXP 中断使能 (TXP interrupt enable)
    TXPIE 由软件置 1,并由 TXTF 标志置 1 事件清零。

  • 0:禁止 TXP 中断

  • 1:使能 TXP 中断

  • 位 0 RXPIE:RXP 中断使能 (RXP Interrupt Enable)

  • 0:禁止 RXP 中断

  • 1:使能 RXP 中断

4.3 SPI状态寄存器 (SPI2S_SR)

偏移地址: 0x14

复位值: 0x0000 1002

  • 位 1 TXP:可用的 Tx 数据包空间 (Tx-Packet space available)

  • 0: TxFIFO 中没有足够的空间来放置下一个数据包

  • 1: TxFIFO 具有足够的可用位置来容纳 1 个数据包
    TXP 标志由硬件进行更改。如果使能 SPI,它将监视 TxFIFO 中当前可用的总体空间。在 TxFIFO 中存储完整的数据包后,必须对其进行检查。

  • 位 0 RXP:可用的 Rx 数据包 (Rx-Packet available)

  • 0: RxFIFO 为空或接收到的数据包不完整

  • 1: RxFIFO 至少包含 1 个数据包
    RXP 标志由硬件进行更改。如果使能 SPI,它将监视 RxFIFO 中当前可用的整体数据量。从 RxFIFO 中完整读取一个数据包后,必须对其进行检查。

4.4 SPI发送数据寄存器 (SPI2S_TXDR)

偏移地址: 0x20

复位值: 0x0000 0000

  • 位 31:0 TXDR[31:0]:发送数据寄存器 (Transmit data register)
    该寄存器用作与 TxFIFO 的接口。对其进行写操作可访问 TxFIFO。

注意点:

  • 1)数据始终右对齐。写入寄存器时将忽略未使用位,读取寄存器时会将未使用位读为 0。
  • 2)DR 可按字节进行访问( 8 位访问):在这种情况下,通过单次访问只能写入一个数据字节
  • 3)按半字进行访问( 16 位访问):在这种情况下,通过单次访问可写入 2 个数据字节或1 个半字数据。
  • 4)逐字进行访问( 32 位访问):在这种情况下,通过单次访问可写入 4 个数据字节或者2 个半字数据或字数据。

4.5 SPI接收数据寄存器 (SPI2S_RXDR)

偏移地址: 0x30

复位值: 0x0000 0000

  • 位 31:0 RXDR[31:0]:接收数据寄存器 (Receive data register)
    该寄存器用作与 RxFIFO 的接口。对其进行读操作时将访问 RxFIFO。

1)数据始终右对齐。读取该寄存器时,未使用的位将读为 0。对该寄存器进行的写操作将被忽略。
2)DR 可按字节进行访问( 8 位访问):在这种情况下,通过单次访问只能读取一个数据字节
3)按半字进行访问( 16 位访问):在这种情况下,通过单次访问可读取 2 个数据字节或1 个半字数据。
4)逐字进行访问( 32 位访问):在这种情况下,通过单次访问可读取 4 个数据字节或者2 个半字数据或字数据。

5 STM32Cube配置SPI

使能SPI接口,选择Master模式

配置SPI相关的参数

配置SPI的工作时钟

6 SPI Hal库函数

STM32 Hal库中提供了需要和SPI相关的库函数,本文主要介绍主从全双工通信模式下的相关内容,所以只介绍和该应用相关的接口。

6.1 初始化接口:HAL_SPI_Init

函数原型:

HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);

使用Demo, 在使用STM32Cube产生工程时,该函数会被STM32Cube工具自动生成,函数中的配置参数可以在Parameter Settings中修订:

6.2 发送数据函数:HAL_SPI_Transmit

函数原型:

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi,
                                   const uint8_t *pData,
                                   uint16_t Size,
                                   uint32_t Timeout);

参数介绍:

参数说明
说明
hspi
SPI的数据结构句柄
pData
发送的数据内容
Size
发送数据的长度
Timeout
发送数据超时时间

6.3 接收数据函数: HAL_SPI_Receive

函数原型:

HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi,
                                  uint8_t *pData,
                                  uint16_t Size,
                                  uint32_t Timeout);

参数介绍:

参数说明
说明
hspi
SPI的数据结构句柄
pData
接收的数据buff
Size
接收数据的长度
Timeout
接收数据超时时间

6.4 发送接收函数:HAL_SPI_TransmitReceive

函数原型:

HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi,
                                          const uint8_t *pTxData,
                                          uint8_t *pRxData,
                                          uint16_t Size,
                                          uint32_t Timeout);

参数介绍:

参数说明
说明
hspi
SPI的数据结构句柄
pTxData
发送的数据buff
pRxData
接收的数据buff
Size
发送和接收数据的长度
Timeout
发送和接收数据超时时间

6.5 自定义发送和接收数据函数:SPI_readWriteByte

STM32 Hal库函数中已经实现SPI的发送和接收数据功能函数,但在实际项目应用过程中,有些程序对时间要求特别严格,为了尽量代码消耗时间,希望能尽量减少代码的长度,这时直接操作寄存器实现功能是一个非常好的选择。

函数源代码功能介绍:

  • 代码第62行:使能串行外设
  • 代码第63行:主传输正在进行,或通过自动挂起被临时挂起
  • 代码第65行:TxFIFO 具有足够的可用位置来容纳 1 个数据包
  • 代码第66行:发送数据
  • 代码第68行:RxFIFO 为空或接收到的数据包不完整,RXP =1 接收数据完成
  • 代码第69行:从RXDR中读取数据
  • 代码第71行:传输结束标志清零 (End Of Transfer flag clear),向该位写入 1 可将 SPI2S_SR 寄存器的 EOT 标志清零
  • 代码第72行:禁止串行外设工作
  • 代码第74行:返回读取到的数据

详细代码:

static uint8_t SPI_readWriteByte(SPI_HandleTypeDef *hspi, uint8_t txData)
{
    uint8_t rxData=0;
    hspi->Instance->CR1|=1<<0;
    hspi->Instance->CR1|=1<<9;
    while((hspi->Instance->SR&1<<1)==0);
    hspi->Instance->TXDR = txData;
    while((hspi->Instance->SR&1<<0)==0);
    rxData = hspi->Instance->RXDR;
    hspi->Instance->IFCR|=3<<3;
    hspi->Instance->CR1&=~(1<<0);
    return rxData;
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号