0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

应用笔记 | 关闭SPI会导致WRPERR错误的问题分析

STM32单片机 来源:未知 2023-08-10 18:45 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

关键字:SPI,Flash,WRPERR

目录预览

1 引言2 问题3 问题解决4 小结

01 引言

STM32的应用中,SPI算是用的比较多的外设了,也是单片机最常见外设之一。客户说它执行了关闭SPI的代码,竟然会导致Flash中的WRPERR标志置位,致使应用碰到一些问题。这就奇怪了,SPI和内部Flash看起来是风马牛不相及的事情,为什么会发生这种事呢?一起来看看吧。

02 问题

2.1 问题起源

客户在使用STM32L072RBT6的时候,使用STM32 CubeL0库,在程序编写时,发现执行关闭SPI代码时,会导致Flash的写保护错误标志WRPERR置位,导致其后面准备写EEPROM的时候,就无法对EEPROM写入了。

客户使用两个标志flag1和flag2,来观察WRPERR标志的变化。代码如图1所示。

bd73cac8-3769-11ee-9e74-dac502259ad0.png

图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.0ProjectsSTM32L052R8-NucleoExamplesSPISPI_FullDuplex_ComPolling例程中直接进行修改测试。

首先,把客户的测试代码加到例程中SPI初始化之后的位置。如图2所示。

bd8bde6a-3769-11ee-9e74-dac502259ad0.png

图2.测试代码1(位于SPI初始化之后)

编译,并在线调试,发现并没有出现客户所描述的问题。如图3所示。

bdcd1132-3769-11ee-9e74-dac502259ad0.png

图3.测试代码1结果(位于SPI初始化之后)

可以看到,WRPERR的值并没有被置1,Flag1和Flag2的值也都是0。那么,为什么客户说他那边会有这个问题呢?

再回头仔细看一下客户的测试代码,发现客户的测试代码中并没有对SPI进行初始化,其_HAL_SPI_DISABLE()代码是放在其他外设初始化之后的。

好,那么再来修改一下测试代码,把客户这三句测试代码挪动到SPI初始化之前,如图4所示。

bdf126da-3769-11ee-9e74-dac502259ad0.png

图4.测试代码2(位于SPI初始化之前)

编译,并在线调试,这时,会惊奇地发现客户所描述地问题来了。其结果如图5所示。

be3694fe-3769-11ee-9e74-dac502259ad0.png

图5.测试代码2结果(位于SPI初始化之前)

可以看到,这时Flash的WRPERR标志位置1了,测试代码中,flag2的值也跟flag1不同了。

再做一个实验,将此处的HAL库写法,改成直接操作寄存器,来试一下。测试代码变成是图6这样的。

be561ea0-3769-11ee-9e74-dac502259ad0.png

图6.测试代码3(位于SPI初始化之前,直接操作寄存器)

编译,在线调试,这次又惊喜地发现,问题不见了。结果如图7所示。

be9c7256-3769-11ee-9e74-dac502259ad0.png

图7.测试代码3结果(位于SPI初始化之前,直接操作寄存器)

三种操作,为什么只有第二种方式有问题呢?而且为什么错的偏偏是Flash的写保护错误标志WRPERR呢?接下来可以分析一下它们的反汇编代码,看看到底是哪里出问题了。

2.3 反汇编分析

对于三种情况,把反汇编拉出来看最清楚其操作过程了。

先分析第一种情况——测试代码位于SPI初始化之后。其反汇编如图8所示。

bebaabb8-3769-11ee-9e74-dac502259ad0.png

图8.测试代码1的反汇编(位于SPI初始化之后)

从之前的Watch窗口,知道flag1的地址为 0x2000000c,flag2的地址为0x2000000d。

现在对三句C语言测试语句的反汇编语句进行解析,如下:

bed8369c-3769-11ee-9e74-dac502259ad0.png

beeb4f7a-3769-11ee-9e74-dac502259ad0.png

可以看到,这段汇编是一点问题都没有的。

接下来,先分析第三种情况——也就是测试代码放在SPI初始化之前,但是使用直接操作寄存器的方式。其反汇编如图9所示。

bf20e914-3769-11ee-9e74-dac502259ad0.png

图9.测试代码3的反汇编(位于SPI初始化之前,直接操作寄存器)

从之前的Watch窗口,知道flag1的地址为0x2000000c,flag2的地址为0x2000000d。

现在对三句C语言测试语句的反汇编语句进行解析,如下:

bf4f4e26-3769-11ee-9e74-dac502259ad0.png

bf8ab4ac-3769-11ee-9e74-dac502259ad0.png

可以看到,这段汇编也是一点问题都没有的。

最后,再来分析一下有问题的第二种情况,也就是测试代码放在SPI初始化之前,但是使用_HAL_SPI_DISABLE()关闭SPI的情况。其反汇编如图10所示。

bfa3c3c0-3769-11ee-9e74-dac502259ad0.png

图10.测试代码2的反汇编(位于SPI初始化之前)

从之前的Watch窗口,知道flag1的地址为0x20000008,flag2的地址为0x20000009。

现在对三句C语言测试语句的反汇编语句进行解析,如下:

bfca076a-3769-11ee-9e74-dac502259ad0.png

bfe4e65c-3769-11ee-9e74-dac502259ad0.png

可以看到,问题出在哪了?问题就出在“STR R3,[R 2]”这个语句上,这个语句在0x00000000这个位置写值,而0x00000000此时映射的是Flash的地址0x08000000,也就是Stack Pointer的位置。如图11和图12所示。

c019f0a4-3769-11ee-9e74-dac502259ad0.png

图11.0x00000000地址的数据

c04706ca-3769-11ee-9e74-dac502259ad0.png

图12.0x08000000地址的数据

首先,这个位置本来就不应该被修改。

第二,因为没有对Flash程序存储器进行解锁,就往里边写值,就会造成写保护错误,导致WRPERR标志位置位。所以,可以明白为什么WRPERR会被置位了。

可是关键的问题在哪儿呢?在执行“LDR R2,[R0,#4]”这条语句时,R2本来应该是SPI2_CR1的地址,但是它竟然是0x00000000!如图13所示。

c06c0ac4-3769-11ee-9e74-dac502259ad0.png

图13.0x2000000c地址的数据

从Watch窗口来看一下SpiHandle的情况。如图14所示。

c0827e80-3769-11ee-9e74-dac502259ad0.png

图14.SpiHandle(未初始化)

从图14可以看到,其实刚才的0x2000000c地址就是SpiHandle结构体的地址,也是SpiHandle.Instance的地址,而SpiHandle.Instance的值为0。SpiHandle.Ins tance.CR1的地址为0x0,导致显示它装载的值是Stack pointer的值0x20000468,这里本应该是SPI2_CR1的地址和SPI2_CR1的值。

也就是因为这里的问题,才会导致了后面的WRPERR错误。

2.4 代码分析

再回到代码这边来看一下,有问题的代码究竟是有什么情况。客户的代码主要就是一句关闭SPI的语句“_HAL_SPI_DISABLE(&SpiHandle);”。

这个语句是怎么解析的?它再stm32l0xx_hal_spi.h中解析,如图15所示。

c0a183d4-3769-11ee-9e74-dac502259ad0.png

图15._HAL_SPI_DISABLE函数

看到这个函数时,看到了重要的字眼——“Instance”!就明白是什么问题了,因为这个SpiHandle.Instance还没有被初始化呢!这也说明了为什么在图14中,看到的SpiHandle.Instance的值为0x0,而SpiHandle.Instance. CR2的值为0x20000468。关键就在于这个SpiHandle. Instance还没有初始化。

所以,把客户的测试代码放在SPI初始化代码之后没有问题,就是因为这个SpiHandle.Instance已经被初始化过了。所以,它不会有问题。

03 问题解决

本来客户的代码就没有必要这么写,因为SPI都没初始化,对它进行关闭并没有什么意义。

如果非要在这里关闭SPI的话,那就要先对SpiHandle.Instance进行初始化才行。如图16所示。

c0afe622-3769-11ee-9e74-dac502259ad0.png

图16._HAL_SPI_DISABLE函数

加了“SpiHandle.Instance=SPIx;”初始化后,再跑这段代码,就不会出现客户所说的问题了。

现在再来看一下SpiHandle的情况。

c0cadd38-3769-11ee-9e74-dac502259ad0.png

图17.SpiHandle(SpiHandle.Instance已初始化)

经过对SpiHandle.Instance的初始化,这里就可以看到SpiHandle.Instance的值为0x40003800了,为SPI2外设寄存器的基地址,而且可以看到SpiHandle.Instance. CR1的地址就是SPI2_CR1的地址0x40003800,值也是SPI2_CR1的值0x0了。

04 小结

在用户代码中,SpiHandle只是定义了SPI_HandleTypeDef结构体,其各种参数并还没有进行实际初始化。在没有初始化的前提下,对其进行操作时不对的,也是危险的,应该在写代码的时候引起重视。

使用HAL库的时候,如果要对一个外设进行任何的操作,请务必记得它是被初始化过的。否则,出了问题可能都不一定知道。

完整内容请点击“阅读原文”下载原文档。

c0e4716c-3769-11ee-9e74-dac502259ad0.png

长按扫码关注公众号

更多资讯,尽在STM32

点击“阅读原文”,可下载原文档


原文标题:应用笔记 | 关闭SPI会导致WRPERR错误的问题分析

文章出处:【微信公众号:STM32单片机】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6074

    文章

    45341

    浏览量

    663706
  • STM32
    +关注

    关注

    2305

    文章

    11122

    浏览量

    371193

原文标题:应用笔记 | 关闭SPI会导致WRPERR错误的问题分析

文章出处:【微信号:STM32_STM8_MCU,微信公众号:STM32单片机】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【EMC技术案例】SPI模块搭接机壳导致辐射超标问题案例

    【EMC技术案例】SPI模块搭接机壳导致辐射超标问题案例
    的头像 发表于 11-11 17:26 420次阅读
    【EMC技术案例】<b class='flag-5'>SPI</b>模块搭接机壳<b class='flag-5'>导致</b>辐射超标问题案例

    唯品:利用订单地址API校验收货信息,降低因地址错误导致的退货率

    ​  在电子商务领域,退货率高是许多平台面临的挑战,其中地址错误导致的退货占比不小。唯品作为国内领先的时尚电商平台,通过集成订单地址API(Application Programming
    的头像 发表于 09-11 15:47 382次阅读

    GPDV6624C应用笔记1.0版

    电子发烧友网站提供《GPDV6624C应用笔记1.0版.pdf》资料免费下载
    发表于 06-06 17:20 0次下载

    了解ISL28022的电流和功率计算应用笔记

    本应用笔记讨论数字电源监控器(DPM) ISL28022的内部计算程序。它解释了数据寄存器的位格式,并举例说明了内部数学处理器从测得的分流和总线电压导出电流和功率值的程序步骤。本应用笔记是ISL28022数据手册的摘要。
    的头像 发表于 02-21 11:30 982次阅读
    了解ISL28022的电流和功率计算应<b class='flag-5'>用笔记</b>

    电压反馈与电流反馈运算放大器应用笔记

    本应用笔记比较了电压反馈型(VFB)和电流反馈型(CFB)运算放大器的基本性能特征,面向不熟悉CFB放大器的工程师。熟悉该主题的读者可以直接阅读第9页的表l,该表总结了本应用笔记中讨论的主要特性。
    的头像 发表于 02-21 10:37 1202次阅读
    电压反馈与电流反馈运算放大器应<b class='flag-5'>用笔记</b>

    高侧、大电流传感技术应用笔记

    本应用笔记讨论两种新的电路技术,用于测量电源应用中的高端电流。与标准差动放大器配置相比,这些新配置提供了相当高的精度和增益带宽。
    的头像 发表于 02-21 10:12 792次阅读
    高侧、大电流传感技术应<b class='flag-5'>用笔记</b>

    CDK应用笔记

    电子发烧友网站提供《CDK应用笔记.pdf》资料免费下载
    发表于 01-16 16:17 0次下载
    CDK应<b class='flag-5'>用笔记</b>

    ES32VF2264应用笔记

    电子发烧友网站提供《ES32VF2264应用笔记.pdf》资料免费下载
    发表于 01-16 16:14 0次下载
    ES32VF2264应<b class='flag-5'>用笔记</b>

    ES7P0214应用笔记

    电子发烧友网站提供《ES7P0214应用笔记.pdf》资料免费下载
    发表于 01-16 16:06 0次下载
    ES7P0214应<b class='flag-5'>用笔记</b>

    智通国际推出全新商用笔记本品牌恒悦

    1月15日,智通国际旗下品牌恒悦举办了全新一代商用笔记本的发布。当前PC市场正处在传统PC向AI PC迈进的关键时刻,硬件架构创新、产品形态创新、软件应用创新风起云涌。而作为AI向大众普及的最佳
    的头像 发表于 01-16 16:01 1330次阅读

    ES7P0213应用笔记

    电子发烧友网站提供《ES7P0213应用笔记.pdf》资料免费下载
    发表于 01-16 15:26 0次下载
    ES7P0213应<b class='flag-5'>用笔记</b>

    AT32F423 PWC应用笔记

    电子发烧友网站提供《AT32F423 PWC应用笔记.pdf》资料免费下载
    发表于 01-15 15:30 0次下载
    AT32F423 PWC应<b class='flag-5'>用笔记</b>

    电桥电路的常见错误分析

    电桥电路的常见错误分析主要包括以下几个方面: 一、电阻值不准确 电阻值不准确是电桥电路常见的错误之一。这可能是由于电阻本身的误差,如电阻的标称值与实际值存在偏差,或者电阻老化、温度变化等因素
    的头像 发表于 01-09 10:08 1946次阅读

    S32K3系列汽车级MCU应用笔记

    电子发烧友网站提供《S32K3系列汽车级MCU应用笔记.docx》资料免费下载
    发表于 12-30 15:43 2次下载

    S32K3xxICU应用笔记

    S32K3xxICU应用笔记
    发表于 12-30 15:38 2次下载