这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。
$ k1 N ?7 p+ j1 M* H+ R, ^0 t. o% K7 o* i' E6 I, Q% W8 N
- // STM32F767IGT6: 1M flash" a$ B* d9 Y/ N8 n* y* B
- // STM32F767ZIT6: 2M flash
" ^$ T4 E- X' C: Z - #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
1 U: |# M1 B) E2 t# I$ s - #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */
0 I9 Y: v9 w$ N$ b( _ S& p - #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes *// n$ {( z- ~2 H# Q, `
- #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
* C# C" O2 c# y9 Q7 s. r - #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */$ k$ e7 f7 |' e1 Z# k2 d- k% F
- #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
7 S3 d& p+ J3 ^5 g/ k2 z4 F/ ~ - #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */: N* a) A7 A. c3 x: |# e4 l
- #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */3 [" w3 u% J6 V! W5 s4 Q8 e- A
- #ifdef STM32F767ZIT67 O, d, f+ U) v. J1 S* F( {
- #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */3 g8 O% i0 B, y) E. m. J( f1 v
- #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
; f) O8 V% Z) J% F# h+ ] - #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */* e' ]1 [$ K7 e1 e( I
- #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */8 `4 X/ v0 d5 d& I$ O
- #endif
复制代码- // 获取要擦除扇区编号+ E" l F' V- q8 k
- static uint32_t flash_sector_number(uint32_t address)
4 ^9 e t B3 W% q" [, ]5 V - {6 j( }. a! O; E. n* R3 F
- uint32_t sector = 0;
3 K7 V/ T0 B( g1 s - 5 _( y* @. y, m9 t- P* e+ U
- if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))% o+ Z$ h% L% Q1 m, g. y2 D6 f
- {: g) Y& G' L4 _! h% q7 n5 H
- sector = FLASH_SECTOR_0;
+ j, x) a, u! ~0 O+ ] - }" V% U6 k+ V5 Q# P! H, x/ q
- else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))
) k. ^- s! Y0 v$ e5 _ - {
! b7 m6 ^. d1 W2 f& d5 s: ^) l% d - sector = FLASH_SECTOR_1;
7 g: d6 Q. M; w! q8 _5 S7 x0 a - }
& @& c# ?+ k) u3 r A - else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))9 E$ o) A0 _% e1 P) k
- {
3 x$ j9 N+ m* x* c1 V - sector = FLASH_SECTOR_2;7 b! Q3 |) @3 u
- }
2 l7 Q1 q! y& X" S% \ - else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))" y' K+ w1 W" e- N7 Y
- {
& E8 t4 Q- n# x3 m3 m - sector = FLASH_SECTOR_3;
+ q+ M. F* d& u4 Q - }
9 W3 e, e# h; o5 t: i" f3 y. ^ - else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
; ]' l4 ^7 Y% F - {
( A# L# W$ H9 @7 L" j - sector = FLASH_SECTOR_4;
6 o( F" U9 w% Y9 A+ h/ M: W: i - }
1 b, T3 \# M6 A& A6 r2 a - else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))
) R2 J5 E# G8 M+ ]: n1 F8 O# Y: ? - {
; y& \6 H A4 k4 T3 e - sector = FLASH_SECTOR_5;
+ y! {7 i( v; k4 k& N - }
7 E# ^; z6 p& y( s - else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))6 ]3 Q8 c4 _! T0 j: i& a1 b% }# B
- {6 e* k' w( W. H% i3 \
- sector = FLASH_SECTOR_6;8 h/ i) ?0 U- A) x$ I7 Z$ y
- }
3 [ T; X7 {& m" l( E$ U" ~7 k7 w$ J, U - #ifdef STM32F767ZIT6
; [* _0 k6 g! T3 n J5 u - else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
: _" a0 S" t3 u4 U* @ - {1 E6 ]$ s3 T: A- p2 E
- sector = FLASH_SECTOR_7;( t- X J7 |3 H5 _
- }! C o% T* h f h0 z
- else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))
; D" ?% e8 o3 A) ^/ ?+ G& F6 W& D - {
1 u a- D, ^, o8 z1 f# O - sector = FLASH_SECTOR_8;
7 j9 k; |3 d- U: _9 M4 C! ?: a - }
8 {$ ?7 B) F) Z6 g" E8 { - else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))
4 G7 A4 f9 ?; M& S3 Q3 y, `2 O - {9 M. b/ y7 \: B5 L* j9 f% R) ]
- sector = FLASH_SECTOR_9;
. `" s+ E# M6 w9 a' G2 F - }
2 V( U. e6 L1 t8 T' y - else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
! R% s: K- x/ k. J* f6 \ - {
! C- A; q" n0 ~( I1 {& h - sector = FLASH_SECTOR_10;
" y3 X G1 K% r3 L0 U* { - }
* j3 k: v6 A) a - else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11)): D6 r# G |0 b) y- ?- w% Z
- {
3 r6 w: R' i) I# f2 V - sector = FLASH_SECTOR_11;
! o$ L6 ~) D+ D k - }9 ~4 i G& q# [1 g% ^$ s
- #else( D3 O6 U B6 b3 y
- else if(address >= ADDR_FLASH_SECTOR_7)
5 f6 V9 R7 Q2 M2 |/ U3 W - {
/ [( H) ? [4 U7 b% o - sector = FLASH_SECTOR_6;* g _0 @5 J+ q8 g. \
- }* c: C/ p9 x0 j" f
- #endif9 d6 P" z7 X( ]
- $ a9 Y& }" f2 R
- return sector;3 X i7 x2 }5 q5 v
- }1 ^) }0 a9 C5 n
" s; G+ v# T! c0 N: U- // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
, R q( V4 X5 x) h3 u9 c4 k7 u) l; A - void SocFlashErase(uint32_t addr, uint8_t count)
& r: o9 Y$ T9 y: {) r' C - {
# O/ W$ v$ K, i. l3 d# m - FLASH_EraseInitTypeDef flash_erase;" C9 V; F8 F$ q' U; @6 O
- uint32_t flash_error;7 H* |$ x. o1 l! Y
- : {3 T" Z1 B& H. f. H* K
- HAL_FLASH_Unlock();9 l, \0 k }( K' [, u) t# B
- / C3 i t& O+ T9 U6 w9 ]5 l- P
- flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; // 擦除类型,扇区擦除+ e1 d i( X/ K d
- flash_erase.Sector = flash_sector_number(addr); // 要擦除的扇区
Z! p4 m g# |8 O& s4 Y* t - flash_erase.NbSectors = 1; // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
, w% i5 a1 R5 K ]+ M - flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!& g7 o0 g% @% K9 o
* ^# l* _- h. Z( v- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
; J( W1 Z7 o* j3 R2 X3 Y - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);! D" g8 y- `8 V
# W s) t' P8 t0 Z- HAL_FLASHEx_Erase(&flash_erase, &flash_error);
2 k0 U0 z- Q& N8 Y5 u e - 1 R; z5 ~' s4 _7 a/ N5 f
- FLASH_WaitForLastOperation(50000);
0 x9 V' y8 d2 N5 B5 l - * @5 @$ D2 r$ F' K
- HAL_FLASH_Lock();
9 l3 G. _" S; U, u0 } - }4 `, d6 B, Q+ M6 g0 }+ _+ ]1 Q$ o; n% v
- F; v$ j; y4 G- uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)2 L1 Y) K/ M! i0 L
- {$ k1 g- ~8 X( s/ Q' A6 u, G" u9 o
- uint32_t i;
7 j( }3 z* f* ^7 M, X$ \# e/ |3 \ - uint16_t data = 0;
3 k% p1 E$ F$ d, t; M- W - ' t: W/ X; S: k9 ^1 f* Z
- if (length == 0)
. G3 O2 ]" o1 J* S- j8 w9 E - {
y6 p; P- G+ k - return 0;
& ^- G6 z9 a/ m+ O- D0 p# N - }* U+ e2 x$ g( v0 e0 z+ f
J- \ O' u4 a- HAL_FLASH_Unlock();1 L& d' R t9 O8 j! F4 D
( \/ S( S) ~ |5 L) h- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |" H2 F- X6 {1 b; {
- FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);# l) P2 H& ^7 G
- 2 o; w' ?3 P1 B& t/ w
- // 按半字编程
: V! b% B' n8 l# V, \) x7 M - for (i = 0; i < length; i += 2)
! g# n& ]' r" T4 i6 F' x - {8 b6 c" i* r$ r3 V8 L5 ~9 S( X7 D
- data = (*(buffer + i + 1) << 8) + (*(buffer + i));3 |7 `0 R- L5 s! }& J2 q
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);
" r$ ]! T# M3 X7 ]0 L - }
6 e+ l/ t5 e! x) d8 ? d4 x$ e' k1 q
6 [9 t' f- u) H- HAL_FLASH_Lock();6 Q% w# x! B( {. u
- + J" ? G% V0 f! J
- return 0;
" h) o- H5 ], t/ t - }! B6 K1 _' }2 F0 \ H; o5 i
- 6 J# x1 b" l. J4 Q
- uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)5 F3 q1 T$ b0 N" E0 p% G/ K
- {" q& v) @' z6 K, w/ O
- memcpy(buffer, (void *)addr, length);
; G# o6 F1 S# K9 \$ }
% ^- a* M. s/ ^" F" N) J2 J' O- return length;
/ T2 `0 a; B9 H- n1 U% t1 N& u - }
f4 Q! \3 L& C r) m: Y3 f' R
2 v9 T/ J& k8 t |; \- v
复制代码
+ q* j; X$ ` p5 ]5 q j
5 @5 X7 m" F1 L3 w. Y6 q |