STM32G0B1CCT6是相对比较新的MCU,属于G系列,不支持标准库,所以下文用的是hal库或者ll库。
1 T! L% J% @0 p* i. \$ q6 P8 `
Z3 O( n+ j) O, F6 Z1 s! e( X8 D首先STM32G0B1CCT6是有256kflash的,每页2k,而规格书里面只提到0-63page,相当于128kflash。5 x# _- v+ x. ^# C' ]/ L
对于后128k的flash其实需要切换bank2才能使用。8 l' [' p ^- p8 x
下图为STM32G0B1CCT6的flash构成. _. C/ ]& ^2 G8 B
5 y% ?9 @9 a# D' Y' C& g( N; z5 {
* m) R3 c; k$ R* u' q! u然后我们先看正常如果要擦除第一页的代码6 w& H5 ]! F- X7 i$ W
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
5 ]4 C+ v: R7 \ h- J$ T - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
9 C# V2 i- m. _# `% `% m - ; Z- X" Z& k/ q0 ~
- HAL_FLASH_Unlock();
) X5 s- Z& ]7 s% S# F8 {
; X) G" ]+ _- F; D: r! Q- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作4 h4 e/ K* [7 a9 c9 \# {
- My_Flash.Page = 0; //声明要擦除的页& g3 [& J! ^7 w7 b
- My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值 `1 o5 n6 z7 f7 R/ n2 Y
- My_Flash.Banks = FLASH_BANK_1;
' Q$ B, Y) v% B9 ~; O - + [' h! P. Z* x
- //调用擦除函数! q) Z( p! F3 {/ S: w: n( }( F
- if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)
( _$ J2 K# g* }3 R# E! A - {
7 \3 K$ a0 u# k( d% |4 X/ m# p - //3、对FLASH烧写
8 H% F1 f- c* U, K - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
; F* U& v9 Q8 a2 Z. w. \) S- e - }4 E# w6 f0 E* a6 V/ ^- `
- //4、锁住FLASH
1 Y, R+ a q# V' C8 q8 N& F - HAL_FLASH_Lock();
复制代码
: J: x) e, ]; C5 z- a当我们要擦除后128k的第一页的时候,即第64页时,需要把FLASH_BANK_1切换到FLASH_BANK_2& p, r7 f" P! J0 r/ Q" @6 r$ e
不能直接在FLASH_BANK_1声明擦除第64页,切换到FLASH_BANK_2后,相应的页数为总页数减64页。
& w6 Q8 u" i1 M9 c3 _0 A( }- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
7 Q {8 L; j, S1 g! w9 t* r - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
* ?2 c" d: s( N
$ y* C5 a8 C6 ?6 C' ]) `- HAL_FLASH_Unlock();
; p% W# T0 G. }' I1 ? x3 o7 U6 W - $ p1 A" G* t6 d0 H( d
- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
( k {2 l5 k1 B. a" \' e - My_Flash.Page = 0; //声明要擦除的页9 q$ t# Z8 Z7 X' S* g& G
- My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
1 K4 Y& H( V r+ x& ~+ u( R, F - My_Flash.Banks = FLASH_BANK_2;
8 f; L5 ]* C; P: K# g! l, z. n
1 N; G5 W, m/ i& D$ \. u- //调用擦除函数4 `, `% L8 j1 ~/ m2 `, P1 I
- if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)
3 a1 Y/ l3 X j - {
* ~; f9 g$ \* I3 O u* s: N! n; b - //3、对FLASH烧写
3 d: z- L% e# I4 K) x* U: r - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
) X& K" z5 X+ t2 [# v - }* s" I0 J% h: `' ^# O4 g6 ^
- //4、锁住FLASH: e2 }6 `: Z' m' ]2 J
- HAL_FLASH_Lock();
复制代码
3 m7 v" `$ y& I4 {( h* [ g* Z, g, y+ S: p1 q& l- {. E' Z8 Q6 h
最后再附上一个ST-programmer和iar的一个小bug。我将这些问题均已反馈到原厂了。
$ o' X: e. g4 s9 K3 q+ h1、如果ST-programmer要单独擦除后128k是擦除失败的,因为软件本身没有切换bank2
* D. A) W s. L3 h$ P2、IAR烧录时该次使用到了后128k,则也是擦除失败导致烧录失败。第一次烧录成功,但是从第二次开始需要擦除到相应flash时,擦除失败就无法下载了(keil应该也是一样)
% E, Q: ]5 T1 u" j a) L0 M, ]
' l7 Z7 {) m# E6 A! h
1 j6 Y( S% j- ~: O4 U( U0 h: o% \/ ?
" C8 j# @ u9 @4 x9 o; _ |