这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。
: X- Q% p0 b& x( ]$ `8 k9 v8 ^6 n9 l0 B
- // STM32F767IGT6: 1M flash
4 _* o; g& ^! S! M( n1 k2 Q1 f - // STM32F767ZIT6: 2M flash) ]" W. `3 u1 A$ R
- #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
& V% v" x" N' a; }1 u' M - #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */) m$ N6 ]$ p- g% C7 I: x3 b
- #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */& @! ]4 q+ t5 |/ c) C
- #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
1 p5 b9 X1 Y. I& R; P - #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */+ N" j2 q0 g8 o0 N
- #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */! j( Z, t; c4 S5 G) {/ S! }
- #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */
W( a; q: Z0 G4 L; a' L. k# x - #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */% [( u' ]3 T2 t5 T, H
- #ifdef STM32F767ZIT6
( B0 O L" _3 B/ s# q0 f - #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
# S! x( U2 E# z U - #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */$ ?/ \$ \1 m/ ?+ m' Y" s
- #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */
0 K1 }2 O( A8 m; ~ - #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */( i* u( k' E4 i* M p3 i
- #endif
复制代码- // 获取要擦除扇区编号
6 ` R) p* W- W: l6 k - static uint32_t flash_sector_number(uint32_t address)
. ?( T/ _1 `" u4 T3 H0 {# N3 W - {
( s% ^( ]: i/ _2 i, U$ i - uint32_t sector = 0;0 C/ c7 C. h$ `! [2 p) }( g
- # A% t4 O8 y* v( M, {5 _: s. @
- if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))5 Z/ t, y/ A' A% X6 r9 U
- {
4 p; ^1 E" `' V% G$ [$ ? - sector = FLASH_SECTOR_0;2 X- k0 q& J' [2 w; |
- }
, |' k) ^, F9 O. \! Z8 c% j - else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))* z& G# u% ~1 d, n
- {( N0 i0 X( A( b; j/ A/ a7 e
- sector = FLASH_SECTOR_1;! w# U7 m) o) S' `. n5 S
- }
+ q- A7 i7 z, D- h" a9 Q0 R3 `7 r - else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))
5 f' k n& T7 ^4 T3 f5 t% M - {
; _* X( `3 ~" z4 Y' ] - sector = FLASH_SECTOR_2;: {6 L7 d( u8 a" x9 D+ P' J% E
- }
9 A4 M- |8 I/ E8 B& A - else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))
9 A0 n" v. @% i - {
( a" M) M @- m, C5 @1 m O - sector = FLASH_SECTOR_3;* X( r) I! U! y0 `0 D- K
- }3 C2 J. ~& k6 B9 I- I( A
- else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
) O- {" o; ^* u2 C8 F* f: p) o - {
1 t0 N ^" K6 M- J# o$ u9 G7 j Y2 ]7 Y, K - sector = FLASH_SECTOR_4;
8 e, k ?9 |$ b( g5 Y - }
1 _( d* d u U a. ?. u6 x - else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))7 F: l4 o! r# ~. ~
- {
$ `( P+ A/ i$ P9 X) T' V - sector = FLASH_SECTOR_5;" U: Y b) p3 U' e
- }
( D# @7 @9 q1 i, ?5 k7 G( P8 d; q# x - else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))* U$ j! G9 ?+ J+ X- d6 z; E
- {1 s, @0 s5 x$ [1 r1 ]8 q. q
- sector = FLASH_SECTOR_6;4 f# C4 i8 I1 R; |% Q
- }1 L" ]% s+ v4 F: b2 W* D
- #ifdef STM32F767ZIT6
2 Q5 J; B G4 a' F! r - else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
: |1 v) e! ~) I" F8 I7 d - {( U7 b' a1 V8 K, s# ^! g5 b: B# d) i% w
- sector = FLASH_SECTOR_7;3 F4 Z3 d1 v3 K. Y+ A" v1 c6 _1 k
- }
* ^0 b, V% E5 V - else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))/ \; b |, Q0 T' }) M
- {
! Q! z; h3 [) `9 J/ _ - sector = FLASH_SECTOR_8;
. E7 @6 g& [" \3 A) L - }
# a: _1 m; Y' n9 f2 U- Y - else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))$ F- q1 q6 Q* x* @
- {
7 Q7 Z% \ [9 [% S* _: H - sector = FLASH_SECTOR_9;
! J+ y8 d0 t2 y6 K6 M% z - }
% q1 l8 `4 _: L, g; v" p - else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
" D+ e7 n" N$ `- t$ i4 j4 Y - {: n# s8 x& m1 Z( t; z
- sector = FLASH_SECTOR_10;
4 b& V( s2 X0 s2 g' i) q! R - }+ W0 `8 k& b3 {2 l9 @' x
- else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))" V( t/ F5 B3 X8 O6 k
- {
& ]5 L( G% o8 G- ]. M - sector = FLASH_SECTOR_11;$ T9 g. k5 @8 W Y( ]4 h
- }
9 {# H; q7 D6 u+ B - #else; {+ |$ z( ]- V4 L4 \, w% Y& O: V. {
- else if(address >= ADDR_FLASH_SECTOR_7)* \0 a. }# \% c. E
- {2 E ` b0 u5 a' R* C0 l; p2 U: O
- sector = FLASH_SECTOR_6;
* T4 I; z4 R2 h5 p# v0 k - }9 C# d J0 r) w# ~; X7 Y7 v
- #endif
8 v# Z9 B. {0 y, k/ C: N - ) E! u' b9 ~* ^- T
- return sector;/ E' J; J9 k( a, b2 J$ }7 W `
- }
1 S* T1 u8 E2 I2 G& M2 v- m& Y
, q8 W0 j+ d9 ]' w, a+ P' c8 C- // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
8 Q9 Z; [+ _, t - void SocFlashErase(uint32_t addr, uint8_t count)0 M1 i6 @' o; f' f# n" @
- {
2 T& g9 |8 {. c! }- s - FLASH_EraseInitTypeDef flash_erase;. M/ Z( ^7 t/ g! W' q2 q
- uint32_t flash_error;
$ m0 Q7 s7 `/ v1 W1 i. t/ J! p( O$ o - : _) `; c8 v3 @' Z/ w& c* L0 `2 U
- HAL_FLASH_Unlock();
) d) l% Z2 N: i) J R8 E
6 ?: ?# {- Z. \- flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; // 擦除类型,扇区擦除
. o* n% F" Z0 G% l# ^2 Z; | - flash_erase.Sector = flash_sector_number(addr); // 要擦除的扇区 C9 I# p( l% L
- flash_erase.NbSectors = 1; // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
+ n& }8 J$ x) F; A/ k - flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!1 _5 m+ n: |2 |0 ^/ l
- 6 G, e% I' R; [: k7 I
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
2 d4 f+ L; M3 N& P - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
7 Q5 W; m6 K+ T a
3 D/ h5 H2 s! U. w0 S! k- HAL_FLASHEx_Erase(&flash_erase, &flash_error);# F3 h2 p5 F* ?" L7 p
$ {1 t, E- i; H" ]! m6 P, Y; {- FLASH_WaitForLastOperation(50000);
9 p1 e3 X6 L' W/ E - / v" U6 r: p* |! t. H% m
- HAL_FLASH_Lock();# {! q3 C% `$ ^
- }
: o" [+ e6 Q, A: x, l9 |
3 P. U+ ~3 Y0 L; u) Q- uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)
- {( W. Q3 @9 G- a( J, q - {
. a% }, u; x1 c - uint32_t i;; @4 k. w( A' { j8 V3 q W5 r
- uint16_t data = 0;
" [6 V2 _- P5 Y- H7 O2 J - 9 `" ]' B' E |$ F
- if (length == 0)
' S4 Q @5 p, a2 @ o: i - {" J) A6 G" _0 s5 F2 c- c q
- return 0;
% i B" m. L4 a9 U - }
& E( ? a# B3 Z6 a' v" n3 a
$ E+ X$ U' |+ ]3 Z- HAL_FLASH_Unlock();
1 h) [# L: A0 c) F; ?
) |3 ]+ [9 P" O) U- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
$ A. S9 ?1 a( ?0 ? G0 m - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
; x# a2 W+ ^: e- b" H1 K - 9 o/ z; N' U4 u. ~
- // 按半字编程
; b, I: R& N7 C( D) V - for (i = 0; i < length; i += 2)+ V% [% Y) \, g5 C) Z0 g
- {
* f+ ~2 H* S6 Z; J7 M; ~8 ^ - data = (*(buffer + i + 1) << 8) + (*(buffer + i));$ y! G1 f" ~" u2 Z" w& H* _6 M& o
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);
; I0 C$ A, y$ n3 ^ - }
. ~' l4 h: x: S0 v) f8 x
* z4 E5 I. b8 v8 G- HAL_FLASH_Lock();
. u R2 p, s D% J; `
Y! b: e3 F3 R7 v- return 0;! N9 a% I% o4 M6 Q$ z# G4 V+ n0 u
- }
5 w' f' z; \: G( x+ F: b - : v( ]$ c$ E3 Z+ h1 U7 q
- uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)& f; \# R7 ^1 o5 W
- {3 i6 C7 f. N. W+ n5 I9 L* ~
- memcpy(buffer, (void *)addr, length);; a" e3 a7 O" U' F8 Y
, Z+ z1 w. ?: h2 [1 m3 ?- return length; j, l5 b% W8 c' h3 b
- }- U' L5 T# m% d, I3 p) k
- 0 E3 ?- D. f5 |; E- g: |5 W
复制代码 8 `* e8 I. g3 }: j
. ^" {+ P+ G' A9 H- ?$ N/ L
|