|
STM32G0B1CCT6是相对比较新的MCU,属于G系列,不支持标准库,所以下文用的是hal库或者ll库。 % m) M3 @6 { w& O$ s# v
8 U' I3 e1 _0 f) e; S首先STM32G0B1CCT6是有256kflash的,每页2k,而规格书里面只提到0-63page,相当于128kflash。5 {8 h9 }0 @- A( @8 E( u
对于后128k的flash其实需要切换bank2才能使用。
0 X! f( Z- `8 N& l3 l下图为STM32G0B1CCT6的flash构成! T: I8 O) j4 ~5 F. Q I
) Y4 i% S H% Y
2 y# S4 D7 E* c n
然后我们先看正常如果要擦除第一页的代码/ F( m# ~8 { N
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
( Z; V6 S- Z5 x& A& U! Z1 U( K. H - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址: m8 n7 g( S C4 |6 ~
- ) o4 P" ?; D6 E- O, B# ]
- HAL_FLASH_Unlock();. f$ Z- R F: s% v4 w, q
- ! d! P/ L' \$ \) ^
- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作7 r% `- D3 s6 f% t1 w2 E3 y5 s: o
- My_Flash.Page = 0; //声明要擦除的页
5 R: r! P* j9 U. \" A% I1 i - My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值% U7 I/ g+ D5 _; |7 R
- My_Flash.Banks = FLASH_BANK_1;
4 X. y! [& c5 N9 Y8 R' ]2 B1 f
, t" F9 a& f% l2 y* U# C- D/ Y! @- d- //调用擦除函数
/ o3 E1 n, X4 k2 L - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)* y% [, e m' w* q4 c9 Y( G. a
- {
+ d3 `4 O8 b3 {) ^; F; u; n - //3、对FLASH烧写
6 v- v9 U" D. |% a& z( s6 Y - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
2 G4 o1 ^! s: C6 Q& d - }6 r+ }7 K0 v% |9 z4 i+ |% g
- //4、锁住FLASH
, T% J5 K2 X) ~- w - HAL_FLASH_Lock();
复制代码 9 F7 y. @$ T! M( W4 r* x
当我们要擦除后128k的第一页的时候,即第64页时,需要把FLASH_BANK_1切换到FLASH_BANK_2
2 g# L3 y1 H' ?/ V- i/ {不能直接在FLASH_BANK_1声明擦除第64页,切换到FLASH_BANK_2后,相应的页数为总页数减64页。5 c ?7 b6 n) h& F8 d
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
7 a( P+ Q p3 C" X1 O% I - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址+ R: j0 r9 X6 @# l
" o# H8 A! M8 A1 `7 F- HAL_FLASH_Unlock();
# p8 a4 {6 i# ] ^# V' U - # h5 d9 k$ S/ T6 f% ]
- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
+ o q$ } O: F# @; \) m4 v - My_Flash.Page = 0; //声明要擦除的页
, a7 Q; B9 v0 x: j! {. E0 Y$ T) K: z - My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值/ o- h' S/ r: O4 z
- My_Flash.Banks = FLASH_BANK_2;
& }/ y, J! j' ?, h) x0 r8 M! G# x: V
: C. c% P5 n5 V$ {8 M5 Q' T. W- //调用擦除函数
0 T N: t* e! N3 h& h! G& z - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK), h( n4 L& S" ]5 G0 l
- {* @6 b& S4 M% D3 V" p
- //3、对FLASH烧写
5 j$ f; [+ U U( @! D" J8 p - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
' F( I" e, o/ \$ V2 n9 y - }! x3 y. ^* p6 I, Z* I
- //4、锁住FLASH+ ]& L0 \0 q8 C% N3 R" X+ p( ?8 m0 Q
- HAL_FLASH_Lock();
复制代码
& A! t8 t3 `0 r7 z
* w; g% f& T% x" k; r5 }6 B7 D! c* B最后再附上一个ST-programmer和iar的一个小bug。我将这些问题均已反馈到原厂了。
+ d: O0 }' r$ P8 u/ x$ H9 }1、如果ST-programmer要单独擦除后128k是擦除失败的,因为软件本身没有切换bank2+ E7 q$ u" ^7 Q5 ?4 E
2、IAR烧录时该次使用到了后128k,则也是擦除失败导致烧录失败。第一次烧录成功,但是从第二次开始需要擦除到相应flash时,擦除失败就无法下载了(keil应该也是一样). z5 B K; E6 j+ ?# G
4 X' J9 A! [3 Q9 |+ g, A. `0 W* A
9 l5 Z$ M" `7 A3 z6 h9 Y9 b
" o. _, F& }4 K
|