【STM32】SPI协议整理:硬件连接、通信时序与HAL库操作

【STM32】SPI协议整理:硬件连接、通信时序与HAL库操作

文章目录

  • 【STM32】SPI协议整理:硬件连接、通信时序与HAL库操作
    • 概述
    • 一、SPI程序层次
      • [1.1 SPI硬件原理图解析](#1.1 SPI硬件原理图解析)
      • [1.2 硬件框图 & 软件层次](#1.2 硬件框图 & 软件层次)
    • [二、SPI 协议](#二、SPI 协议)
      • [2.1 CS 片选](#2.1 CS 片选)
      • [2.2 SPI 是怎么传 1 字节数据](#2.2 SPI 是怎么传 1 字节数据)
      • [2.3 SPI模式](#2.3 SPI模式)
    • [三、HAL 编程](#三、HAL 编程)
      • [3.1 STM32CubeMX 配置](#3.1 STM32CubeMX 配置)
      • [3.2 查询方式函数说明](#3.2 查询方式函数说明)
      • [3.3 中断方式函数说明](#3.3 中断方式函数说明)
      • [3.4 DMA 方式函数说明](#3.4 DMA 方式函数说明)
      • [3.5 W25Q64 操作方法](#3.5 W25Q64 操作方法)

概述

  • SPI 可以理解为:主控 MCU 按自己给出的时钟节拍,和外设一边发数据、一边收数据的高速串行通信协议。(同步)(全双工)

  • SPI 接口主要应用在 EEPROM、 FLASH、实时时钟、网络控制器、 OLED 显示驱动器、 AD转换器,数字信号处理器、数字信号解码器等设备之间。


一、SPI程序层次

1.1 SPI硬件原理图解析

SPI_Flash模块 SPI硬件原理图
MCU 引脚 SPI 名称 Flash 引脚 作用
PA7 MOSI DI MCU ==> Flash
PA6 MISO DO Flash ==> MCU
PA5 SCK SCK MCU 提供时钟(节拍)
PB9 CS CS 片选,选择某个 Flash
GND GND GND 共地
VCC VCC VCC 供电

1.2 硬件框图 & 软件层次

SPI 硬件框图 SPI 软件层次

程序 ==>通过SPI控制器 来操作SPI Flash(SPI设备)


二、SPI 协议

2.1 CS 片选

硬件连线
  • SPI设备只能片选一个,谁的 CS 被拉低,谁就被选中

2.2 SPI 是怎么传 1 字节数据

SPI 传输一个字节

2.3 SPI模式

SPI 模式 CPOL CPHA
Mode 0 0(SCK初始电平为低) 0(在第一个时钟沿采样数据)
Mode 1 0(SCK初始电平为低) 1(在第二个时钟沿采样数据)
Mode 2 1(SCK初始电平为高) 0(在第一个时钟沿采样数据)
Mode 3 1(SCK初始电平为高) 1(在第二个时钟沿采样数据)
  • 不管是什么模式,SPI协议 都可以同时发送八位数据,同时接收到八位数据 (交换数据)

三、HAL 编程

3.1 STM32CubeMX 配置

配置 SPI 配置 CS 片选

3.2 查询方式函数说明

c 复制代码
/* 发送同时接收数据 */
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
/* 发送数据 */
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
/* 接收数据 */
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
参数 说明
SPI_HandleTypeDef *hspi 使用哪个 SPI 控制器
uint8_t *pTxData或uint8_t *pData 要发送的数据的 buffer
uint8_t *pRxData或uint8_t *pData 存储接收到的数据是 buffer
uint16_t Size 数据个数
uint32_t Timeout 超时时间,单位是 Tick,一般是 1ms
返回值 HAL_OK:成功HAL_ERROR:错误HAL_BUSY:总线忙HAL_TIMEOUT:超时

3.3 中断方式函数说明

STM32cubeMX 配置中断方式
c 复制代码
/* 发送同时接收数据 */
HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
/* 发送数据 */
HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_tSize);
/* 接收数据 */
HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
    
/* 发送、接收完成回调函数 */
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
/* 发送完成回调函数 */
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);
/* 接收完成回调函数 */
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
/* 出错回调函数 */
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
参数 说明
SPI_HandleTypeDef *hspi 使用哪个 SPI 控制器
uint8_t *pTxData / uint8_t *pData 要发送的数据的 buffer
uint8_t *pRxData / uint8_t *pData 存储接收到的数据是 buffer
uint16_t Size 数据个数
uint32_t Timeout 超时时间,单位是 Tick,一般是 1ms
返回值 HAL_OK:成功 HAL_ERROR:错误 HAL_BUSY:总线忙 HAL_TIMEOUT:超时

3.4 DMA 方式函数说明

STM32cubeMX 配置DMA方式
c 复制代码
/* 发送同时接收数据 */
HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
/* 发送数据 */
HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
/* 接收数据 */
HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);

/* 发送、接收完成回调函数 */
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
/* 发送完成回调函数 */
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);
/* 接收完成回调函数 */
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
/* 出错回调函数 */
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
参数 说明
SPI_HandleTypeDef *hi2c 使用哪个 I2C 控制器
uint16_t DevAddress 设备地址,需要把 7 位地址左移 1 位
uint8_t *pData 数据 buffer
uint16_t Size 数据个数
返回值 HAL_OK:成功HAL_BUSY:总线忙

3.5 W25Q64 操作方法

读数据
  • 写使能、读状态,擦除扇区,烧写页 见W25Q64芯片手册

欢迎大家一起交流讨论!