这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。! C2 T+ K! n& d+ m7 ^+ @7 D' m
" d4 |) O5 o$ b) J- // STM32F767IGT6: 1M flash
" S# g- m. `7 t - // STM32F767ZIT6: 2M flash5 {0 [7 @6 S9 h4 v7 k' M
- #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
1 x$ Q6 p; Q5 G% J - #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */
( B9 |' M' N }1 F - #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */
4 J7 R% z% B0 B5 [0 _ - #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */+ o! V/ e' }+ @ z1 D
- #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */
! v7 D8 O7 a$ ~- C! ] - #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
4 Z! Y1 m% q1 i) ~) X7 o" p - #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */5 u* S" a4 u8 F* e* R2 b! g
- #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */6 q8 _8 A5 r9 T- ~ L2 L+ X) g
- #ifdef STM32F767ZIT6
6 d ~' q) j" _ - #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
* Y" C9 n) |0 O- @/ ^ - #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
- n5 C6 _0 c: r% j - #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */; T5 M9 t/ X$ V u5 H- _# B* o
- #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */
$ j* q4 ~, V, K$ j - #endif
复制代码- // 获取要擦除扇区编号8 T2 M9 S$ u4 V/ M- j! w0 r
- static uint32_t flash_sector_number(uint32_t address)
, c% ]; y% b8 ]+ w3 j - {# q2 k0 U k0 K8 y
- uint32_t sector = 0;7 s0 e. E# l! j, ] L0 }5 \- e
1 w2 R+ O4 H5 R- if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))& P: ^6 L0 y# F: D1 P( ^6 J
- {# C& f) _0 P7 N% s \9 x3 m5 c, v: I0 K
- sector = FLASH_SECTOR_0;6 ?$ f1 Z' K& W1 d
- }
2 ^! Z0 U0 Y% Q* ` - else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))1 Q3 i3 I3 o: F
- {
$ ^. N3 b0 ?. [* | - sector = FLASH_SECTOR_1;( A$ E: l1 B7 K- ]/ w9 f! @
- }
( u" r* W* v$ T s, m1 Q! ^ - else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))
6 z' B6 ^) A0 h7 X8 h" s - {* _3 r: e) h2 u- X
- sector = FLASH_SECTOR_2;
: w1 F; Q; A* C: m - }. Z3 e: S% ~$ E- `0 Y
- else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))8 Z# p- P" u& {" k; w6 n' F% f
- {
1 i+ x7 P+ Y# M - sector = FLASH_SECTOR_3;
0 d; x, }( b, f2 V# Q$ E - }$ }$ ?! ?3 N8 @* U
- else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))+ i" }4 h# s! E8 N, W1 s8 x
- {
4 k$ @5 A' M( c, U+ c) s - sector = FLASH_SECTOR_4;6 l) n8 h6 w2 I2 e
- }
c' a" W. r8 C7 ` - else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5)), d* T* ], g) t/ i+ T4 K* x! N! o
- {1 C' l' M6 o% B$ `2 Q) `
- sector = FLASH_SECTOR_5;/ }9 ^) |2 K( C& d1 S5 N' u
- }, u; Y( ?- o/ f6 \6 K
- else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))% Q: i9 _" }7 _% L0 L7 K( B
- {
C' i$ I% R+ e6 J2 O - sector = FLASH_SECTOR_6;5 ^ s& q5 _; u/ s
- }
* I) r& V# W2 U* \8 l; E - #ifdef STM32F767ZIT61 _9 G/ j: E# f( D# Y& \. R) g
- else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))" d! \- ?: f0 W- u
- {
) L) ?; O, i3 I0 r, f3 r - sector = FLASH_SECTOR_7;. l( g& V% J. H+ J- B0 u; @
- }) {5 I' V3 y" S' q O. [
- else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))
7 s* S) y, b; \. i! ? - {3 d& [0 M0 @+ t. g
- sector = FLASH_SECTOR_8;) l" D- @, f+ K2 s% H* [: z) C' V
- }/ a) {* i" A4 u8 S
- else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9)). c/ b& ^: Q- }! r) L
- {( `# q% F& L% h7 T2 ?% u
- sector = FLASH_SECTOR_9;
% u( j: t6 n; W4 c8 ~, r; `8 { - }; p! |+ m. s ?/ j$ h* Q
- else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
8 O# H, X7 k7 J& o9 U! i9 p3 ^( R - { w( c/ J7 [6 }! g' M
- sector = FLASH_SECTOR_10;
& \- Q1 F8 f/ M& y - }$ N9 z: j/ H! I; f- t- x4 K
- else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))$ E, x( x3 C7 @' W
- {5 z/ R+ t& Q* ?- B2 _- z$ j
- sector = FLASH_SECTOR_11;
8 i6 l0 ^7 L) P - }% v. ^6 ~2 |' b! ?9 G
- #else
1 Q4 R# Q6 e4 e - else if(address >= ADDR_FLASH_SECTOR_7)
6 Y7 Q, T6 Y9 z2 n: n - {: }5 z8 \% t3 v0 { m% ^" C+ N
- sector = FLASH_SECTOR_6;" a: d' ^6 Y2 G% p9 B
- }4 W1 s% j) ^. } q7 K
- #endif
6 }# ?6 J/ r% X - 6 R5 R! O9 `, b; X; C4 [
- return sector;
9 b6 n/ M+ {( H! w7 K5 D - }7 o, b" C- \( T* x, f
- * K4 e8 b! g: d. u! s
- // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。1 K/ d' s7 h2 |" {4 U
- void SocFlashErase(uint32_t addr, uint8_t count)
5 I' R$ r; [! T - {
1 g1 ]) j. `) t: P4 z- l - FLASH_EraseInitTypeDef flash_erase;
" |0 ?" T; a2 T$ p+ m$ A: n) k - uint32_t flash_error;' Y* v5 r0 l% j) B; v3 D
& a: u4 t2 r* B/ \9 Y- HAL_FLASH_Unlock();7 S' g# ^; `1 e6 k" _1 w9 z% `5 E
. F+ Q! |4 q# O8 X1 w% F- flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; // 擦除类型,扇区擦除* B& h9 n0 U& u6 ^. B
- flash_erase.Sector = flash_sector_number(addr); // 要擦除的扇区3 z0 S) P }( U5 |- e& ?
- flash_erase.NbSectors = 1; // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1" A" e% \# [* s) d2 B; Y
- flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!& y9 `& l1 x `' x( c
2 t! u; x7 V) l ^- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
9 F" r9 X* ^ J9 b1 l - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);3 W/ p) |4 P: v/ |, j
- ; E: L: p" c9 }( Y
- HAL_FLASHEx_Erase(&flash_erase, &flash_error);
% R2 T7 [9 V% j# `8 r- ^* P - % q1 k# m( {6 i
- FLASH_WaitForLastOperation(50000);
" [9 u$ l* [' i4 W" A - . T+ {0 g% g1 v" W% v# ~
- HAL_FLASH_Lock();
+ Q1 [' {0 v/ I& u* c. j' J7 w - }( r2 P) H" K& B8 w
- % i1 ^' i$ ^5 o' }9 x
- uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)# e4 \3 B/ ?8 s
- {) d9 j5 U. \: B. q, M8 }8 W
- uint32_t i;9 V3 f" G+ U) D
- uint16_t data = 0;
, Q6 i+ S) n7 o1 k+ \ J% f. r: O+ } - 6 ]% P4 p B( O# v) P# B
- if (length == 0)
* H5 F5 K# ~8 J - {" g1 v9 T$ [( ?
- return 0;7 K9 y1 [2 B' J9 W3 b
- }( d( n( o6 X* p4 S4 v# l
+ r1 p* [2 I( F4 j5 i/ K- HAL_FLASH_Unlock();
! m- t, n& T* R+ L: H% b - 7 y' h5 K8 K+ ]5 ~& n+ K: v8 _
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \& Q% G6 r" L( C- f: T; B
- FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
% U/ c% U- O# @7 S% @ q" b* w - 8 ?, E1 E% M8 E5 C
- // 按半字编程
! w: | A: D9 N5 m. F - for (i = 0; i < length; i += 2)
$ P$ ?4 i/ z' c" o# S2 j$ s - {
) M- f- r+ `) i: W$ K - data = (*(buffer + i + 1) << 8) + (*(buffer + i));4 ^0 ~# a# Z5 v
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);7 y/ D2 }/ [1 Y# {; S
- }+ u- M" k# c0 I" |
- 3 x1 {2 A* m" E+ ?. V3 w
- HAL_FLASH_Lock();
/ ?1 {- k/ c3 N9 y - ' i/ m) E8 j: m
- return 0;
7 {% S2 _8 @# c! s' P: d; M - }
/ d: F, D0 s* u; |& n* C3 R
) o% D# Y! `% M( |- i, e6 b3 Q4 }! p: J- uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
0 ^) v- X9 t I/ P) u- Z - {
- e3 g d) ]1 G2 G8 N. N - memcpy(buffer, (void *)addr, length);
2 c; h; r0 E# H8 k, z, |, B - : P) a9 |6 a; n, G
- return length;
* e4 c5 ~& R, X' I2 O - }' s- C* v) V& Y/ f& E: I: s
- ( W/ ~; {4 @1 T) r8 ]
复制代码
. V# j3 x s- [6 D$ z: r, r4 h% Q
|