|
STM32G0B1CCT6是相对比较新的MCU,属于G系列,不支持标准库,所以下文用的是hal库或者ll库。
/ ^/ @7 i. e' U0 E) @, o6 { B* h' _* o8 a; W# K! y
首先STM32G0B1CCT6是有256kflash的,每页2k,而规格书里面只提到0-63page,相当于128kflash。$ j) P7 S- ?& X, @
对于后128k的flash其实需要切换bank2才能使用。' D, H8 z. p/ r/ @) r I" e
下图为STM32G0B1CCT6的flash构成
4 D6 r" k! T a) L% P1 S
5 |) s8 d# u( E+ _0 o5 [& `8 A- r" l+ `
然后我们先看正常如果要擦除第一页的代码 B* L# S9 B4 n+ Q
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
4 a* N/ C( H0 i) M4 M! J - uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址; `+ y1 i& o& B$ ~+ x
+ g) P2 r% e% s$ l y- HAL_FLASH_Unlock();
L5 H; L2 R( `. B
( g+ h. X: v" H, F; z) U- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作% M; F+ _0 V- `" L4 o; @" _
- My_Flash.Page = 0; //声明要擦除的页" k8 X; |0 |. n6 C* {
- My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值 n3 W2 h2 H6 s) r/ w
- My_Flash.Banks = FLASH_BANK_1;
" R4 f4 M( c% i5 o7 K
1 G4 L3 @, c6 N% y% |! ]- //调用擦除函数
9 Y- Q' B2 S4 P - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)
2 v% S) a# {, p8 y( n& W/ H - {
1 J$ a% p5 ~+ X2 ?- k- a - //3、对FLASH烧写 t" s7 m* ^& L! t3 D8 @
- //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
/ N2 d3 u* P, p% E4 o. g1 c ] - }
. Q$ ~& [! t' R0 @$ p' G - //4、锁住FLASH+ f& B( C: Y N' l7 l5 u
- HAL_FLASH_Lock();
复制代码
1 s) R0 w) b" D$ _7 R$ n: m+ \当我们要擦除后128k的第一页的时候,即第64页时,需要把FLASH_BANK_1切换到FLASH_BANK_2
8 a) h/ [: b S6 \( h+ G不能直接在FLASH_BANK_1声明擦除第64页,切换到FLASH_BANK_2后,相应的页数为总页数减64页。, ^/ E ^# A- C& H& c7 i
- FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash( W7 L5 M1 D" a7 g3 \5 G$ C- z
- uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址, C, n, d& _: c" k! r
" h4 _( W# q; @7 D- HAL_FLASH_Unlock();& f9 a+ d. k% F0 K
8 A$ z* ` x+ _$ Z8 a; v0 N! o h- My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作3 s) k+ {2 A' M: L2 y' T, u2 k( d2 Z
- My_Flash.Page = 0; //声明要擦除的页; O$ G6 H+ H$ m# s
- My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
8 Z" D6 `* P8 `% o4 _+ y8 a& a# U - My_Flash.Banks = FLASH_BANK_2;
, v+ Q; W; H" q- M4 g% K - 2 j" ]' b6 Z7 q: V4 l: E
- //调用擦除函数
0 W6 d6 f; d' ?, c+ S- n0 @ - if(HAL_FLASHEx_Erase(&My_Flash, &PageError) == HAL_OK)
2 H& G. t# K1 G - {
0 c, n0 ]- l2 |2 N& I2 F - //3、对FLASH烧写
! }5 e* T$ z, D3 g - //MEM_WRITE(FLASH_SYSTEM_DATA_ADDR, buf, 5);
& v/ Y, O# I. ?1 ]7 ~/ P9 ? - }
1 k7 B! H( S+ l! D1 H - //4、锁住FLASH
. k0 V" L6 O# [$ H8 l - HAL_FLASH_Lock();
复制代码 3 l; I* f$ b! j+ L/ m6 ^& }
) a+ v( [ ]' U" [最后再附上一个ST-programmer和iar的一个小bug。我将这些问题均已反馈到原厂了。$ _4 a9 t, a$ |6 U; V4 U
1、如果ST-programmer要单独擦除后128k是擦除失败的,因为软件本身没有切换bank2
4 c& [. i+ _& H9 H) t$ H6 ~2、IAR烧录时该次使用到了后128k,则也是擦除失败导致烧录失败。第一次烧录成功,但是从第二次开始需要擦除到相应flash时,擦除失败就无法下载了(keil应该也是一样)
# q& g1 f, ?* B8 n" l
$ o. g t1 n Q4 v' T0 ~0 C$ l% x7 \( M: @
5 j3 |: W X6 Q5 D1 i {, z& X |