STM32G0B1CCT6是相对比较新的MCU,属于G系列,不支持标准库,所以下文用的是hal库或者ll库。
1 \ l8 @' E& Y' z0 O+ g4 D
1 ~+ A$ O& U$ t. _, ]首先STM32G0B1CCT6是有256kflash的,每页2k,而规格书里面只提到0-63page,相当于128kflash。4 U2 v$ C% k" T0 e5 v
对于后128k的flash其实需要切换bank2才能使用。
2 z- Q8 ^+ _$ S- ]( O: e# Q. O下图为STM32G0B1CCT6的flash构成5 Z7 k! ]& B' ?& k0 f; j7 l% Z
|# z# R% t0 G* r. D: ]$ Y! o( J
% o% M( m0 _, S7 G; z% D# h然后我们先看正常如果要擦除第一页的代码1 i% E' x1 q6 u3 ]% q# K4 j2 a
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
, Y- Y8 i0 f" Y9 B4 M( }9 f - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
/ `5 r) N e1 E+ B" y$ s
" f0 V' s4 U w$ q+ s0 d" O+ E4 _- HAL_FLASH_Unlock();3 G9 L# J3 i. J9 i& I% d
U0 {4 Y3 Y' b; R( B/ a5 Y- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
4 Q- X0 O6 a2 \' j - My_Flash.Page = 0; //声明要擦除的页
* P9 K- C% q% O# u - My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值( i+ ^1 o. _: O
- My_Flash.Banks = FLASH_BANK_1;+ c% f) b) g$ K+ b% d- n# T
- / \; g& U7 J0 O* R) }
- //调用擦除函数
4 ~+ C x. c1 P7 w0 P! u - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)
1 C; q) W( \( D7 u y( M6 E6 C - {
6 i! t) t+ p* S0 b - //3、对FLASH烧写
+ B; E1 P/ w% L' Z3 d& e - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);* m1 H5 S8 T: v _5 _% R! e( t
- }/ e. J/ _' S3 l; u( S+ s% l
- //4、锁住FLASH1 r9 P$ R# ?/ z
- HAL_FLASH_Lock();
复制代码
+ T7 T' j) V- T0 ^当我们要擦除后128k的第一页的时候,即第64页时,需要把FLASH_BANK_1切换到FLASH_BANK_2. I; v% q8 [0 F! Y
不能直接在FLASH_BANK_1声明擦除第64页,切换到FLASH_BANK_2后,相应的页数为总页数减64页。
# i( P5 o \! \" p+ j- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash5 e& ]; e) h4 t
- uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
' t1 X5 @/ N! ]3 n - 0 \+ g# |% l1 _# S2 @
- HAL_FLASH_Unlock();
% z# ]* Z: O' t
3 A' b7 Y5 f, {- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作 g7 ?; I* W% L& E8 ~$ _
- My_Flash.Page = 0; //声明要擦除的页 s; ^. q# B# S- q
- My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
# z1 S% |% a) k! H$ U- ]+ S - My_Flash.Banks = FLASH_BANK_2;' Y2 i1 A0 c" [
- 9 l4 s; d M* W C' Y
- //调用擦除函数& n/ B: Q% C5 f* r$ z/ v/ S4 G
- if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)) x! Z. Q' K) x C& \+ R5 J$ \
- {$ y0 n; f6 ^* e X/ S& g5 i" Q
- //3、对FLASH烧写
# q" ^# a7 {9 U; `- z5 _ - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);, ~0 R# \8 \' [+ F4 b
- }( m4 b9 G" {. D# ^$ i) a
- //4、锁住FLASH# B& f3 F/ A J0 ]5 b: P
- HAL_FLASH_Lock();
复制代码 9 T/ l7 M7 @. c# r8 I0 f
4 |4 o7 A4 e, M. s% R, f: Z( @最后再附上一个ST-programmer和iar的一个小bug。我将这些问题均已反馈到原厂了。
2 C' @# D$ @7 {6 \3 V9 r! M$ h1、如果ST-programmer要单独擦除后128k是擦除失败的,因为软件本身没有切换bank2
0 T; o* Z& {9 k$ b# Z- U2、IAR烧录时该次使用到了后128k,则也是擦除失败导致烧录失败。第一次烧录成功,但是从第二次开始需要擦除到相应flash时,擦除失败就无法下载了(keil应该也是一样)
4 b) ?# n1 a/ R1 ^! |4 j* i O3 _# a( {
4 U3 y/ B5 _% ?+ o* O& N S
* b2 p5 ^' t$ G6 ]! K
|