跳到主要内容

STM32 QSPI 接口

介绍

QSPI(Quad SPI)是一种高速串行通信接口,广泛应用于 STM32 微控制器中,用于连接外部存储器(如 Flash 存储器)。与传统的 SPI 接口相比,QSPI 通过使用四根数据线(IO0、IO1、IO2、IO3)显著提高了数据传输速率。QSPI 不仅支持单线 SPI 模式,还支持双线和四线模式,使其在需要高速数据传输的场景中非常有用。

在本教程中,我们将逐步介绍如何在 STM32 微控制器中配置和使用 QSPI 接口,并通过实际案例展示其应用。


QSPI 接口的工作原理

QSPI 接口的核心是通过四根数据线并行传输数据,从而大幅提高通信速度。以下是 QSPI 接口的主要特点:

  1. 四线模式:QSPI 使用四根数据线(IO0、IO1、IO2、IO3)进行数据传输,相比单线 SPI,传输速率提高了四倍。
  2. 命令-地址-数据模式:QSPI 通信通常包括命令、地址和数据三个阶段,每个阶段都可以选择使用单线、双线或四线模式。
  3. DMA 支持:STM32 的 QSPI 接口支持 DMA(直接内存访问),可以进一步减少 CPU 负载,提高数据传输效率。

配置 STM32 的 QSPI 接口

以下是一个简单的代码示例,展示如何在 STM32 中配置 QSPI 接口以连接外部 Flash 存储器。

1. 初始化 QSPI 外设

首先,我们需要配置 QSPI 的时钟和 GPIO 引脚。以下代码基于 STM32CubeMX 生成的 HAL 库代码:

c
#include "stm32f4xx_hal.h"

QSPI_HandleTypeDef hqspi;

void QSPI_Init(void) {
// 启用 QSPI 时钟
__HAL_RCC_QSPI_CLK_ENABLE();

// 配置 QSPI GPIO 引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_6 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

// 配置 QSPI 外设
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 2; // 设置时钟分频
hqspi.Init.FifoThreshold = 4;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
hqspi.Init.FlashSize = 23; // 设置 Flash 存储器大小
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
hqspi.Init.FlashID = QSPI_FLASH_ID_1;
hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
HAL_QSPI_Init(&hqspi);
}

2. 发送命令并读取数据

以下代码展示了如何使用 QSPI 接口发送命令并读取外部 Flash 存储器的数据:

c
uint8_t QSPI_ReadID(void) {
QSPI_CommandTypeDef sCommand;
uint8_t id;

// 配置读取 ID 命令
sCommand.Instruction = 0x9F; // 读取 ID 的命令
sCommand.Address = 0;
sCommand.AlternateBytes = 0;
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
sCommand.DataMode = QSPI_DATA_1_LINE;
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.AddressMode = QSPI_ADDRESS_NONE;
sCommand.NbData = 1; // 读取 1 字节数据

// 发送命令
HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);

// 接收数据
HAL_QSPI_Receive(&hqspi, &id, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);

return id;
}

实际应用场景

QSPI 接口在以下场景中非常有用:

  1. 外部 Flash 存储器:QSPI 常用于连接外部 Flash 存储器,用于存储固件、配置文件或日志数据。
  2. 高速数据传输:在需要高速数据传输的场景中,QSPI 可以显著提高通信效率。
  3. 图形显示:某些图形显示模块(如 OLED)支持 QSPI 接口,可以快速传输图像数据。

总结

QSPI 接口是 STM32 微控制器中一种强大的通信接口,特别适合需要高速数据传输的场景。通过本教程,您已经了解了 QSPI 的基本工作原理、配置方法以及实际应用场景。

提示

如果您想进一步学习 QSPI 接口的高级功能(如 DMA 支持或双 Flash 模式),可以参考 STM32 的官方参考手册和 HAL 库文档。


附加资源

  1. STM32 QSPI 参考手册
  2. STM32 HAL 库文档
  3. QSPI Flash 存储器数据手册

练习

  1. 修改代码示例,使其支持双线模式传输数据。
  2. 尝试使用 QSPI 接口读取外部 Flash 存储器的容量信息。
  3. 探索如何在 QSPI 接口中使用 DMA 功能以提高数据传输效率。