STM32G0B1CCT6是相对比较新的MCU,属于G系列,不支持标准库,所以下文用的是hal库或者ll库。
( Y0 G2 E" N2 g) F5 Y
2 b% _# f4 V( C' i) g( w- ?首先STM32G0B1CCT6是有256kflash的,每页2k,而规格书里面只提到0-63page,相当于128kflash。
/ h: z9 ~3 q# G( } v/ [9 x对于后128k的flash其实需要切换bank2才能使用。! t5 r0 h% @1 i, y- E
下图为STM32G0B1CCT6的flash构成
$ p- A8 L% B# d# S) z$ E$ N& U) L/ C* l( o4 ]) E9 d0 b* Q
5 i; U; b y5 x/ o+ ?0 w
然后我们先看正常如果要擦除第一页的代码8 o. }" z6 |8 V" v F
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
6 Q l; J! S6 ] - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址2 D! ^& q/ b) J" A- f* N( t9 P; k8 h8 m1 R
- : f! Y/ z7 J3 Q' M# A
- HAL_FLASH_Unlock();
6 Y( S+ J5 v# b0 W# {. x# h - 3 N* D3 U) r, p4 H0 ~
- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
. h; N, d/ V4 L0 Z( B$ { - My_Flash.Page = 0; //声明要擦除的页
9 u- j& C8 R: |6 G) I: [5 Q9 F - My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
! n3 P# k! z% b" l - My_Flash.Banks = FLASH_BANK_1;
; T( s& \) J# Z; G G - 5 V* v; F' _' H/ r" h0 p
- //调用擦除函数
9 O+ E2 \; {3 v P% z9 f - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK), x$ V! |; d6 {: j" o
- {
2 l1 R g+ ]6 ~& m$ o8 S! o* F - //3、对FLASH烧写
7 P. V' Y" J3 e" r& a - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
( M+ w7 ^" ~: ^% m/ J2 z/ Z! _ - }
& T9 Q. ?' Z( a1 t' K) k - //4、锁住FLASH. H7 U* n' \/ \
- HAL_FLASH_Lock();
复制代码
7 o7 j; d! }8 X当我们要擦除后128k的第一页的时候,即第64页时,需要把FLASH_BANK_1切换到FLASH_BANK_2
, Y7 U2 Q; G/ K, Y- i% g不能直接在FLASH_BANK_1声明擦除第64页,切换到FLASH_BANK_2后,相应的页数为总页数减64页。5 z0 _& d& s/ |9 r9 y: {; h
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
, Z# I/ d; X7 n& ]' ~ X& F - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
/ r+ H s5 S/ z% \# ?+ b* ^ - % V' D. i0 _, P) R, [
- HAL_FLASH_Unlock();
9 Y) O8 x$ R: T! \- h4 R- g1 C" l
4 u1 S1 ?- M' a, F& `8 s8 @+ x- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
4 v+ L! v* S/ Y( E! _9 I% W - My_Flash.Page = 0; //声明要擦除的页
% ~- V, f- ~" @8 U+ b; |6 K4 V - My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值/ u4 ^1 \ q8 q7 E5 c) ]+ w7 P7 Q. z
- My_Flash.Banks = FLASH_BANK_2;
& L9 v0 t' w5 @ - 3 j) s! Z/ D- p/ m( N' m" W! h
- //调用擦除函数
* ^: t2 j) k0 `9 e7 S; P" N - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)6 O- s3 E$ @2 _* w& D
- {" l9 I: _7 t) |/ @( j
- //3、对FLASH烧写4 E" y* s( T, b0 l2 Z$ F
- //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);; a( H: {: L" _, f% r. J
- }
6 Z, \- D2 r; r& t% i/ { - //4、锁住FLASH8 N& w+ H4 k( h2 ]
- HAL_FLASH_Lock();
复制代码
% v; j `2 Y2 k* M% X$ W0 k- o+ E2 h, {7 M
最后再附上一个ST-programmer和iar的一个小bug。我将这些问题均已反馈到原厂了。8 J7 i" A: z; T" q
1、如果ST-programmer要单独擦除后128k是擦除失败的,因为软件本身没有切换bank2! t' u, p8 F5 Y* [
2、IAR烧录时该次使用到了后128k,则也是擦除失败导致烧录失败。第一次烧录成功,但是从第二次开始需要擦除到相应flash时,擦除失败就无法下载了(keil应该也是一样)
& K: @6 d- ~& `8 C& p N
. i6 ^7 K7 p- H$ h3 Y) a3 Y% @: z' ]! q8 h
3 h6 n$ @# L* z) Z* P7 }$ u |