|
STM32G0B1CCT6是相对比较新的MCU,属于G系列,不支持标准库,所以下文用的是hal库或者ll库。
9 e# R. k- f J9 \5 U# h1 I. n
" L u6 ~( q6 q3 x1 x+ }9 {2 T: ^6 z首先STM32G0B1CCT6是有256kflash的,每页2k,而规格书里面只提到0-63page,相当于128kflash。
! n3 G7 D% t$ M4 R, c9 p2 o对于后128k的flash其实需要切换bank2才能使用。8 l3 H" ~: G( @% S' A
下图为STM32G0B1CCT6的flash构成
: `! H8 Q) a( J# c! F" R( k! X) w% P( Y
; x& u, { a3 s1 n7 |4 |
然后我们先看正常如果要擦除第一页的代码
. ]5 h% [2 R: V/ h/ C- g3 C- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash1 ]8 ]3 i$ R, \( _8 A( {4 i! P
- uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址( q% E- ?9 g/ a% ?8 l
" j6 i. t8 m# [# X4 f6 c n- HAL_FLASH_Unlock();+ {0 U0 l+ _" @) }
* |: J( F& t' M7 E! \! o- A- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作# h7 L3 N7 p& t- g8 r
- My_Flash.Page = 0; //声明要擦除的页
. k) z* Z* V3 i) o: l m - My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
+ ?, T% a2 l0 J) a- I, U: M6 b - My_Flash.Banks = FLASH_BANK_1;/ P& a; s9 e0 i9 {8 g
- ) ]4 P0 r, R; p& i' Q& a
- //调用擦除函数0 S) `5 d, D4 d3 z# `5 i
- if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)4 S$ D. v) @; x9 {7 C7 a
- {! @; _2 ] Q% I+ ?) w% ]
- //3、对FLASH烧写: a9 Y3 b1 c' x, \- W3 s
- //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
9 D2 T1 s9 \2 s4 L9 Q4 @ - }: g. h) ^: g# D
- //4、锁住FLASH# W2 J* i) ~* o$ |
- HAL_FLASH_Lock();
复制代码 $ b0 `/ d q- J
当我们要擦除后128k的第一页的时候,即第64页时,需要把FLASH_BANK_1切换到FLASH_BANK_2) z2 O8 r, m1 x
不能直接在FLASH_BANK_1声明擦除第64页,切换到FLASH_BANK_2后,相应的页数为总页数减64页。
; e9 `" |# U- \% N" m) ~( k9 d- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
! D1 j- ^3 d3 J% ?2 W - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址/ g0 T! X" Y0 R# p9 W' e
8 E" d5 v- |( ? m$ C) g7 _- |3 z- HAL_FLASH_Unlock();
& z& m$ K$ q6 e2 R - & E3 b* {2 e& h. P7 i# W7 F
- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
) l0 Y! e1 Z( K( | - My_Flash.Page = 0; //声明要擦除的页' L2 ^5 ]( Z# y3 [, ]$ R
- My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
}- v2 H0 z" q# k" H+ p9 { - My_Flash.Banks = FLASH_BANK_2;, _# A: i6 {- J
& q# v2 M5 B/ G" v# V$ N" i* D. [- //调用擦除函数
3 \' n) v8 t* L- O' ^' i - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)
! ^7 ]$ Q- c4 Y9 }6 v/ W$ Y5 S - {! ~) R' C0 m5 Q. d, K
- //3、对FLASH烧写$ F* M! ^, F+ r+ T( U8 g% c9 b
- //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);# ^- z. U% \. g( | [! y5 {# `
- }
; Y6 i- s" |; g x4 ^ - //4、锁住FLASH! Q" q- M+ o, `& D: E' z% v
- HAL_FLASH_Lock();
复制代码
* n3 s4 r: E8 w' m* y/ e- ^' h0 P) C" I% A6 f# @8 q1 V X
最后再附上一个ST-programmer和iar的一个小bug。我将这些问题均已反馈到原厂了。
0 \: `5 {+ s: u s/ L2 S1、如果ST-programmer要单独擦除后128k是擦除失败的,因为软件本身没有切换bank2& _" f) C) l% z5 U
2、IAR烧录时该次使用到了后128k,则也是擦除失败导致烧录失败。第一次烧录成功,但是从第二次开始需要擦除到相应flash时,擦除失败就无法下载了(keil应该也是一样)
" q$ ^" W8 ?, n- [5 T4 s& A
! L! m& f: F! z! N+ q3 I3 f& H# ?; |) K& P+ g6 a* Q7 S% W
( ?' S$ P1 C( q* F. y" K+ a" N |