这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。2 {, Z: V/ I' Y* v% e- V
& Z i3 W$ p& P
- // STM32F767IGT6: 1M flash! k) C! N( a* n6 M* J
- // STM32F767ZIT6: 2M flash! _& U/ \% E* S4 M' F2 X: n
- #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */6 l( m/ E/ G6 f3 s5 h- x1 p7 l
- #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */" u( a7 C7 e2 ]
- #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */; Q' r/ q0 h% J4 S, o' E0 ?8 l3 m
- #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */& i6 x* c+ a5 U/ v* b
- #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */- \3 n; `7 f4 u( s* i- j/ D
- #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
! q- f2 {+ X3 ^ - #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */9 e/ [3 G* k/ a0 t$ l* k Q& L" B
- #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */$ r. t& `, t3 D9 A/ x
- #ifdef STM32F767ZIT6: p. q3 ]4 A, F
- #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
& q" Y6 r( Z8 _5 q - #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
2 M/ ^* X6 O4 n; ` - #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */) a* T* m+ E: g+ z; Q- f. `/ ?5 T
- #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */" j2 B, Y7 y j$ J; [
- #endif
复制代码- // 获取要擦除扇区编号
; Y' c: ]# j6 y3 C' l - static uint32_t flash_sector_number(uint32_t address) H* S. y6 N9 ~8 t' v( f
- {) R" i) H8 _* X
- uint32_t sector = 0;. N" ^, S/ X$ Q$ ^% `: M
5 Y O3 k1 p4 d. _8 p- if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))
w& X) F3 L- a# _% T+ S! D0 o8 V7 f - {
" c, j- y% D$ H0 c9 F8 S/ `& I8 y ~ - sector = FLASH_SECTOR_0;8 b; ?+ x' z6 o" N/ H/ k- U
- }$ _% ]- ?" }0 E: c& \ C- v4 Q7 p
- else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))
+ S3 G1 \0 A( X% K# O - {
( t: \5 o! d% Q! b4 p - sector = FLASH_SECTOR_1;
8 l2 ? G6 B s2 ^9 g) Y9 H; G - }
, J" H4 g% B2 i - else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))
/ Y' }; F, v4 L) d: w) C j: w - {
' y8 r/ H& J$ Z. t - sector = FLASH_SECTOR_2;, p0 x2 m' r5 J* L* o
- }
9 {! Z% c1 f/ N+ H& U: N - else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))% j9 C) j* N5 C+ ]8 S& p0 P3 v
- {
5 w% k7 y c1 C5 F8 x! B9 J" L1 e. k - sector = FLASH_SECTOR_3;& F" A8 _* W$ V9 L
- }
8 |% l- T! M! O) h8 _( l( C - else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
6 \: @, K1 `* p1 J - {
8 K. D/ w: | R. y - sector = FLASH_SECTOR_4;
+ a* X5 ~/ A( t$ S0 J6 q - }+ T" e+ q+ x- j
- else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))( d6 D K) d6 n6 F$ t X q1 j
- {7 l( n& U$ }, k s3 ?& ^/ J
- sector = FLASH_SECTOR_5;
, [* W: J0 L+ W8 {2 q( ? - }' C$ U6 z5 r7 {& O) T9 s
- else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))- Y+ N, y& p) L% [: L
- { s8 V7 W7 a& H3 |, `, ~
- sector = FLASH_SECTOR_6;/ l0 T# s* j* L! ~' _
- }
& D' Y6 L4 m1 \8 R6 R, t( e- _, @) U- ~5 E - #ifdef STM32F767ZIT6
4 K, I4 j! K6 J - else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
9 R" N ?5 Q- X$ A" R - {
9 H: v" f! G$ o8 L8 [4 V7 T) w/ W - sector = FLASH_SECTOR_7;
; W, L, }/ t, ~! f# F& @ - }
6 T, V* D1 c6 K/ b' k6 n+ A. M. M - else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))6 a% G* B4 F0 v2 y% g" x
- {0 I9 \; z6 E+ s& h' H7 b+ {4 n6 d0 [
- sector = FLASH_SECTOR_8; r* P/ V6 `& J" w
- }
3 d6 @8 n; c: q/ h9 o* E - else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))3 I. {7 q' X0 w$ y$ X
- {6 b) l/ Q" B7 |0 t; C5 f* |; X3 ?- _
- sector = FLASH_SECTOR_9;
* n$ V& w* c" P - }
/ l% J) v8 h- p6 N) K: V - else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
6 X% Y" ~ T( U3 i, w - {% k' i) S0 d+ c+ T2 m: g3 h
- sector = FLASH_SECTOR_10;
# F# ~2 k. \, ]) h - }! R8 A- w7 e" ]/ C6 ]$ G
- else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))
3 P. U# f; \; r; j% A - {9 o( D( D7 n. T* Y7 j, V7 Z
- sector = FLASH_SECTOR_11;) \) a9 | \( f" I8 ~% O
- }
l3 X8 c0 c8 p# Z5 M2 ] - #else
$ v0 l% x% X; p- w - else if(address >= ADDR_FLASH_SECTOR_7)
. B y! M8 _' p - {/ V4 a K& w" h% V
- sector = FLASH_SECTOR_6;: y3 w2 d- u# ~' a, ~5 y
- }. [1 Y6 D; K- S2 U+ U8 X4 d2 ^! x
- #endif
" |; j7 K, }9 n+ z; \: T - 4 \9 P: ]/ Q. t
- return sector;
4 K: S T6 T( \ - }3 C1 Q. e6 P& Z- |
# j8 W: I4 K+ B6 ]3 a# Z9 ]3 }- // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。( K. n/ F0 X4 ^: }4 d8 A
- void SocFlashErase(uint32_t addr, uint8_t count)& n9 K. ]+ D* I7 U) j2 [$ e# M
- {
; V6 V4 i1 R' A7 i' w7 {' @% M - FLASH_EraseInitTypeDef flash_erase;
' x% i" G* R4 t0 L. H' \2 ` - uint32_t flash_error;
6 W% H k7 J* N! N& [ ?: E
+ M+ Y9 ]" g1 F- HAL_FLASH_Unlock();
8 q( J! C8 j7 _+ i" O, f) c
( E% T6 T" Z3 `2 }# g* Q+ c* N6 p- flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; // 擦除类型,扇区擦除
4 w# P( L! Y$ P3 A/ d9 ^ - flash_erase.Sector = flash_sector_number(addr); // 要擦除的扇区
8 I& v7 U) I. K, V - flash_erase.NbSectors = 1; // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
5 [0 I2 q/ P4 t- ?- b# W! b8 u - flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!* X4 w# F8 f5 M- m+ L5 w9 K
- % z8 [6 p$ B, U1 }, |4 ]5 C2 c
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |, ?, @. ? X g% I2 h
- FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY); f. E! A+ ~' p0 j* D
2 P( @8 d% h, V: H1 T" x3 V ]4 Q- HAL_FLASHEx_Erase(&flash_erase, &flash_error);( P' e8 M3 i- I# j6 c
- ' r$ j! e( C4 d# N
- FLASH_WaitForLastOperation(50000);) h/ G8 E, H) a4 I; k& O
- ' q/ G6 s: \/ a$ F' @2 E& g
- HAL_FLASH_Lock();) N: M/ g$ @/ c: d4 u( l
- }: `4 W3 v% z$ C$ W% O' t$ q4 P
7 |; {$ c: c# C- uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)6 ] N% y& c( T& ]
- {
) e* _4 M. a8 L1 M2 z* y - uint32_t i;
8 g( T, [- @- U1 v; ]) j. a" q J7 q* ~ - uint16_t data = 0;
4 V( ]- W: A$ x4 r4 L, ]0 Y& q
5 K# G. X* u* ]5 m5 X( f A5 N3 A- if (length == 0)
& h' W* W6 h# T" v& \ - {, Q, C/ F f6 z0 ?0 S# }: k: S
- return 0;
7 |3 G B+ X% w - }( u) G, l* Z& |7 ^5 q# c V
/ h: e) ?! _& F* k# m' n- HAL_FLASH_Unlock();* [% Q% |: B! p3 L8 k3 ?( u5 \
; W U& V7 K$ _$ z. U7 h- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
' a0 ~* S, Q# q8 i! I - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
7 |, ^8 f, Q7 w8 S V A; U8 y - 8 B# Y. Z' H9 V$ }8 M. v+ m w
- // 按半字编程
5 k( ]# i' |# @ - for (i = 0; i < length; i += 2)
8 o1 y. z+ `( G0 ^1 ]1 v. n4 ? - {7 d" O5 d5 H5 b& {
- data = (*(buffer + i + 1) << 8) + (*(buffer + i));( t9 k7 B: i. A9 u8 a( Z
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);
/ ^8 S* O: h! @9 F- t - }/ t& R* |, j: `
- 3 I3 K/ j& {; V/ \$ G7 R h
- HAL_FLASH_Lock();$ Y: W; Q% Q; Z& E
4 ^) {# a: H4 A- return 0;
6 J5 S1 x1 s& w" X! G2 ] - }5 i: l. S# s; x- a, f* y3 T! ~
- 4 f4 ?7 F- L2 C1 D; j
- uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
; k* w0 f9 C4 \% t! C4 D - {) O/ s X' ? B- G1 Q
- memcpy(buffer, (void *)addr, length);
: S- e) M& ^* ^" d. m - : \5 ]5 H) K9 j2 O+ \
- return length;7 i6 w/ v: S& y4 _7 ^9 W9 C
- }
- \ r6 z* I+ b D4 O - 1 t8 @* o. n# I6 M4 `
复制代码 & s% J0 \2 Z" W6 b( F
4 m, l9 c0 f5 h) t |