基于标准外设库的STM32F0驱动25LC256 EEPROM SPI接收异常问题
问题根因分析
- SPI配置缺失关键位:初始化代码中
SPI2 -> CR2 |= SPI_CR2_FRXTH;被注释,STM32F0 SPI默认RXFIFO阈值为16位半满,8位数据宽度下需要收到2个字节才会触发接收标志,你判断单字节接收的条件无法触发,最终读取到无效值。 - 25LC256控制引脚未初始化电平:代码中仅配置了HOLD引脚为输出模式,未将其置高,HOLD引脚低电平会暂停EEPROM的SPI通信,导致芯片响应异常。
- SPI收发函数逻辑冗余且错误:发送指令后清空RXFIFO的时机不对,且用FIFO状态判断接收的逻辑依赖未开启的配置位,可靠性极低。
修复步骤
1. 修正SPI初始化配置
取消FRXTH位的注释,开启8位数据下单字节接收阈值:
// 原SPI初始化代码末尾修改 SPI_NSSInternalSoftwareConfig(SPI2,SPI_NSSInternalSoft_Set); SPI2 -> CR2 |= SPI_CR2_FRXTH; // 取消该行注释,开启单字节接收阈值 SPI_Cmd(SPI2,ENABLE);
2. 重写SPI收发函数,使用标准全双工收发逻辑
直接用TXE、RXNE标志位判断,逻辑更简单可靠:
uint8_t SPI_TransmitReceive(uint8_t data) { // 等待发送FIFO为空 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); SPI_SendData8(SPI2, data); // 等待接收完成(开启FRXTH后,收到1字节RXNE即置位) while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); return SPI_ReceiveData8(SPI2); }
3. 修正GPIO初始化与主逻辑
初始化时将HOLD引脚置高,调整状态寄存器读取逻辑:
GPIO初始化补充:
// 初始化HOLD、CS引脚后补充 GPIO_SetBits(GPIOB, HOLD); // HOLD引脚拉高,确保EEPROM正常工作 GPIO_SetBits(GPIOB, CS); // 初始状态CS拉高,未选中EEPROM
主函数测试逻辑修正:
SystemInit(); SPI_EEPROM(); GPIO(); // 发送写使能指令 GPIO_ResetBits(GPIOB, CS); SPI_TransmitReceive(WRITEEN); // 发送WREN指令,返回的无效数据直接丢弃 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET); GPIO_SetBits(GPIOB, CS); // 短延迟等待写使能生效 for(volatile uint32_t i = 0; i < 100; i++); // 读取状态寄存器 GPIO_ResetBits(GPIOB, CS); SPI_TransmitReceive(READSR); // 发送读状态寄存器指令,返回的无效数据丢弃 uint8_t eeprom_status = SPI_TransmitReceive(NULLBYTE); // 发空字节,读取状态值 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET); GPIO_SetBits(GPIOB, CS); // 输出结果到USART USART_SendData(USART1, eeprom_status);
内容的提问来源于stack exchange,提问作者DividianPC
相关产品推荐
相关产品推荐

