wvyg3jmqsxc64042477602.png
6 \: _* c# O+ h, R2 v& ]/ [, S. m* s, y1 L
一,GD32的flash特征
' k! j( j, D+ J' F1、在flash的前256K字节空间内,CPU执行指令零等待;在此范围外,CPU读取指令存在较长延时;
{, J1 Q3 J- U2、对于flash大于512KB(不包括等于512KB)的GD32F10x_CL和GD32F10x_XD,使用了两片闪存;前512KB容量在第一片闪存(bank0)中,后续的容量在第二片闪存(bank1)中;
# l' c6 A# Y% n! `) V% h& ?0 U3、对于flash容量小于等于512KB的GD32F10x_CL和GD32F10x_HD,只使用了bank0;% j8 x0 S L( z2 o0 u$ Y, G& t
4、对 于 GD32F10x_MD , 闪 存 页 大 小 为 1KB 。GD32F10x_CL 和 GD32F10x_HD ,GD32F10x_XD,bank0的闪存页大小为2KB,bank1的闪存页大小为4KB;
2 f! r' n* e8 E5、支持32位整字或16位半字编程,页擦除和整片擦除操作;
5 Y# y1 \! z( }8 m0 Z9 p5 {' P0 v0 Z4 A4 U: ]
二,GD32的flash结构/ n) a, G# E. K" K' C
1、GD32F10x_MD% A7 h) V+ A, t. z
e1gvnses2tn64042477702.png
, ^/ l, g% `3 Z/ u, K5 \* p/ M
5 }8 m' ?( V1 P5 J3 Z
GD32F10x_CL,GD32F10x_HD 和 GD32F10x_XD2 U2 k! z _& }& S! f1 ]
c5mhntthw0t64042477802.png
# W; y5 C# ^- e4 Z/ r- V
( ~$ ?: W O1 Z- r# c三,GD32的flash读操作8 a+ Y4 ]) o8 g7 A- K
flash可以像普通存储空间一样直接寻址访问。
; p: q3 ?( J* A- `0 I2 }; |value=*(uint32_t*)FlashAddr;uint16_t IAP_ReadFlag(void){ return *(volatile uint16_t*)(FLASH_ADDR); }# m1 V1 W8 Z: U$ Y) B" A+ P
四,GD32的flash擦除操作$ E" q" M6 t. z' X* j$ K6 P+ |
每一页可以被独立擦除,步骤如下:: {. G+ F% x6 V5 i% O3 d* K& v: n
1,确保FMC_CTLx寄存器不处于锁定状态;
9 G3 ^4 G% F- Z0 Y ]2,检查FMC_STATx寄存器的BUSY位来判定闪存是否正处于擦写访问状态,若BUSY位为1,则需等待该操作结束,BUSY位变为0;
6 o9 b7 j( N& f, E2 P3 T3,置位FMC_CTLx寄存器的PER位;6 Y" U; S# V; G: h: i
4,将待擦除页的绝对地址(0x08XX XXXX)写到FMC_ADDRx寄存器;
" T8 w- ^7 l- ?( _- g3 r5 s5,通过将FMC_CTLx寄存器的START位置1来发送页擦除命令到FMC;% I3 P1 @& I( ~' P4 Q e* Y3 w
6,等待擦除指令执行完毕,FMC_STATx寄存器的BUSY位清0;$ y- X- m0 w. r1 V9 M- {4 o/ [' H# u- X
7,如果需要,使用DBUS读并验证该页是否擦除成功。
" ]9 z5 e: {5 q, |void fmc_erase_page(uint32_t Page_Address){ fmc_unlock(); //fmc解锁 /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR);/ D, ?3 i0 n) G; d8 R
/* erase the flash pages */ fmc_page_erase(Page_Address);8 u$ y- W0 q) C. f7 _9 h
/* clear all pending flags */ fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR);2 @! V- X! t' e# H% H2 E
fmc_lock(); //fmc上锁}* w/ ~4 N# `' Z6 D0 d% C8 W# G7 d
要擦除连续的几页:
4 w' b: F' B; J1 F% R* M9 Dvoid fmc_erase_pages(void){ uint32_t erase_counter;. S% D! R& I2 D8 B6 D; h1 \
/* unlock the flash program/erase controller */ fmc_unlock(); /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
! M3 x' D3 D6 B /* erase the flash pages */ for(erase_counter = 0; erase_counter fmc_page_erase(FMC_WRITE_START_ADDR + (FMC_PAGE_SIZE * erase_counter)); fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); }. V( S) d& g3 |1 M* t
/* lock the main FMC after the erase operation */ fmc_lock();}
0 Z4 ^. y4 |$ O. f2 ?全部擦除:0 a" C V: d7 e" @; i# U
void fmc_erase_page(uint32_t Page_Address){ fmc_unlock(); //fmc解锁 /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
) v" x* f; [9 y! j5 p; @- C /* erase whole chip */ fmc_mass_erase();! J. Y9 B, H3 M4 O4 Y3 n5 A8 I
/* clear all pending flags */ fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR);3 \5 y' d! y4 s% R& [8 l1 d" E
fmc_lock(); //fmc上锁}- c7 Z+ _1 D4 u2 S" i
五,flash写
}, `; ?# |# g3 P) _$ _8 l! w' |" y4 T往flash的某个地址写入数据前,一般要先擦除该地址。
/ p, N$ k/ i6 G$ R' R3 w+ k. h+ B/ H0 d' X( Y8 f
16位半字编程:' W4 u5 w. A1 E* s; S# b
void IAP_WriteFlag(uint16_t flag){ fmc_unlock(); fmc_page_erase(IAP_FLAG_ADDR); fmc_halfword_program(IAP_FLAG_ADDR,flag); fmc_lock();}
3 |9 ?' C% m4 l, F+ s8 d2 S( y32位整字编程:
! U3 K" e. a4 Z3 e/ y$ J1 Uvoid fmc_program(void){ /* unlock the flash program/erase controller */ fmc_unlock(); l: h7 Q/ x8 p: m# N
address = FMC_WRITE_START_ADDR; /* program flash */ while(address fmc_word_program(address, data0); address += 4; fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); } /* lock the main FMC after the program operation */ fmc_lock();}- u v$ x+ s% q8 {. f4 a
==========
8 L/ D" t% f6 o9 Y% ?$ r- y往期回顾:第十五届蓝桥杯电子赛知识点大纲
+ s) d7 R9 D, SSTM32单片机实现固件在线升级(IAP)
+ z( O) Z6 w: @+ `4 Q【蓝桥杯更新通知】
6 m8 ^$ Y- Z5 B& s8 r* OMODBUS通讯之数据帧格式解读* ?8 o" ~% q3 c9 l- c$ a9 u
物联网LWIP之socket编程) l/ ~) P* N$ Y$ r: P
==========作者:ql君
6 c4 x4 a# |" P" E! S1 q: |- ^2 J6 |链接:点击阅读原文; E Y; ?5 d! g( `' L& d, K; J G
j0 z$ b4 E6 t7 I z
530pa1o4zv464042477902.png
" b2 F# M3 w& ]0 i0 L2 ]( |: N' k4 ?4 U( e; x: N
jcvk245divx64042478002.png
8 k/ T; n6 D2 U5 H, @1 z& ]8 j$ s: A3 R* h
g24upbtlfk564042478103.png
|