1. 引言在 STM32 的应用中,SPI 算是用的比较多的外设了,也是单片机最常见外设之一。客户说它执行了关闭 SPI 的代码,竟然会导致 Flash 中的 WRPERR 标志置位,致使应用碰到一些问题。这就奇怪了,SPI 和内部 Flash 看起来是风马牛不相及的事情,为什么会发生这种事呢?一起来看看吧。 2 \$ {2 F7 @$ l& } 2. 问题$ D O2 A! C( G7 g# k$ J4 \2 Q7 y 2.1. 问题起源, i1 ~5 N9 A, O& a 客户在使用 STM32L072RBT6 的时候,使用 STM32CubeL0 库,在程序编写时,发现执行关闭 SPI 代码时,会导致 Flash 的写保护错误标志 WRPERR 置位,导致其后面准备写 EEPROM 的时候,就无法对 EEPROM 写入了。 客户使用两个标志 flag1 和 flag2,来观察 WRPERR 标志的变化。代码如图 1 所示。, v8 V5 G! j& | ! R( C; Q2 a& I 3 s, p# [' O' e! z3 o 在执行这个代码时,前面 flag1 还等于 0,执行到 flag2 那句,就变成 flag2 等于 1 了,同样地取了 WRPERR 标志位的值。所以客户就怀疑执行__HAL_SPI_DISABLE()会把Flash 的 WRPERR 标志置 1 了。8 Y$ h0 ^+ c6 K( v& H 因为在对 EEPROM 编程中,需要先调用位于 stm32l0xx_hal_flash.c 中的FLASH_WaitForLastOperation()函数,此函数中,将会对 Flash 所有错误标志进行检查,如果出现了错误,它则返回 HAL_ERROR,导致后续对 EEPROM 的编程不会被执行。 2.2. 问题重现. W$ Y* _. g2 |9 u 使用 NUCLEO-L053R8 来验证客户的这个问题。在\STM32Cube_FW_L0_V1.10.0\Projects\STM32L053R8-Nucleo\Examples\SPI\SPI_FullDuplex_ComPolling 例程中直接进行修改测试。首先,把客户的测试代码加到例程中 SPI 初始化之后的位置。如图 2 所示。 编译,并在线调试,发现并没有出现客户所描述的问题。如图 3 所示。 $ w/ M& z* X3 w4 Z 8 D( K/ C5 D( L* x5 w. p 1 t m& x. u! }) n1 M ) M% E n; F3 o+ G% _4 e. b0 ? 可以看到,WRPERR 的值并没有被置 1,flag1 和 flag2 的值也都是 0。那么,为什么客户说他那边会有这个问题呢? 再回头仔细看一下客户的测试代码,发现客户的测试代码中并没有对 SPI 进行初始化,其__HAL_SPI_DISABLE()代码是放在其他外设初始化之后的。 好,那么再来修改一下测试代码,把客户这三句测试代码挪动到 SPI 初始化之前,如图 4 所示。 ' d I; Z' X% ^$ d/ W. p + X4 B6 Q0 q7 |! z* ~ 编译,并在线调试,这时,会惊奇地发现客户所描述的问题来了。其结果如图 5 所示。 + ?$ Z) R; s. }3 K 5 M3 ]! Y( c- _ 8 T& b4 ~; }& ]; U 完整版请查看:附件 |
【STM32C0评测】4、驱动Lorasx126x,实现透传
基于STM32的SPI传输时会丢失数据吗?
基于STM32基础的SPI总线概述
基于STM32的SPI读取数据的最后位出错问题经验分享
基于STM32关闭SPI会导致WRPERR错误的问题分析
基于STM32关闭SPI导致WRPERR错误经验分享
基于STM32CubeMX的SPI总线经验分享
如何实现基于STM32 SPI+DMAWS2812灯的驱动
基于STM32F030硬件SPI经验分享
基于STM32的经验分享—SPI详解