STM32 HAL库 SPI 4种模式配置实战:W25Q128 Flash 读写速度实测 2MB/s
2026/7/10 11:38:45 网站建设 项目流程

STM32 HAL库 SPI 4种模式配置实战:W25Q128 Flash 读写速度实测 2MB/s

嵌入式开发中,SPI通信协议因其高速、全双工的特性成为连接微控制器与存储设备的首选方案。本文将深入探讨STM32 HAL库下SPI四种工作模式的配置差异,并以W25Q128 Flash芯片为实例,实测不同模式下的读写性能表现。

1. SPI通信核心机制解析

SPI协议通过四线制实现全双工同步通信:

  • SCLK:主设备生成的同步时钟信号
  • MOSI:主设备输出/从设备输入数据线
  • MISO:主设备输入/从设备输出数据线
  • NSS:从设备片选信号(低电平有效)

时钟极性(CPOL)与相位(CPHA)的组合定义了四种工作模式:

模式CPOLCPHA时钟空闲电平数据采样边沿
000低电平上升沿
101低电平下降沿
210高电平下降沿
311高电平上升沿

提示:W25Q128默认支持模式0和模式3,实际使用需根据芯片手册确认兼容性

2. HAL库SPI初始化配置

2.1 硬件环境搭建

以STM32F407为例,硬件连接如下表:

STM32引脚W25Q128引脚功能说明
PA5CLKSPI时钟线
PA6MISO主入从出数据线
PA7MOSI主出从入数据线
PA4CS片选信号

2.2 四种模式初始化代码

SPI_HandleTypeDef hspi1; void SPI_Init_Mode(uint8_t mode) { hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; switch(mode) { case 0: // CPOL=0, CPHA=0 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; break; case 1: // CPOL=0, CPHA=1 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; break; case 2: // CPOL=1, CPHA=0 hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; break; case 3: // CPOL=1, CPHA=1 hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; break; } hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // 42MHz/4=10.5MHz HAL_SPI_Init(&hspi1); }

3. W25Q128驱动实现

3.1 关键操作指令集

Flash芯片常用指令封装:

#define W25Q128_CMD_READ_DATA 0x03 #define W25Q128_CMD_PAGE_PROGRAM 0x02 #define W25Q128_CMD_SECTOR_ERASE 0x20 #define W25Q128_CMD_READ_STATUS1 0x05 void W25Q128_Read(uint32_t addr, uint8_t *pData, uint16_t size) { uint8_t cmd[4] = { W25Q128_CMD_READ_DATA, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, addr & 0xFF }; HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, cmd, 4, HAL_MAX_DELAY); HAL_SPI_Receive(&hspi1, pData, size, HAL_MAX_DELAY); HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET); }

3.2 写操作注意事项

Flash写入需遵循特定流程:

  1. 发送写使能指令(0x06)
  2. 等待芯片就绪(检查状态寄存器)
  3. 执行页编程(最大256字节/次)
  4. 再次等待操作完成
void W25Q128_WriteEnable(void) { uint8_t cmd = 0x06; HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET); } uint8_t W25Q128_WaitBusy(void) { uint8_t status; uint8_t cmd = W25Q128_CMD_READ_STATUS1; do { HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_SPI_Receive(&hspi1, &status, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET); } while(status & 0x01); return status; }

4. 性能实测与分析

4.1 测试环境配置

  • MCU:STM32F407 @168MHz
  • SPI时钟:42MHz (APB2时钟)
  • 预分频:4 (实际SPI时钟10.5MHz)
  • 测试数据块:4KB连续地址

4.2 不同模式速度对比

模式读速度(MB/s)写速度(MB/s)稳定性
02.10.8★★★★☆
1不兼容不兼容-
2不兼容不兼容-
32.00.75★★★★

实测发现:

  • 模式1和模式2因时序不匹配导致通信失败
  • 模式0在10.5MHz时钟下达到最佳2.1MB/s读取速度
  • 写入速度受Flash芯片页编程时间限制

4.3 优化策略

  1. 时钟提升:将预分频设为2可获得21MHz SPI时钟
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  2. DMA传输:减少CPU干预提升效率
    HAL_SPI_Transmit_DMA(&hspi1, txData, size); HAL_SPI_Receive_DMA(&hspi1, rxData, size);
  3. 双缓冲技术:读写操作交替进行

5. 典型问题排查指南

5.1 常见故障现象

  • 数据错位:检查CPHA配置是否与从设备匹配
  • 时钟无输出:确认SPI外设时钟使能
    __HAL_RCC_SPI1_CLK_ENABLE();
  • 片选异常:软件控制NSS时需配置为SPI_NSS_SOFT

5.2 逻辑分析仪诊断

建议捕获以下信号波形:

  1. SCLK与MOSI/MISO的相位关系
  2. CS信号的有效持续时间
  3. 第一个数据位的出现时机

通过调整CPOL/CPHA参数可观察到四种模式下的典型波形差异。模式0和模式3的时钟起始边沿相反,但采样时刻均在第一个跳变沿。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询