
1. 引言在 STM32 的应用中,SPI 算是用的比较多的外设了,也是单片机最常见外设之一。客户说它执行了关闭 SPI 的代码,竟然会导致 Flash 中的 WRPERR 标志置位,致使应用碰到一些问题。这就奇怪了,SPI 和内部 Flash 看起来是风马牛不相及的事情,为什么会发生这种事呢?一起来看看吧。 2. 问题 2.1. 问题起源 客户在使用 STM32L072RBT6 的时候,使用 STM32CubeL0 库,在程序编写时,发现执行关闭 SPI 代码时,会导致 Flash 的写保护错误标志 WRPERR 置位,导致其后面准备写 EEPROM 的时候,就无法对 EEPROM 写入了。 客户使用两个标志 flag1 和 flag2,来观察 WRPERR 标志的变化。代码如图 1 所示。 ![]() 在执行这个代码时,前面 flag1 还等于 0,执行到 flag2 那句,就变成 flag2 等于 1 了,同样地取了 WRPERR 标志位的值。所以客户就怀疑执行__HAL_SPI_DISABLE()会把Flash 的 WRPERR 标志置 1 了。 因为在对 EEPROM 编程中,需要先调用位于 stm32l0xx_hal_flash.c 中的FLASH_WaitForLastOperation()函数,此函数中,将会对 Flash 所有错误标志进行检查,如果出现了错误,它则返回 HAL_ERROR,导致后续对 EEPROM 的编程不会被执行。 2.2. 问题重现 使用 NUCLEO-L053R8 来验证客户的这个问题。在\STM32Cube_FW_L0_V1.10.0\Projects\STM32L053R8-Nucleo\Examples\SPI\SPI_FullDuplex_ComPolling 例程中直接进行修改测试。首先,把客户的测试代码加到例程中 SPI 初始化之后的位置。如图 2 所示。 ![]() 编译,并在线调试,发现并没有出现客户所描述的问题。如图 3 所示。 ![]() 可以看到,WRPERR 的值并没有被置 1,flag1 和 flag2 的值也都是 0。那么,为什么客户说他那边会有这个问题呢? 再回头仔细看一下客户的测试代码,发现客户的测试代码中并没有对 SPI 进行初始化,其__HAL_SPI_DISABLE()代码是放在其他外设初始化之后的。 好,那么再来修改一下测试代码,把客户这三句测试代码挪动到 SPI 初始化之前,如图 4 所示。 ![]() 编译,并在线调试,这时,会惊奇地发现客户所描述的问题来了。其结果如图 5 所示。 完整版请查看:附件 ![]() |
使用Nano板验证驱动SPI串口屏的颜色显示
【经验分享】STM32的SPI的原理与使用(W25Q128附代码)
【STM32C0评测】4、驱动Lorasx126x,实现透传
基于STM32的SPI传输时会丢失数据吗?
基于STM32基础的SPI总线概述
基于STM32的SPI读取数据的最后位出错问题经验分享
基于STM32关闭SPI会导致WRPERR错误的问题分析
基于STM32关闭SPI导致WRPERR错误经验分享
基于STM32CubeMX的SPI总线经验分享
如何实现基于STM32 SPI+DMAWS2812灯的驱动