这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。7 C( O/ ~/ t- J9 ]/ Q! g% R" d
! w! l' a) q& \( J+ g! k
- // STM32F767IGT6: 1M flash: p: W7 l5 \7 y, s6 I
- // STM32F767ZIT6: 2M flash& y' A; {- U- h$ _ `
- #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
) J+ p1 Z5 W$ ]# d- n5 p - #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */4 y _4 R) s8 K1 g
- #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */% h# t- d, V0 ~3 y' H7 N/ W3 s
- #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
, B' v+ i% h: v8 s5 _9 n - #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */: _( v( `& D/ A+ L, _" `
- #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes *// k+ y0 ^2 A8 f2 F* Q9 n- \( X
- #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */( e F5 d/ C, a6 f0 x6 c; a+ K
- #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */, B! Y; g P3 s4 p
- #ifdef STM32F767ZIT6+ C+ W9 M) K4 L& ]
- #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
) U' t1 I. v4 d! o+ [6 M - #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
/ H( R4 y# Y0 d - #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */$ ^1 c* C1 i; e% [& i
- #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */; L: N$ j: s+ T+ e" p# |" }/ d
- #endif
复制代码- // 获取要擦除扇区编号
8 Q8 A5 G" [7 T* G - static uint32_t flash_sector_number(uint32_t address)
- b3 }4 j7 Q- K - {
r, z$ ?$ D% W( j5 {) X! G" g: F - uint32_t sector = 0;
2 j: p- U) k; {" t
! @/ m3 a$ z) M" `" |: y0 e) v- c- if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))
R' H1 A3 |9 P( V3 `0 Y - {0 t6 @6 }9 }& `$ v( v. X
- sector = FLASH_SECTOR_0;3 B. M3 G8 O4 X( [" r. X
- }) Z2 }. i |& o4 e r) @) p
- else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))4 x. `7 \' {/ L; h9 j8 X2 C
- {" h" A1 K2 ] }: l- O
- sector = FLASH_SECTOR_1;
8 `4 ], [5 L0 J! S n! W! a4 g1 w4 } - }
0 B4 A( B8 _# {; ]4 Y/ u) ?. \3 W - else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))+ N7 t# J3 O6 [
- {3 h" y3 z" W6 f% I% V
- sector = FLASH_SECTOR_2;7 p, }. }$ B. e+ D, d
- }4 \; q8 X. I0 o3 ~8 P! J# C5 ~% w/ {
- else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))9 Q. I4 @$ a2 f6 n2 q$ M* N1 ?3 e
- {: U, c& I* }0 P3 X. b' m
- sector = FLASH_SECTOR_3;7 V% \6 h0 b, [# ^
- }- M2 I, Z# p3 n! A4 y
- else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
7 z8 Z' l. b: ^ - {
# N" C1 L: I u. Q; q; x) r. _ - sector = FLASH_SECTOR_4;
O \9 } b6 ? - } R1 l# E) v/ w) I: k" l2 @
- else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))4 I6 z) {, ?2 X9 n- o2 H- k u8 S
- {
2 B4 S; M$ L4 ]# E1 W4 ?: z - sector = FLASH_SECTOR_5;
5 o' P i) }- W* u# G - }
$ s# l, ?+ M6 i9 _ - else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))! D8 r! h2 b C- D4 ?. f
- {2 c4 i+ e/ b+ I" M6 F3 R+ S7 l
- sector = FLASH_SECTOR_6;0 ~5 ], r x( a. t7 X7 J
- }
! v5 }: a5 R8 Q& A/ i. B4 U' r) N6 h, t - #ifdef STM32F767ZIT66 Y$ B- s( Q$ a6 [
- else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
# T6 Z* g1 k" U7 u$ }* t3 K - {. f2 w+ Y0 q! y/ y
- sector = FLASH_SECTOR_7;
8 }* F4 n1 c# _8 y! Y - }
8 D) U3 _6 U1 U& J' T% J - else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))+ u1 N# D6 I* `9 F) k
- {
1 p1 g0 ?2 d8 L1 ~' x# G - sector = FLASH_SECTOR_8;
T7 Z7 ~" T7 d - }5 `3 X- f# @2 ~6 z# \+ H, m
- else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))! v+ o; x- R+ @% i
- {
/ j9 B! l. n& A3 v* B - sector = FLASH_SECTOR_9;
9 l6 F- i9 O% L" C - }
! F3 b- [, {; C0 u - else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))) `# z0 u+ s) e; N1 t
- {0 L E4 n% T0 {# c( v Q0 R2 v
- sector = FLASH_SECTOR_10;+ l3 d7 ]0 U/ k4 C3 }( ?% ]9 r8 \# E
- }2 H2 h) a* t3 h
- else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))9 E4 W$ w% x9 Y. f$ L: T+ Y1 H, B
- {8 y, J) n$ a2 b+ B3 Q# o4 _
- sector = FLASH_SECTOR_11;0 h+ f) k& n+ n! H
- }
6 G4 r* A6 O6 L6 D2 I: ?. `1 G( G' q - #else; M9 K) K/ A2 S# [
- else if(address >= ADDR_FLASH_SECTOR_7)+ w/ S) b. E5 G1 ~
- {( ^6 L8 G3 q4 J$ |
- sector = FLASH_SECTOR_6;0 V5 J9 A# e: Y: q! ?( j, U- S+ q
- }+ g2 k, Y" E# g$ H7 [$ O
- #endif; z9 x0 L2 P2 p. @: L: k
- 9 G. V, K R e# \$ X( I3 J- @: i
- return sector;8 ~: n: }, {6 |3 p# y$ s
- }
% ?0 P% o: P* D. ?' c8 Y& x) q h8 r - 2 P3 \: ?. Z) F1 {
- // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
# P& X( h ~& X3 K% q n ~' ? - void SocFlashErase(uint32_t addr, uint8_t count)
4 A' t% Y/ ?7 v& p& r% P# G, F - {, c- u# U9 j3 f6 T! D, M2 {
- FLASH_EraseInitTypeDef flash_erase;
& S! m( E* }* g5 X9 }8 h5 } - uint32_t flash_error;
- @ ]; y/ G ^) f$ I, | - , n" H, a6 @! V; P6 V/ a1 \3 V! h- ~
- HAL_FLASH_Unlock();1 j8 o# o6 O* n5 w- f9 q8 O
0 e! [! y& g( s% [) o- flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; // 擦除类型,扇区擦除1 _/ Z: n3 t- T9 G, U
- flash_erase.Sector = flash_sector_number(addr); // 要擦除的扇区
! F5 {, D c9 N1 `! _, e - flash_erase.NbSectors = 1; // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成18 v: t! }# L4 R: [
- flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!
* ^$ R/ K* A+ m/ q7 f% L7 D
6 K1 t/ v6 B) M- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
& I3 }, l- h' S1 [6 U2 S - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);; D; x- Z2 h6 n' E0 r7 \( O
- |4 y" b( h) ~- ?. P2 e- HAL_FLASHEx_Erase(&flash_erase, &flash_error);
1 o8 @ e' z6 T6 w- ]6 P
& J }' A% q; m# J- FLASH_WaitForLastOperation(50000);
7 A7 Z# z: E% r1 Y' \# f - $ o3 s+ l8 h( D' L2 ?6 m9 a
- HAL_FLASH_Lock();$ \ r" p' L7 t" P1 y9 @
- }+ x7 I1 E u* ^3 Z* W7 k
- ) e$ }2 E& D/ a. q; {2 i
- uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)+ a6 b2 r$ [/ s4 L. v
- {
' z! ?# S3 Q# T; O, i - uint32_t i;
! T$ G) o/ I/ R. u - uint16_t data = 0;
; i( Z; E3 \- m; W8 D - : }$ o* k7 a, h+ `9 ]1 p
- if (length == 0)0 S8 N* R" D v# } Z
- {8 X2 ^3 d: w- C l D0 d
- return 0;! z$ l2 L: A* {6 D9 J! ?1 I: r
- }, ]; K/ V- `. z
- f/ p% x# u/ |- HAL_FLASH_Unlock();
/ N9 V0 q5 k8 Q$ r; j - ; B" P y; x( @( K" d; y! u* p
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |4 w: r% u: G9 C; [2 Z* p
- FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);0 ]- y" ]9 t3 N6 v# M; e. @
- - p- |. m) E) s3 o! g% R
- // 按半字编程
* A/ U7 G5 F; S - for (i = 0; i < length; i += 2): K; g! T: Z, h+ t( B) [! J
- {+ h4 t! C( R: I' b+ i
- data = (*(buffer + i + 1) << 8) + (*(buffer + i));
2 Z4 U5 i! P1 V" {+ O - HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);$ J- ~5 F, i# l0 |7 j# \5 q
- }" C) Z p" N& z- i1 Z0 o" K) t B& r
4 t) O+ k* }7 p9 X3 i1 F7 Q+ _- HAL_FLASH_Lock();
9 L" u1 Q5 A2 f1 ?0 z3 k
6 j- h( y9 v$ k. G9 d- return 0;) G+ n! \6 E6 e3 A' r' B4 k6 v3 N8 F
- }0 }+ O# r; \9 I; `
+ Y2 o, ^: G/ Y @, Z2 J' h5 @ y- uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
, g6 m1 p/ M' R A5 w - {
1 p- p* O. q9 \/ o6 g4 O - memcpy(buffer, (void *)addr, length);
2 ~/ y' M9 w4 i, i" E: G - + K: K7 T# S3 J1 n
- return length;
2 M% q5 _% {( A8 K - }
: r0 r. N# C. \3 T& g; a6 _7 M3 D
' W" k) K. \5 E! j; w* [
复制代码 7 e7 G3 i' F- T# H* G2 q) {7 f2 y1 q9 q
4 u& [3 w0 P$ Y: W; f
|