这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。
8 b1 c1 V( ~* ^ ~; j
( n0 p+ Y% X! |& ~- // STM32F767IGT6: 1M flash
9 m7 r. d% A s - // STM32F767ZIT6: 2M flash
3 H. I8 D4 X- I7 L& ^( D - #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
$ v$ x- d( |- o& J6 ` - #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */7 |5 t/ Z" P$ D0 V& B1 I; A' r' V
- #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */
9 k) S$ C- l2 E% @) k4 f+ b- U - #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */5 g0 P+ V" n" f. e
- #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */& Q: S7 Y2 K N6 L( o* O: e
- #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
9 W8 ?3 ]( ?' S, a" l$ S) |# B( ]) ^ - #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */& y8 I/ a( Q* b( ~0 k) u8 M
- #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */ @' N4 P: h/ P2 T: y$ `
- #ifdef STM32F767ZIT6
" c O3 Z6 M& e1 { - #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
3 B! U& X: `# F+ K. r - #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
$ ~8 s# G) o* | v - #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */
! o2 [' A: }# L7 E+ ~ - #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes *// r. Q& }2 G5 x0 b5 o: C
- #endif
复制代码- // 获取要擦除扇区编号% y1 m0 I5 G4 {; B% H
- static uint32_t flash_sector_number(uint32_t address)/ e c- F( p5 [
- {
5 H: K1 F/ M0 \1 B" w$ W# W) B$ q - uint32_t sector = 0;
: P S- ^% F& K, l, W8 [
* w3 m# y- D$ v6 ^5 X/ j- if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0)): `" C$ X+ B9 x% ^; C$ Y: B! x
- {
5 s6 X' a K, c4 `: ^4 ~% u/ \, @ - sector = FLASH_SECTOR_0;
) ~# R5 h- B) ~7 P. { - }1 t! _2 C, y& W0 s
- else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))* t/ p5 ^, f& J+ z
- {4 f4 I! b* \% I4 e! o% D+ q
- sector = FLASH_SECTOR_1;% \' c% V7 [- ^
- }+ q7 Q( [9 I' Z, {( D7 ?% P
- else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))- I( @1 y; b& ^: ~0 d
- {) k( E& I" `* B. G- _: V) [( G+ ~3 q0 w
- sector = FLASH_SECTOR_2; L3 R' r; f! u6 g
- }
- ^7 g Q. E" Z Y2 a. H; }1 W - else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))
1 |! F+ Z9 P) W9 ]5 X7 @9 b8 b - {3 p8 q& H0 {9 [5 Z5 |4 q1 N
- sector = FLASH_SECTOR_3;
0 Q' h* A$ \* g/ m- \% A' \: ^& F - }
# K$ A- ^* B+ ~7 v! A* S x; } - else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
# @+ R! d# M3 \; f1 d - {8 e, H( Z5 F/ j- b2 \
- sector = FLASH_SECTOR_4;
, p' Q% t8 w7 r9 B5 P1 A4 ] P - }
" a" v" U b9 A& T, |$ v - else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))1 i Z0 @ A [* t
- {7 E5 ^ J& ^4 I, D# l
- sector = FLASH_SECTOR_5;* V/ O9 M8 H$ R: |: ^0 L
- }( p0 a4 R1 e+ _3 d4 V; j
- else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))
0 b! v- r. G. a4 F9 V1 @ - {' s; w- _/ B% q
- sector = FLASH_SECTOR_6;' e' r, k. P3 o: {% d" A! o
- }
* p, t2 _& s/ s: E: d' `9 o - #ifdef STM32F767ZIT69 E. a" K9 c/ z
- else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
+ p1 Q( x( X% r( x% d4 ] - {' Q8 b6 S `; B- L {2 y+ o
- sector = FLASH_SECTOR_7;
- F( {, b7 N8 h; H5 H$ Z - }
( t, ]8 Q7 G; \$ `) e( z+ M - else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))& C5 { p) E+ W4 ? c! T
- {' z" H* J$ a# Z8 q
- sector = FLASH_SECTOR_8;
+ Q: G* W* z$ d! B0 }9 D! Q* b+ z2 T - }
3 B9 ]8 N( E; S4 W. ? - else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))+ X0 p- v" Z# n
- {& q: B @' T* K9 b8 Q1 o
- sector = FLASH_SECTOR_9;% D; b0 c, O3 e' Z) }: o, {
- }
) Q! R8 o6 R" I - else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10)): a G! E0 H$ n) Y) q G
- {0 _3 O! j8 r$ F6 P# D/ P
- sector = FLASH_SECTOR_10;! l+ }8 b/ }: `5 O# m
- }
! I8 ?) l% j* K9 ` - else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))
: E7 @4 y% b$ Z& _7 P+ A/ s/ { - {) _5 V2 M5 u# [' s, {* O
- sector = FLASH_SECTOR_11;: Z# i4 h3 w8 E: E
- }. o8 E- d$ l% D7 x( W. l
- #else
3 j7 A! r- D: G N; y- _! Q - else if(address >= ADDR_FLASH_SECTOR_7)" \: s) |9 w5 q
- {
2 h) x$ s- {) l3 F, k! O - sector = FLASH_SECTOR_6;0 \3 [/ M4 s X* j2 x
- }
$ @8 x. ^" ^" J8 { - #endif
1 z! h, `1 g) Q! D) C1 e - 0 ?: m ]( h9 p
- return sector;
0 |% j4 Z1 D) t. Y' b+ a - }% M; Y* Z' {& a4 Q) D
- % N" Q: }6 w, S8 I7 |* D
- // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
& c7 w9 J$ Y" z7 B2 B$ I - void SocFlashErase(uint32_t addr, uint8_t count) H7 G$ N( H- u; i! |
- {
. d# J5 n/ f/ | - FLASH_EraseInitTypeDef flash_erase;2 \) T& f* Y' |. C7 _
- uint32_t flash_error;" ^% } e! e b: L5 v. c" }/ s
0 ~5 U$ D/ P' j- HAL_FLASH_Unlock();$ r; S4 }* ~. W% K' c
. F3 M* [6 W0 N- flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; // 擦除类型,扇区擦除$ b8 J# U7 `# h7 L- R/ W
- flash_erase.Sector = flash_sector_number(addr); // 要擦除的扇区
& e# U1 w( i4 a: p8 H: h - flash_erase.NbSectors = 1; // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
3 b# Q6 N0 @9 o( V - flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!: V: c& B) O+ f3 R1 T
" V( V; h, G) L% F9 s4 r- B: a- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
3 D+ ~3 N! f8 r5 j# {+ H% J - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
7 y9 r5 Y/ R" ~& ?0 g! q' N - ) X0 P6 h3 k+ ?6 O y
- HAL_FLASHEx_Erase(&flash_erase, &flash_error);7 e4 y0 n. r3 K8 g0 W6 J
5 q; k% d/ Z2 D1 U: u7 i( d- FLASH_WaitForLastOperation(50000);5 r8 r+ b& e! ]5 ^+ q4 O) L+ F
; Z& Y5 @( K" q2 Z5 Q- HAL_FLASH_Lock();
3 d/ u3 ?0 Z8 L - }
3 J5 P7 V; y* P& l4 Z& S l) ] - 8 Q) b9 r- _3 b2 m [6 u
- uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)
* P* x: _1 t. \1 `/ z - {
3 G y$ f* a* r; i/ @ - uint32_t i;
1 d8 Y p/ ^6 h8 V- x$ T. F - uint16_t data = 0;
7 i, r+ P- K+ Y! \ - 9 w7 c0 B9 a7 P z0 r
- if (length == 0)
4 n+ s& N; ?% J' g - {$ }( n; F0 @9 x7 ?/ S
- return 0;
1 K2 r$ q4 Q& [( s: n - }
$ T) h) L! A/ r: w) f7 g' n - " w4 a8 _. b6 V$ h
- HAL_FLASH_Unlock();
( p4 ]# U5 I. Z7 p& e5 Z
- r* O- t, N* Q( m3 w0 u- O }9 j- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
1 L6 ?9 n& C( I" R# H) b - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
0 a4 A) [3 d8 K1 Z, r0 k, T" c! F7 z
$ x" H& `/ C' i" ]1 W- // 按半字编程
1 h& z- S* l$ D/ q - for (i = 0; i < length; i += 2)8 v/ L" g( g& y" `3 K' b9 i- B
- {2 C$ g* ~1 n$ O, G2 U
- data = (*(buffer + i + 1) << 8) + (*(buffer + i));- n& c: c9 F2 W! u7 ~
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);; ]5 [* ^% P s
- }7 J/ g( F8 D4 \. N
/ Q0 Y K4 S$ W# h6 [4 y- HAL_FLASH_Lock();
0 U' R% {" {8 C. [1 |4 R
. s, v5 x/ m: m3 M% h/ H6 [9 R- return 0;. o0 B/ F& B! ]9 Z$ d
- }
0 K2 z; \+ e! @2 `" x1 }) d% k
% [( D7 j" L3 Y( J# A- uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
$ ]6 m0 R7 j B9 X6 q# q0 X - {
$ \8 P( l% J, ~2 j5 i9 X - memcpy(buffer, (void *)addr, length);
% ~5 x* J/ C3 D8 ]7 g: W" a# U% U
9 D( d. b/ j' ]3 {/ x# Y7 R- ~- return length;9 h5 e2 p* @5 C! R/ U
- }
& d7 G& a6 `9 H, M! i& r - ( D. R; ]$ D) k/ q
复制代码 7 G5 F* g, d2 n5 d$ m
3 Z; \, I+ d; i; \: J: z |