这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。* _4 N' F6 \) {3 V4 J2 p1 M
0 p- k' F v* A5 g6 ?# \- // STM32F767IGT6: 1M flash
. s' W1 b+ } ?- o2 A - // STM32F767ZIT6: 2M flash: t9 Q! v1 V" E; Q% ]
- #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
( |/ c a5 E$ Y9 I - #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes *// }$ ` U$ j) c9 ?& n6 \5 {
- #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */
/ C9 y3 r0 H/ F - #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
* c6 _: Q" ~% S/ {# m4 R, E4 v- m - #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */' }9 l4 K3 f% ]' z! `0 C
- #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */1 |% i3 Q2 R3 A' }& F# Q, N
- #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */
3 |" J' }: m1 m: x9 X0 Y - #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */
- t* r. F3 d# @2 r - #ifdef STM32F767ZIT6
1 R5 L5 c9 }1 B4 z% J - #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */5 Q8 M; @- o! ^, E/ }
- #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
4 C" e' e6 C, @ B* G: j - #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */
* E9 ?, z( J( B, S - #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */, [0 z9 O& p4 f+ K/ j
- #endif
复制代码- // 获取要擦除扇区编号4 k% E5 e5 H' |# F* E1 S% H
- static uint32_t flash_sector_number(uint32_t address)1 L2 p$ T+ S- c5 }' p1 p0 }
- {; \" v. a# n8 s# ]6 s
- uint32_t sector = 0;
o5 q. U. y6 O. r) r0 f
9 W" o8 |6 I7 V' K' Y1 O- if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))5 z0 }2 p, a% r! m% y+ M
- {
3 D9 g% y9 v/ }8 s% s# J$ T( a - sector = FLASH_SECTOR_0;
! O0 \5 a' z) B/ c& r1 M0 P - }
* @- n$ a, [# b9 _+ F. D8 F - else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))
6 R- r, } o0 C0 w - {
! \$ ]; o( `6 ?2 e - sector = FLASH_SECTOR_1;# c* @1 c. s; P0 F7 g7 m0 e
- }
/ q1 F% @; `' _' T/ ? - else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))$ [! P$ o+ j/ i* w3 U# O9 b, g
- {
7 ^: b2 a0 k9 Q4 o - sector = FLASH_SECTOR_2;' c. N8 h' {- {+ S! t( L
- }
- J( R5 @* V C; ]7 X - else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))
% n& ^( \9 o5 z - {& x5 ` x' c* O4 d: S+ ~+ V
- sector = FLASH_SECTOR_3;* c. |6 y/ V+ K) {& E4 }
- }# y Z8 G. Y8 j; c+ U$ Y3 W/ Z8 R! F6 L
- else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))$ r' Z: r% ~- R. A0 C- C- g H
- {
3 D9 h. U" t# M - sector = FLASH_SECTOR_4;
$ ]! s. @4 \1 o' O) x9 @ m5 j - }4 C! x/ p, a+ b( z( i7 I* I, P9 L
- else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5)) D* x* y; m9 E$ e
- {' Y; J z$ W S* K+ c
- sector = FLASH_SECTOR_5; r6 V9 N' P0 F( j! X
- }% p0 ^) o4 `: A
- else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))
3 p }0 e: X. {1 \1 P - {" _$ H- ?* }, l$ ]. G( R1 m
- sector = FLASH_SECTOR_6;0 b! O+ d+ s9 S5 U$ Y, Y
- }
" z1 Z- E/ o7 F, S1 y# _9 c - #ifdef STM32F767ZIT6
- {$ F3 H9 e6 a% X - else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))3 {( f& ]$ ?7 U
- {, c6 m4 i _" {! ~9 c. O. a
- sector = FLASH_SECTOR_7;- N" `9 l: q4 U) G- a0 A
- }; r% v: `/ J+ }
- else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))5 u2 j1 @. C8 n& g
- {) n _5 ~3 {5 ~& x
- sector = FLASH_SECTOR_8;
. @; j$ O8 o7 y! ^. } - }3 r6 R a+ @& t2 X$ x
- else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))0 L6 E, C5 T, ]* G. s
- {7 e9 U1 H2 z a, F+ h
- sector = FLASH_SECTOR_9;' g- b5 i. H5 e0 O& R$ ]( k- M
- }
! d; t6 m5 ]; z% v - else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
; y- K; Y8 Y; e - {5 o0 E2 v R; z0 O
- sector = FLASH_SECTOR_10;( `4 W6 q8 j6 t/ i# c9 }' u3 x
- }
8 E' R3 ?7 Z/ o: P5 @4 x$ a - else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))
( [% x- _# t; D+ e% t# |7 X - {
& Z8 H6 |# F$ `. r+ H7 C. G - sector = FLASH_SECTOR_11;1 C: S6 l% p2 i* ?2 D- t! `
- }7 {: X; m* `" I9 b( ~" x& C0 b
- #else
4 s1 X# y; d l2 c$ J, T - else if(address >= ADDR_FLASH_SECTOR_7)2 D5 x) r' N* ^ b' \
- {5 Z& V% u9 N# j2 V# }6 c
- sector = FLASH_SECTOR_6;
. f+ W9 o; L& I& {" e5 F- t4 T - }
. F8 w K# Y& T. R8 \% l/ B - #endif
2 A1 {9 P7 N$ P, R9 c; e - : l4 q- U1 d; Q4 Q9 |/ {, L
- return sector;1 x6 m% P2 O$ u0 s& P# m8 [. C& s
- }3 b( h9 `; z5 `* b/ L
7 b5 i' S( P% k) M- // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。8 x% M6 A! m ~* ?9 P
- void SocFlashErase(uint32_t addr, uint8_t count)5 R9 v/ V& D7 D
- {
/ \+ u) g* w% y - FLASH_EraseInitTypeDef flash_erase;
$ J/ t9 S- q* e i4 t - uint32_t flash_error;! I8 J% |$ x$ i9 E& g: G
- ' s" ]& z$ {: w. H: n) k
- HAL_FLASH_Unlock();
$ u) f( \+ |. n6 J6 @: p0 P
9 j; _( m7 b: P- flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; // 擦除类型,扇区擦除
# H* o# S; U1 J- R: k - flash_erase.Sector = flash_sector_number(addr); // 要擦除的扇区
; ~: d9 u, L, y5 `+ V - flash_erase.NbSectors = 1; // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
& J; I7 n& C5 ]0 ~/ a - flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!
. b7 a4 S% |: D! ^6 }% X1 Y
+ E/ z9 \& r- P3 s1 |, N; T3 B' H& U6 E# {- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |+ B. b y% Z' a$ _$ I
- FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);( ]" f" \0 N& [
9 }( n) m: l( B8 }. {- HAL_FLASHEx_Erase(&flash_erase, &flash_error);7 }4 k6 F0 A/ U+ k2 w' M) R% y* l; D
4 K( z; Q! ]. H. v! {0 ~- FLASH_WaitForLastOperation(50000);0 G, m; f5 l0 T
5 @* r: O8 h' E& s: r# [5 a: F6 F! R: I- HAL_FLASH_Lock();$ @' H( h @9 B+ C, d- U O! g
- }
, `; s5 |/ o* Z+ e% W' _( Z6 z v
- i& |( t; B" ?) x0 ]0 H8 V( A- uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)& M# f" W0 l: d& f* E
- {
+ S# o& ]+ G @# o# x - uint32_t i;
7 @: b/ g2 o0 B4 U - uint16_t data = 0;; `0 R+ N$ T$ O* N2 F3 a% U
- 8 l7 E+ Q! w$ d1 O) C
- if (length == 0)* v4 y1 A* [2 ^% j
- {9 V8 G5 c/ U# \
- return 0;
& i" @; r N% ]" m - }
3 t' i: Q9 @+ V# q! \2 r/ [ - ( J6 h9 v1 t+ @% v
- HAL_FLASH_Unlock();
/ ~ u T( X { r6 p( n0 o9 ~
' p3 e5 x0 }$ f- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |3 m* @1 k8 D! R
- FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);" P' ?+ O$ n+ P) [
- , k( T4 I5 A, k; ?2 o
- // 按半字编程
1 i1 m3 [8 A5 B - for (i = 0; i < length; i += 2)
* R+ p$ Q/ b, c# i1 q0 M - {" V7 a2 e0 [+ ^2 Z
- data = (*(buffer + i + 1) << 8) + (*(buffer + i));/ Q$ t6 Z: z* j
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);' y9 V2 ^. Z: c* C R
- }- R9 T0 ]: R6 h: @% f
1 c; L$ L, }) y7 E+ h7 {9 h% h- HAL_FLASH_Lock();
. X- e2 }- ?% ^) a
9 }: L# L7 K/ u0 {( Z5 J- return 0;+ P& ?$ E$ K6 W6 G8 P% R
- }7 P+ b2 c& I5 G3 ?* Z. S5 }
7 M2 S% |4 X# }& k! U' B4 E4 n6 R- uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
: h' R, j# D) p4 [+ H+ l2 V - {" x7 W2 | j5 P0 E. R
- memcpy(buffer, (void *)addr, length);% h. |9 b! S) m* S
- " f5 {( p# x+ n: L
- return length;
/ O" Z2 w" i1 R# r5 l% p7 f3 @2 E1 ^ - }. {* v7 q7 H- c, ^5 W6 j3 l6 H
1 v' J+ V; Q( E0 }' r+ G
复制代码
3 e: D6 t$ g0 ?, U# d$ l' u" I% [' s& o8 f+ D/ W) f* p
|