STMCU小助手
发布时间:2025-11-17 10:10
|
有人使用STM32G474芯片做开发,在涉及到单双BANK的页擦除时遇到些问题并心生疑惑。 按照手册描述,Single ank是整个芯片内部FLASH为单一Flash区域,最小页擦除单位是4KB,Dual ank就是将片内FLASH等分为2份,支持双Flash区域,一边的擦写操作不影响另外一边的程序运行,此时的最小页擦除单位是2KB【下面会将2KB页和4KB页分别称之为小页和大页】。 但该用户在使用过程中,对单双BANK的判定标准感觉有点不确定,比方到底是DBANK位还是BFB2位还是二者共同确定?对于单BANK的页擦除的空间大小也颇为疑惑,感觉跟手册写的不一致。 首先,关于FLASH单双BANK的判断标准,手册描述得很明确,就是DBANK位,我们可以通过FLASH选项字节寄存器的DBANK位得到信息。该位若为1,则是双BANK模式,否则就是单BANK模式。至于BFB2位,它是决定在双BANK前提下是否支持从BANK2启动的控制位。当然,更不是代码中某个宏定义来决定,宏定义只是软件代码 配合 硬件的相应写法,即代码实现要跟硬件设置匹配。
其次,关于FLASH单、双BANK页擦除的最小容量问题,手册描述也得很清楚,单BANK模式下为4KB/页,双BANK模式下为2KB/页。 我们可以通过对Flash选择字节进行编程完成对FLASH单双BANK模式的选择,有两种实现方式。第一种,使用工具,比方STM32CubeProgrammer在图形界面下直接对DBANK编程位进行勾选或取消勾选来完成;第二种就是程序员基于用户代码对flash Option字节进行编程完成。若不是特别需要,一般利用工具完成方便省事【下面截图是选择双BANK的配置,如果选择单BANK取消勾选后APPLY即可】。
我们借助STM32Programmer工具做单、双BANK的选择,然后生成最简单的代码后,在调试状态下可以查看FLASH选项寄存器的相关数据信息。【FLASH选项寄存器地址在手册里注明】
上图是选择单BANK模式时FLASH选项寄存器的内容,我们只关注DBANK位,此时BIT22为0。再看看另外一种情况:
不难看出,上图是Flash双BANK模式时选项字节寄存器的内容,DBANK为1。 不论我们选择使用单BANK模式还是双BANK模式,从物理地址来看都是连续的一堆空间,只是划分的Page页大小不一样,单BANK每页4KB,双BANK每页2KB。下面是相关截图,分别是单BANK和双BANK下的FLASH page地址布局图。【注意:不要把图中information block中的BANK1 BANK2跟我们下面要提到的双BANK模式下的BANK1 BANK2混在一起,这会不要理这些。】
基本的东西就介绍到这里,下面我们一起来验证两种模式下的页擦除操作。下面基于ST提供的STM32G4cube库里如下例程来进行。
目前来看,通过该例程实现双BANK模式下的页擦除是没啥大问题的。 该例程默认基于双BANK模式编写,如果擦除BANK1的页没啥问题,若擦除BANK2的页或基于单BANK做页擦除,代码上得稍微调整下。例程不算完美,瑕不掩瑜吧。毕竟基本操作流程都有了,API库函数也准备得比较齐备。 我们先基于双BANK模式来验证页擦除。芯片是G474RE。。 要做的事情就是先后对BANK1和BANK2的第48页进行擦除。页编号依据参考手册从0开始算,两个BANK分别编号。在STM32G4系列的库代码中,它按照2KB单位统一定义了256页的地址表,这样定义可以兼容单双BANK的地址信息获取,只是在不同模式下获取页码时稍加注意。我截图过来看看:
我们基于上表或参考手册,可以得知将被擦除的2页的起始地址,见下图:
我通过常量指定存储的方式,先在上面两页的起始位置都写上些数据。
现在就分别对位于两个BANK的页做先、后擦除。 这里对例程里的一些宏和两个用户函数【不算是库函数,只是设计人员临时准备的用户代码】稍微解读下。 FLASH_BANK_SIZE宏,用来计算BANK大小,它跟另外一个宏FLASH_OPTR_DBANK关联。FLASH_OPTR_DBANK决定代码里是否使用双BANK,若用双BANK, 则FLASH_BANK_SIZE的大小就是片内主Flash的一半,若是单BANK,FLASH_BANK_SIZE的大小自然就是整个片内主FLASH空间。 再就是另外两个用户静态函数:
这两个函数是当初设计者为了演示FLASH擦写功能基于双BANK模式而写。若要对BANK2进行页擦除或基于单BANK进行擦除,目前我们有必要自行对其做些调整。我把这两个函数稍作改动,贴出来供参考。修改后的函数代码兼容单、双BANK模式。
FLASH_BASE/FLASH_PAGE_SIZE/FLASH_BANK_SIZE/FLASH_OPTR_DBANK都是例程里本来定义好了的。 FLASH_PAGE_SIZE对应小页大小,即2KB。FLASH_OPTR_DBANK表示代码是否适用于双BANK模式。另外,那个MiddleAddr是我定义的宏,双BANK时才用得到,即双BANK时中间的地址分界值。这个不难理解,这个值需结合芯片不同FLASH容量来定,比方128K Flash芯片和256KB Flash芯片的中间值肯定不一样。 主用户代码就是下面这些,完全沿用例程的写法。我只是微调了GetPage()和GetBank()两个函数的内容。这里每次只擦一页,重点验证单次页擦除操作到底擦除多少空间。
我分两次先后擦除BANK1和BANK2的第48小页。下面是验证结果。
上图的上半部分的左边是擦除前待擦除页的部分内容,右边是做了2次页擦除的结果。 上图的下半部分是调试状态下被擦除的2页的编号信息及所在的BANK域,即BANK1还是BANK2。此时的BANKSIZE是256KB。 现在来基于单BANK模式做页擦除操作。 首先使用STM32Programmer将FLASH选项字节的DBANK位清零,变成单BANK模式。这里就不重复贴图了,开篇有操作截图。 另外,基于现有例程写法,关闭使用双BANK相关的宏定义。见下图所示:
现在打算擦除单BANK模式下的第50页,是4KB大页。此时BANK号只有BANK1了。【提醒:如果使用双BANK模式,请保证上面宏定义是开启的】
我们可以依据手册或代码找到单BANK模式下编号为50的页起始地址。显然,该页相当于双BANK模式下的2个小页。上图的写法只是沿用库定义而已,知道怎么回事即可。毕竟没必要为单、双BANK做两个地址表。 现在采用跟前面类似的做法,我先在该大页的起始位置和中间位置预先写点东西,然后做一次单页擦除,看看被擦除的到底是2KB还是4KB。 代码方面在写法上跟前面双BANK模式下完全一样,不同的只是给的参数变了。具体就是BANK后和页编号。当然,核心的变化就是FLASH应用模式变了,这通过前面的修改选项字节DBANK位并屏蔽代码中使用双BANK的宏定义来完成。 下面最终的测试结果的相关截图:
上图的上半部分的左边是擦除前待擦除页的起始位置和中间位置的部分内容,右边是做了1次页擦除的结果,是一次性擦除了4KB空间的FLASH。 上图的下半部分是调试状态下看到的被擦除页的编号信息及所在的BANK域。其实,此时只有BANK1,还可以看到BANKSIZE是512KB,正好是双BANK模式下2倍。 关于STM32G4系列单双BANK模式下的页擦除操作就介绍、演示到这里。整个操作基于现有例程,具体实现时需对个别用户函数及定义做适当调整以适应不同需求。东西不多,也不算复杂,但要完全实现估计还是要花点精力。最后顺便提醒下,即使STM32G4系列也不是全系列支持双BANK模式,哪些子系列支持可以参考下图信息。
OK,今天的话题就聊到这里,下次再聊。 文章出处:茶话MCU |
经验分享 | STM32G4片内FLASH擦写实验笔记
经验分享 | STM32G4系列是否支持位带操作
STM32系列芯片之间相互移植注意事项
STM32如何成为现代科技的隐形引擎
大神都是怎么学习STM32的,我也跟着学
如果你解决了这些问题,就可以直接学STM32
经验分享 | 基于STM32G4芯片TIM+SPI+DMA应用示例
新手学几天STM32,为啥一脸茫然
实战经验 | STM32G474勘误手册中SRAM Write Error详解
STM32电机控制用什么型号?高级定时器功能详解与芯片选型指南
微信公众号
手机版