STM32G0B1CCT6是相对比较新的MCU,属于G系列,不支持标准库,所以下文用的是hal库或者ll库。 3 E0 e: d$ t" h' w) t
8 z; h+ `; ?& c! j# I首先STM32G0B1CCT6是有256kflash的,每页2k,而规格书里面只提到0-63page,相当于128kflash。0 R, @5 C' @4 d/ d6 ~& O* {, b
对于后128k的flash其实需要切换bank2才能使用。
. [8 U8 e4 ?* h1 x# d( d. G下图为STM32G0B1CCT6的flash构成5 S0 z+ r1 a0 ^, J5 v
" z% U+ ?0 w I+ W; \3 |: }0 H2 s8 x6 [( K6 T
然后我们先看正常如果要擦除第一页的代码3 \7 Q. F$ W* i, l' U9 S) q5 Q& Y
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash' c# v1 [2 J, f1 N5 L
- uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
2 J- E; i- Z" v - / F& E7 M# N/ T' M: Q
- HAL_FLASH_Unlock();
- K% L# Y( V" q+ h/ i
' ] C4 W- b/ e+ a; p1 N- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作+ b5 [/ o, p% O% |7 M" j
- My_Flash.Page = 0; //声明要擦除的页/ d* {8 f, F- \( t1 u/ \
- My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
, a0 @! E9 i$ k+ ^ - My_Flash.Banks = FLASH_BANK_1;& ^" ?! a# \7 t( q" W v0 y
- 5 T+ U* k* h* B
- //调用擦除函数2 S: \5 s0 D; e' E2 J
- if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)
@5 a! m0 q7 R: ]/ z/ W - {
! X6 ?/ t4 P. b+ o# K - //3、对FLASH烧写0 t% n8 q# C/ l$ N0 D
- //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);0 e9 c0 N/ X2 n/ W. q& p
- }% J9 u+ H5 ]7 h; z- @0 R
- //4、锁住FLASH; I8 {# u& n) h- W( G
- HAL_FLASH_Lock();
复制代码
) P& B$ V; b' L1 q; l6 [当我们要擦除后128k的第一页的时候,即第64页时,需要把FLASH_BANK_1切换到FLASH_BANK_20 J( ?/ i( q7 f9 w
不能直接在FLASH_BANK_1声明擦除第64页,切换到FLASH_BANK_2后,相应的页数为总页数减64页。
& N/ A( J# |( x* d7 r3 k4 v- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
, q0 M- l, a5 h2 q - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
/ O( s+ u9 J* H4 E- Z4 ^3 q5 Y - ) e% B* \: Y5 |) Y
- HAL_FLASH_Unlock();5 k i$ U8 d' d' G2 z# }, ?& e
8 c$ A& q( A7 o- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
1 C7 c6 }: h9 x* J5 i% [1 {) { - My_Flash.Page = 0; //声明要擦除的页
( b/ t! w- H- ?: H2 M - My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
) B. e; O4 o4 h- U3 [! `# S - My_Flash.Banks = FLASH_BANK_2;
; V- s' n& C W7 E" X - ; ~: q- p7 |% b8 ~5 [8 c
- //调用擦除函数9 @) |- n8 F1 u; R
- if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)! ]$ `; R$ y- J- E- }# g' d! r
- {
6 r- | E" R5 w3 g' v: d; }$ b - //3、对FLASH烧写+ r) ^& D1 N. h' z/ N. h
- //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);! b% q( s- D3 u/ y0 @
- }7 X6 c# K- I8 t
- //4、锁住FLASH
8 D) L$ @0 i6 W3 J - HAL_FLASH_Lock();
复制代码 ; l7 E# s3 O+ O. |# v" s+ J+ D% P
7 h9 Z9 {- a7 V8 z( E3 }最后再附上一个ST-programmer和iar的一个小bug。我将这些问题均已反馈到原厂了。
: x/ G! U' j4 Z5 C b$ p1、如果ST-programmer要单独擦除后128k是擦除失败的,因为软件本身没有切换bank2- F. u7 M( [6 {6 X
2、IAR烧录时该次使用到了后128k,则也是擦除失败导致烧录失败。第一次烧录成功,但是从第二次开始需要擦除到相应flash时,擦除失败就无法下载了(keil应该也是一样)
( ?7 N( l1 u3 ~' G% [. q" q* e7 g. j4 A
4 v" b% y' b* D
3 r- `, M, N ?7 M7 E. i! {( W |