读写FLASH0 g* K: G. W" N
1. 简述
- [) X3 \/ s: N9 e. p& \" H0 f1 fSTM32的写FLASH相对简单,直接读即可,写FLASH相对复杂。首先看STM32的内存大小和分配。
5 g; |+ g; ]: y3 H
2 S$ s# y$ j6 o. S- ]. A用到的HAL库函数:
7 s, e1 ~1 [9 |$ }1 Z- G- HAL_StatusTypeDef HAL_FLASH_Unlock(void);
9 {" o1 E* A1 ? - HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);
/ Q. Z9 L# Z3 ^0 X* [" ^& o8 Y - HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
1 g1 w! o$ C$ U9 h1 i9 {; w* E1 _9 L - HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);$ {7 I7 I* b/ l& \& D
- HAL_StatusTypeDef HAL_FLASH_Lock(void);
1 T- _$ Q" c8 y5 q5 `
复制代码
4 n/ T1 b) ~: v5 }, {% Z: V9 a2. 读写FLASH代码- #define STM32_FLASH_BASE 0x08000000
. h( _( H+ Z) a8 E- s& ^* q" S* [/ L - . |1 C* t# W; \5 ]: Y8 H( ^' W
- /* 获取扇区号 */; l; r E% e" o6 g
- static uint8_t bsp_flash_get_sector(uint32_t addr)( S$ ^* q! M, Y3 [& P- W
- {) P' S7 [) v+ M
- if (addr < ADDR_FLASH_SECTOR_1) return FLASH_SECTOR_0;
" q( S- s( {" i# L7 x# G2 q6 p% w - else if (addr < ADDR_FLASH_SECTOR_2) return FLASH_SECTOR_1;3 {7 i- Z) M$ a3 ?& t& j0 T$ o5 ^; o
- else if (addr < ADDR_FLASH_SECTOR_3) return FLASH_SECTOR_2;
/ d% }% Q! n& A# U' Y% b - else if (addr < ADDR_FLASH_SECTOR_4) return FLASH_SECTOR_3;- f9 k& E- k7 Y1 c& a4 y# o
- else if (addr < ADDR_FLASH_SECTOR_5) return FLASH_SECTOR_4;
0 Z; H3 w3 y1 x. `1 N - else if (addr < ADDR_FLASH_SECTOR_6) return FLASH_SECTOR_5;+ Y" B/ Z/ |: \$ \4 z2 y% ^* Y
- else if (addr < ADDR_FLASH_SECTOR_7) return FLASH_SECTOR_6;
+ J9 K# Y3 H0 |9 _ - else if (addr < ADDR_FLASH_SECTOR_8) return FLASH_SECTOR_7;( g7 A5 ]$ B" Q+ f
- else if (addr < ADDR_FLASH_SECTOR_9) return FLASH_SECTOR_8;
# B5 c8 @3 `9 e- u4 B4 D3 f: @ - else if (addr < ADDR_FLASH_SECTOR_10) return FLASH_SECTOR_9;' T7 h" U, `) a& c$ d% e# B
- else if (addr < ADDR_FLASH_SECTOR_11) return FLASH_SECTOR_10;
- x; j# s% d" D7 f0 d - return FLASH_SECTOR_11; ( c0 F. P$ C) V, ~- l X" f' L
- }
# v1 R( \7 w0 U - 1 r7 ^0 K) m& g' p6 K* B3 f7 K% @5 k; Z
- /* 读FLASH */9 u7 n" G8 Y: C
- uint32_t bsp_flash_read(uint32_t addr)+ Y) J3 n* d; r' C# c
- {1 M( w! p& d8 E o6 Q a
- return *(__IO uint32_t*)(addr);
& g( Q; V6 C I# u) v, C* I9 d - }
+ a3 n i# E, I8 \: S
) l; U3 v' L* t, [: r% e( N- /* 写FLASH */& ~3 s! P( B: S/ n% @* R, m
- void bsp_flash_write(uint32_t addr)
7 x8 s% y* D3 C2 R; {) [4 h4 t# S - {8 e- `* Y$ q: z/ B- V' m' ]( J
- FLASH_EraseInitTypeDef f;, N) u/ h, z" m+ x# B
- uint32_t sector_error=0;
8 `: k# r6 i" i/ J2 B" u6 G( Z - uint32_t start_addr = addr;
/ e- x \, z7 I+ Q - uint32_t end_addr = start_addr + (size * 4);4 h/ f* j. k: g/ ~, P1 A6 w( e
-
+ n. O- n% A+ d - /* 1. 判断地址合法 */' Y0 k [7 m8 b$ v* I( E
- if ((start_addr < STM32_FLASH_BASE) || (addr % 4)) return;/ ^& \6 k' h0 s( G9 L* w
- 0 G0 e+ t* q y/ z
- /* 2. 解锁 */
% ^& t' Z( \# Q. r( G+ j. H - HAL_FLASH_Unlock(); ' G+ H5 L9 K0 u* X
- 1 H2 e6 R4 w) ]) g% a2 J
- /* 3. 擦除 */+ T# N" q5 R N- O+ H) W; |
- if (addr < 0x1FFF0000) - E' G' P; P4 X; K6 C2 z+ b
- {4 n. s5 n: Q; }0 f$ A& a! s& D0 D
- while (addr < end_addr) , T5 m* Y7 Y4 S5 y3 {+ b1 Y
- {
7 w. |9 u! h# h% K% k1 M1 m$ }; V - if (hal_flash_read(addr) != 0XFFFFFFFF)
8 R1 A% M* l2 t9 { - {
4 Y8 Z/ L2 k" G$ i# o3 ] - f.TypeErase = FLASH_TYPEERASE_SECTORS;1 A" \+ y) _3 U; Z3 L
- f.Sector = hal_flash_get_sector(addr);
' Z. A- o2 R! f+ M) D" B - f.NbSectors = 1;$ T" k' X6 H4 x8 z3 f, |
- f.VoltageRange = FLASH_VOLTAGE_RANGE_3;5 q2 R* S* N6 {" C
- if (HAL_FLASHEx_Erase(&f, §or_error)!=HAL_OK) break;5 M- o7 w4 w- N8 t
- }
, T$ Y3 ?0 w7 d4 m8 A - else addr += 4; 9 v# g1 B1 J+ Y0 D
- FLASH_WaitForLastOperation(50000);* @3 w+ _! I" K& m2 ~( o
- }! U& F' E$ x* N0 i
- }
3 C' h/ d, l# Z9 f& Z$ g -
4 x9 A" u7 a9 u3 [2 s) F$ U% i - /* 4. 写入 */9 n% w, f+ e" X: U; h# l2 ]. `
- addr = start_addr;) g% I$ V% [# u& Y, i
- while (addr < end_addr) / D6 a+ t5 x2 p4 J" F) e+ B! o
- {
. ^8 G6 A7 f/ c4 u" h - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *data) != HAL_OK) break; ; }8 J% l9 X0 h
- addr += 4;
% T# {- h6 {% Y1 P/ E/ O. O, `% \ - data++;, M; k' Q5 ~: O2 c) [8 g
- }/ `3 n ]* j9 Q$ d* {. r
-
+ Y7 x) l$ I- H4 o) i) f; s - /* 5. 上锁 */$ C5 {$ H" |+ U3 V) X, t
- HAL_FLASH_Lock(); $ v6 l S5 X5 f: v+ N8 I! y
- }
复制代码 : a' Z+ z% U3 ^4 C4 g
————————————————* A& m' E: w: h0 e+ u2 m
版权声明:lljwork2021) s( L: G4 u+ b/ \% {- P! s4 `* w
. x0 N9 |8 ^& g6 s" a0 J
9 ?9 a& [9 V/ A3 j- }( o- u
1 k! n. A" X( J9 F- g
|