• 正文
  • 相关推荐
申请入驻 产业图谱

STM32F7 SPI 从机通讯异常?BSY 位卡死导致 OVERRUN 错误深度解析

05/21 13:43
293
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

在工业通信、电机控制等项目中,STM32F7 作为 SPI 从机应用广泛,但不少开发者遇到过数据转发不全、SPI OVERRUN 溢出错误等棘手问题。这类问题偶发难复现,看似是 DMA 或时序问题,实则暗藏芯片硬件勘误陷阱。本文基于 ST 官方 LAT1583 文档,结合 STM32F750 实测案例,从现象、排查、根源到解决方案,全流程拆解 SPI 从机通讯异常的核心原因,帮你彻底避坑。

资料获取:经验分享 | LAT1583 一例SPI从机通讯异常的分析

1. 问题现象:数据丢包 + 偶发溢出

某项目使用 STM32F750 作为 SPI 从机,主机通过 GPIO 电平触发从机 EXTI 中断,启动 / 停止 DMA 接收不定长数据。实际运行中频繁出现两个问题:

    1. 数据转发不全:主机下发的数据,从机转发时总是缺失部分字节;
  1. SPI OVERRUN 错误:调试发现 SPI 状态寄存器频繁报溢出错误,数据直接丢失。

初步排查 DMA 配置、SPI 时序、中断优先级,均未发现异常,问题偶发且无规律,严重影响项目稳定性。

2. 初步排查:卡在 Abort 函数的 “1 秒死锁”

梳理代码逻辑:主机拉低 GPIO 触发下降沿中断,从机调用HAL_SPI_Receive_DMA启动接收;主机拉高 GPIO 触发上升沿中断,从机调用HAL_SPI_Abort终止传输。

理论上 DMA 高速搬移不会导致溢出,但实测发现:上升沿中断中调用HAL_SPI_Abort时,偶尔会卡 1 秒以上。这段时间内若主机再次下发数据,从机无法响应新的下降沿中断,直接导致新一帧数据全部丢失,最终触发 OVERRUN 溢出。

3. 深层根源:芯片硬件勘误 ——BSY 位异常

跟踪HAL_SPI_Abort底层代码,发现卡顿源于SPI_EndRxTxTransaction函数 —— 该函数会循环等待 SPIBSY(忙)位清零。而查阅 STM32F7 勘误手册 ES0290,明确了硬件设计缺陷:

STM32F4/F7 系列 SPI 从机模式下,传输结束后,BSY位可能因 CPU 时钟与 SPI 时钟异步,偶尔异常置高且无法自动清零。

这意味着,当 SPI 传输完成后,硬件BSY位 stuck 在高电平HAL_SPI_Abort会无限轮询等待,造成 1 秒以上死锁。死锁期间 SPI 外设仍在接收主机数据,FIFO 满后直接触发 OVERRUN 溢出,数据彻底丢失。

4. 解决方案:固件升级 + 超时规避

针对 BSY 位硬件缺陷,ST 官方和实操验证提供两种解决方案,优先推荐固件升级。
方案一:升级 STM32Cube FW_F7 固件(根治)

ST 从V1.16.2 版本开始,已修复该硬件缺陷:

  • 底层驱动新增超时机制:若BSY位超时(默认 1ms,可按 SPI 时钟调整)仍未清零,直接判定传输完成,避免死锁;
  • 超时时间按 1 字节传输周期计算,适配不同 SPI 时钟频率。

实操步骤:

  1. 打开 STM32CubeMX,升级 F7 固件包至 V1.16.2 及以上;
  2. 重新生成代码,编译下载即可,无需修改业务逻辑。

方案二:手动添加超时(临时规避)

若无法升级固件,可修改HAL_SPI_Abort底层代码,增加超时判断:

// 新增超时计数器,按SPI时钟计算1字节传输时间
uint32_t timeout = 1000; // 1ms超时
while ((__HAL_SPI_GET_FLAG(hsp, SPI_FLAG_BSY)) && (timeout-- > 0));

注意:超时时间需匹配 SPI 时钟,过短会误判,过长仍可能卡顿。

本次 SPI 从机通讯异常,核心是STM32F7 硬件 BSY 位缺陷,而非代码或时序问题。这类偶发异常,优先查阅芯片勘误手册,往往能快速定位根源。

避坑核心建议

  1. STM32F4/F7 系列 SPI 从机项目,务必升级固件至 V1.16.2+,根治 BSY 位死锁问题;
  2. 开发时避免依赖BSY位判断传输结束,优先用RXNE(接收就绪)中断或 DMA 完成中断;
  3. 涉及 SPI 从机高速通信时,提前查阅 ES0290 等勘误手册,规避硬件陷阱;
  4. 遇到偶发通讯异常,优先排查芯片硬件勘误,再排查代码时序。

相关推荐