1. SPI与W25Q64基础认知
作为一名嵌入式开发者,初次接触SPI外设时最常遇到的困惑就是:为什么需要这么多模式配置?为什么时钟极性和相位会影响通信?通过实际驱动W25Q64这颗SPI Flash芯片,我逐渐理解了这些参数的实际意义。SPI(Serial Peripheral Interface)作为一种高速全双工同步串行总线,其核心优势在于硬件简单、速率高,但灵活的配置特性也带来了学习门槛。
W25Q64是Winbond公司推出的64M-bit串行Flash存储器,采用标准的SPI接口。它的存储结构分为128个块(Block),每个块包含16个扇区(Sector),每个扇区4KB,相当于一个微型硬盘。与I2C相比,SPI没有设备地址概念,依靠硬件片选线(NSS)来区分设备,这使得单主机多从机系统布线更为复杂,但换来了更高的传输速率(W25Q64最高支持104MHz时钟)。
关键认知:SPI的四种工作模式(CPOL/CPHA组合)本质上解决的是主从设备时钟同步问题。不同厂商的SPI设备可能固定支持某种模式,例如W25Q64支持模式0和模式3,这就是为什么我们需要仔细配置这些参数。
2. 硬件连接与引脚配置
2.1 原理图解读
从提供的原理图可以看到,W25Q64的SPI接口包含以下关键信号线:
- SCK(Serial Clock):时钟信号,由主机产生
- MOSI(Master Out Slave In):主机输出从机输入数据线
- MISO(Master In Slave Out):主机输入从机输出数据线
- NSS(Slave Select):片选信号(低电平有效)
特别需要注意的是,STM32的SPI引脚是复用的。以STM32F103系列为例:
- SPI1的SCK可选择PA5或PB3
- MOSI对应PA7或PB5
- MISO对应PA6或PB4
- NSS对应PA4或PA15
2.2 实际接线方案
根据项目中的接线图,采用的配置是:
- PB3 -> SCK(复用推挽输出,2MHz)
- PB4 -> MISO(上拉输入)
- PB5 -> MOSI(复用推挽输出,2MHz)
- PA15 -> NSS(通用推挽输出,2MHz)
这种配置有几个技术细节值得注意:
- 选择PB组引脚可以避免与JTAG调试接口冲突(PA15默认是JTDI)
- MISO配置为上拉输入可以增强信号稳定性
- NSS使用普通GPIO而非硬件NSS,便于软件控制
c复制// 引脚初始化示例代码
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA, ENABLE);
// SCK和MOSI配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// MISO配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure);
// NSS配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_15); // 初始置高,不选中
3. SPI初始化参数详解
3.1 工作模式选择
SPI_Direction_2Lines_FullDuplex是最常用的模式,允许主从设备同时收发数据。对于W25Q64的操作流程通常是:
- 主机发送命令字节
- 主机发送地址字节
- 在发送数据的同时接收从机返回的数据
这种全双工特性使得SPI的效率高于I2C,但实际应用中需要注意:
- 读操作时主机需要发送"哑元"数据(通常为0xFF)来产生时钟
- 写操作时从机返回的数据通常可忽略
3.2 时钟配置关键参数
c复制SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // 空闲时高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // 第二个边沿采样
这两个参数组合构成SPI模式3(CPOL=1, CPHA=1),与W25Q64的规格书要求一致。不同模式的区别如下图所示:

实测中发现,如果模式配置错误会导致:
- 读取的Flash ID返回0x00或0xFF
- 写入数据后读取校验失败
- 高速通信时出现位错误
3.3 波特率设置
选择64分频(SPI_BaudRatePrescaler_64)意味着:
- 假设APB2时钟为72MHz,SPI时钟=72MHz/64≈1.125MHz
- 这个速率对于初期调试是安全的,后续可提升至16分频(4.5MHz)
经验提示:W25Q64支持最高104MHz时钟,但实际使用中建议:
- 读写操作使用≤25MHz
- 擦除操作使用≤10MHz
这样可以避免电源噪声导致的异常
4. 软件NSS控制策略
4.1 硬件NSS vs 软件NSS
硬件NSS自动管理片选信号,但存在以下限制:
- 多从机系统需要额外逻辑电路
- 某些STM32型号的硬件NSS有特殊时序要求
软件NSS通过普通GPIO控制更为灵活:
c复制#define FLASH_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_15)
#define FLASH_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_15)
// 在每次传输前后手动控制片选
FLASH_CS_LOW();
SPI_TransmitReceiveData(...);
FLASH_CS_HIGH();
4.2 片选时序要点
- 片选拉低后需等待至少50ns再发送命令
- 连续操作时片选保持低电平(如写使能后立即写数据)
- 传输结束后需保持片选低电平至少100ns
- 擦除操作期间片选不能频繁切换
实测案例:在一次扇区擦除(Sector Erase)操作中,如果在tSE(典型400ms)完成前切换片选,会导致该扇区数据损坏。
5. 数据收发实现机制
5.1 发送与接收函数
STM32标准库提供了三种级别的API:
- 阻塞式(Polling):SPI_I2S_SendData/SPI_I2S_ReceiveData
- 中断式:SPI_I2S_ITConfig
- DMA:SPI_DMACmd
对于初学者推荐使用阻塞式实现:
c复制uint8_t SPI_TransmitReceiveByte(uint8_t data)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, data);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI1);
}
5.2 完整读写流程示例
读取Flash ID的典型序列:
c复制uint16_t W25Q_ReadID(void)
{
uint16_t temp = 0;
FLASH_CS_LOW();
SPI_TransmitReceiveByte(0x90); // 发送读ID命令
SPI_TransmitReceiveByte(0x00); // 哑元地址
SPI_TransmitReceiveByte(0x00);
SPI_TransmitReceiveByte(0x00);
temp = SPI_TransmitReceiveByte(0xFF) << 8;
temp |= SPI_TransmitReceiveByte(0xFF);
FLASH_CS_HIGH();
return temp;
}
6. 常见问题排查指南
6.1 典型故障现象及解决
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 读取全0xFF | 片选信号异常 | 用逻辑分析仪检查NSS时序 |
| 读取数据错位 | CPOL/CPHA配置错误 | 确认设备规格书要求 |
| 写入失败 | 未发送写使能命令 | 在写操作前加WREN指令 |
| 通信不稳定 | 上拉电阻缺失 | MISO增加4.7k上拉电阻 |
6.2 调试工具推荐
- 逻辑分析仪:观测SCK/MOSI/MISO/NSS时序(推荐Saleae Logic)
- ST-Link Debugger:单步调试SPI寄存器
- 万用表:检查电源电压(3.3V±10%)
6.3 性能优化技巧
- 使用DMA传输批量数据
- 将SPI时钟提升至设备允许的最高频率
- 对频繁访问的数据进行缓存
- 在空闲时让SPI进入低功耗模式
通过这个项目的实践,我深刻体会到SPI接口的灵活性背后是对硬件细节的精确把控。每个参数的设置都需要参考设备规格书,而调试过程中逻辑分析仪是不可或缺的工具。后续可以进一步探索SPI的双线模式、DMA传输等高级特性来提升系统性能。
