不知道为为什么,STM32 LL库并没有FLASH的库函数,于是决定写一个- ~2 J& O! e$ B0 `. D$ P
0 B, D0 @, N! `, iLL库的特色,就是一个函数,只占用一个指令周期,比如,设置GPIO输出的状态,就是LL_GPIO_SetOutputPin();
* k2 [1 h: s' f* S7 f! C; P- __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) x5 {. ~1 R: h
- {
# I/ l6 N: K! e i0 T - WRITE_REG(GPIOx->BSRR, PinMask);6 H- i9 i8 A5 s; S4 v; S
- }
复制代码 于是我根据这种风格,已经常用的操作写了一个.h和.c文件
& T: T# D2 X! V: ^0 q O9 w5 \7 a, X) ~" p. v* m8 T
头文件代码
) e+ C& |7 Q) w! @( {+ h- #ifndef __STM32F0xx_LL_FLASH_EX_H
% Q, `% h. A/ i: [7 N3 K; I; ~3 K/ F - #define __STM32F0xx_LL_FLASH_EX_H
8 m1 D4 l8 r' {9 l2 C& ^6 ^ - - c h7 R6 Y; _& k
- #include "stm32f0xx.h"
: l8 P% D5 {9 ^# z/ U/ Q9 e1 b6 Z
" ?$ G6 M4 x3 s2 x s& q" l. _
! i* e* f% n+ S" h$ H- #define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */ 5 ^8 Q& M* W: R9 b* u% ]: k
- #define FLASH_FLAG_PGERR FLASH_SR_PGERR /*!< FLASH Programming error flag */
- C; X2 w7 I9 j, a+ r - #define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */
" v) S5 C1 V' z) d' C9 ^1 s - #define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */3 i! z3 |% Y* h- t P* \
9 ^. \6 k0 y6 z# ?- |- #define FLASH_TYPEERASE_PAGES FLASH_CR_PER /*!< FLASH_CR_PER */
% ~5 x" u$ q' e; v - #define FLASH_TYPEERASE_MASSERASE FLASH_CR_MER /*!< MASSERASE */0 V4 u( m* \+ x" ?
% ~; v' Z; O: f* u9 L1 K5 s' y- % b5 ]1 z' f7 v! `
- #if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \
t2 [' z9 h; m. n8 G - || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)3 L& M- S* s( ^
- #define FLASH_PAGE_SIZE 0x400U( H0 D: f# e! D, Q
- #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */4 v/ P# X2 \# B& o4 v
+ }3 ?" }6 c+ j; Y- #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \
! y* a; X3 f- j) N) P8 I8 j - || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
! k/ M. J4 |6 v+ \% E# m) r; W - #define FLASH_PAGE_SIZE 0x800U
- S' s; A- |+ _ N: ` - #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */
9 I* z0 S1 k. U8 q+ T6 i/ @ - # I$ X2 M% G4 E/ S2 R9 [: w
- typedef enum {7 `" J s% e. Z3 B/ U0 J$ `9 s
- ProgaraType_DATA64,
% I& h. a! x( Q+ B! K/ E - ProgaraType_DATA32,
$ `7 O) x! V) P" a; w5 Y - ProgaraType_DATA16
7 [& C g) j7 f' b) n+ n7 _ - }ProgaramDataType;2 K W. `2 S2 R! N2 P
' f) w3 L' y; m6 H' G. ~- typedef enum {\0 u. _3 ~* X+ L
- FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\* u) E& F0 j2 o6 c8 S/ \
- }FlashStates;8 d2 r. _* D& T4 |5 x; A
" g& k; W+ B' Z3 W) m! V1 @- /* Set the OBL_Launch bit to launch the option byte loading */( p3 z) A% z. V( S& V9 d
- __STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)" F; {* ]: C" m0 D& t! \
- {
- M3 @0 b4 X$ k3 A - SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);) z, Z0 R$ @" ]# A$ E* M
- }
5 w" R9 U" i- E5 { - __STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx)8 `1 A: ?" P/ Q
- {
1 Q6 t( \1 a! B - SET_BIT(FLASHx->CR, FLASH_CR_LOCK);9 p0 s6 c) b7 }2 I# Q
- }$ M l( M5 m& o' W4 ?
0 d7 M7 J# l- W( M, C
+ _3 q+ i9 h# V" G# R! r- /* @brief Set flash erase type.
9 V" B) u& ^# j: l z - * @param FLASH_TYPEERASE specifies the FLASH flags to clear.& L) \7 M% [7 N; X7 [( U
- * This parameter can be any combination of the following values:/ }: g, k8 w1 R$ y L9 Y
- * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase9 l# u9 e6 P# t$ S
- * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag 2 P8 u- o f2 [5 f% Z& R* L
- * @retval none*/
3 c1 k3 G! H/ G. `# v5 { - # U" J$ K( Y0 x! ^/ @9 h0 B
- __STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
% g, [+ n2 Y3 W; ^3 C - {
$ a# t/ _( g& Y* b4 o+ H# q - SET_BIT(FLASHx->CR, FLASH_TYPEERASE);: h4 E+ ]3 ^. F0 ]' N" b$ x
- }4 A+ z. `; k; l# Z" m" M
- /* @brief Set flash erase ADDR.% n3 Y; u4 L, A/ q6 E8 f0 `
- * This parameter can be any combination of the following values:
9 O, j: |# c& G3 M: P - * @arg @ref EraseADDR uint32_t value0 f ?" v6 y5 b8 D" X9 m
- * @retval none*/" o& L8 h1 j" x+ n9 }
- ! n( I( `. y$ X9 U1 J
- __STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR)( J- V9 i3 j4 ?# y+ h
- {
' z& a k# d7 _. q& [+ Z - WRITE_REG(FLASHx->AR, EraseADDR);
/ L* @/ D$ { a - }
/ `7 o" q T K - /* @brief Set flash erase ADDR.
9 H/ O% u8 u N! Z- G0 ^5 p7 K: |/ ` - * This parameter can be any combination of the following values:* U! N; B/ w1 e8 Q+ q$ ]% c2 W
- * @arg @ref EraseADDR uint32_t value
6 Y2 y, A, M# f/ {) x - * @retval none*/
! h/ h5 a% Z# Y+ V2 w' ^
# l3 U& |4 u- l8 f! M- __STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)/ h: q' o! P9 ?3 j2 r5 y; N
- {
4 h0 I$ e; H3 }0 G' \% o( Q - SET_BIT(FLASHx->CR, FLASH_CR_STRT);7 V/ W3 i2 I0 w) C# T2 P
- }
9 g! t e6 g. a! k/ s" w, g
0 B. V. e8 L0 q- /* @brief Clear the specified FLASH flag.
6 K4 d+ a1 n/ i; L2 y - * @param __FLAG__ specifies the FLASH flags to clear.$ U+ [" L: y& w8 N$ V
- * This parameter can be any combination of the following values:; e$ k% e3 S& c5 ~# A! V4 C
- * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag
& S) Z1 B( @+ M3 {3 g - * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag
1 m b( c: Q) J4 q - * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
* f. r1 Y$ s( V - * @retval none*/
! t7 w9 U+ b% c& x- e, P - : ^0 w2 C! n; f7 c1 l1 W W% |
- __STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG)0 X1 h- R d+ y* V9 O
- {
( b9 C" F$ G: {) L( W - WRITE_REG(FLASHx->SR, STATE_FLAG);0 ]7 N$ M. d7 B4 l5 R/ `+ s
- }0 S! D4 Y% U( v6 C6 s$ {% G
! A+ \/ ?: {/ ?. L# o! \% w) t2 y, A7 W- /*get bit flash bsy*/+ V/ I& v' c) _: @. e e
- __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)
4 F/ M, x' w) r0 j" }2 Q - {8 T! V) i5 H* y$ r- M, g( w
- return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));) b( A3 z% A) ?/ x, ~! F
- }8 Z0 u% h0 w7 n$ q8 s1 ~: o" `
- /*get end of operation bilt*/
' \: V7 N$ i+ G- r- L - __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx). M0 w* i$ ?8 v1 r7 I- h
- {' P) }/ N' [, Z0 T0 K; }. A7 @
- return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));8 L+ \' \5 m3 ` L* ?. e0 O
- }/ U4 }, [$ _% o0 m! j
- /*clear end of operation bilt*/2 n1 h, `. ?7 K. o2 H; s
- __STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx)
6 C# V) M- i! L3 N3 \+ l' c. x - {
. n! v+ k- n& B* K: m- F* z3 S - SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear" b: A* S( P( B' O2 I( }$ n" ~: ~4 _9 X
- }
1 i$ a% Z3 U3 d6 x, e1 u - /* @brief Set flash erase type.
0 ]* [& t9 b8 q) ]! A - * @param FLASH_TYPEERASE specifies the FLASH flags to clear.
& \2 S, {9 B- k6 f2 |; b - * This parameter can be any combination of the following values:
$ {/ z/ o. j7 G - * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase
: c, Q# Z% {9 A - * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag / a9 u# O4 R% X0 B2 U
- * @retval none*/
% B/ x' E( Q, J - __STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
( }6 C# h- I& w Y. P8 W1 ? - {. A# L: s2 S) M
- CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);5 m7 r* y' r" s5 ]& z% \7 V" ?* t8 f
- }
9 p( _3 J" k9 n+ { - 4 A/ v6 f& U( s! N; ]
- /*EnableProgram*/5 c1 d# I% i8 o, _4 O \4 n
- __STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)
+ c7 k9 V: |% ^+ S8 [7 [ - {
6 n9 c% j# L' f6 I - SET_BIT(FLASHx->CR,FLASH_CR_PG);1 v0 J! O" H$ Q2 p7 z8 _: q
- }! t- P ?- e! d
- /*DisenableProgram*/" Y3 M8 K3 D- q {; U- e) A! h
- __STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx)* H8 d6 p2 a: B
- {
; Y8 j( y6 ~- m G - CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);4 C6 K9 K: c4 Y' f
- }9 `2 y: r, Q$ ~/ z" o
- /*read flash's states of lock or unlock*/
# [3 N% z9 m) \# Y5 F - __STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx)2 Z# u. a& l8 G
- {
i* n+ Q/ f: t5 ? - return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));7 h* |! F/ d% Y1 M! r
- }
5 c( c' n$ a7 S! n8 y5 d7 a4 ^ - /*set key for flash*/
% P9 }: G. A% K7 t - __STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key): |" T# F+ d' X; P) A: B0 _
- {+ [7 U7 Q; C8 T' z1 K
- WRITE_REG(FLASH->KEYR,key);: A" v, D9 I: I3 ]
- }
3 a1 k5 ?. h; M. L9 y
2 }. y% h* S. r: z4 c3 a! \- 7 u3 |- \' A' y- I0 R* o
- LL_StatusTypeDef LL_Flash_Unlock(void);
% ]6 w( j" X5 Q - LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);1 x( Q- ]# W7 w2 {+ p
- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data); |7 f& f& S# Y e& b
- #endif
复制代码
5 |- i: M7 J) z V, l& mC文件代码
% r) l: `/ w6 B% z0 ~- #include "stm32f0xx_ll_flash_ex.h"" _- I" h9 ?( Z/ s; U
. e4 q' R+ w1 l3 ^- . u1 [4 M- D: [5 }9 X6 f/ W
- void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data)
/ w) y& S: M7 i - {
' f, I2 m0 l( ^ - LL_FLASH_EnableProgram(FLASH);/ v `2 d; S7 f1 L7 C
- *(__IO uint16_t*)(flash_addr) = data;
2 w9 Q& e! p, k/ I1 l2 N% t - }" W. `- L$ t6 k3 Q+ U
x' m9 x4 D2 v; h- LL_StatusTypeDef LL_Flash_Unlock(void)! `+ e+ T0 G& l( C7 i
- {
. q/ P6 O# g% J6 l) Y l+ m - while (LL_FLASH_IsActiveFlag_BSY(FLASH))
) ]- O* @1 B5 j5 w" l - {
. t; ^8 _- j- ^9 n/ R1 V) Q - }
6 T- G* \" S2 W, x# Z" w* D - if (LL_FLASH_LockState(FLASH))
# {2 Q: C3 R% I" O3 @' g; Y: C' p v - {
% t! A4 o8 {9 F: h$ \% y2 i. F - LL_FLASh_SetKey(FLASH,FLASH_KEY1);
7 M4 `- e# B s# K - LL_FLASh_SetKey(FLASH,FLASH_KEY2);
1 t8 H( E; c1 X5 W0 O. e - }- j7 G v, C4 b5 E+ t( e, T9 A
- return LL_OK;
% z% z7 p& {; S7 q; H. H0 k - }4 N2 i- X) Q" G8 k7 c) z
- % q6 }6 [0 `5 D! N( p
- LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)
R* t2 p! e" @. S3 l# v$ j - {5 Q9 k; U; z! W' z
- uint32_t End_addr = 10* FLASH_PAGE_SIZE +page_addr;
+ a& L% D7 h: l+ |0 s2 E: ~1 c - uint32_t Start_addr = page_addr;" j$ T& |; P G' X4 A" I8 @5 z. {, T; @
- for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE))# [; d# U" n- f6 j7 g
- {
: o' `& p4 K% k$ C" o& k8 @ - LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);
( O. ^8 ^, r4 S1 }: W3 ~, p( I* x- b - LL_FLASH_SetEraseADDR(FLASH,Start_addr);
4 e7 C2 ^+ }/ z8 g$ b" m - LL_FLASH_StartErase(FLASH); & H0 f+ D5 ]9 x
- while (LL_FLASH_IsActiveFlag_BSY(FLASH)) 9 L, X$ B1 q% {, d+ C
- { + @. [4 @7 P w% Z3 F5 a
- } , p$ Y0 Q5 R" z( w* g
- if (LL_FLASH_IsActiveFlag_EOP(FLASH))
. O% ]) S. f2 ~ - {
1 H8 V0 x+ W) f; ^0 A2 A - LL_FLASH_ClearFlag_EOP(FLASH);;
# Z6 B& n" |* Z' F - }
1 p3 m. W' g3 C0 O" {+ Q - else
& q+ g2 |; E* Z/ Z6 S - { " Y- b' R4 V/ I* f- O. p/ U$ T8 {- l) f
- return LL_ERROR;* D& y( r; e. w; ]/ K& y
- }
, k- R/ u" o% M/ c0 B6 K - LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);, @1 R v. S: Q7 R9 g- X% ~
- }
8 e6 l# k' R! V: v7 e - return LL_OK;
" r4 T" v7 M }$ j9 n7 ~ - }
; }2 q# t- ]( ^8 C# J
) b1 c2 d# D: P5 A: l- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data)
) j, ^8 N: G7 D8 I - {9 q2 f" c3 E) e: J
-
( N) v# F. U8 V- y7 w$ z+ ~ - uint8_t index = 0U;# J8 e/ U r# P6 R
- uint8_t nbiterations = 0U;5 M; Y% C, z$ x6 t9 h
-
5 _0 @* t; f) `) z& Y7 G! w - if(ProgramType == ProgaraType_DATA16)
5 Z0 B9 T, w: G G2 I' v - nbiterations = 1U;1 i/ q% s! j. h, a6 y
- else if(ProgramType == ProgaraType_DATA32)
4 I! N7 V. R" F1 F0 ?7 p3 } - nbiterations = 2U;. U5 J8 ]5 ^+ u& b
- else
, i) g K% i2 R: J5 r) y( ]6 ] - nbiterations = 4U;, u3 n0 i4 x0 N, j' u
- for(index = 0U; index < nbiterations; index++)
& r% F+ o Q! p6 @- p6 l9 s) d - {, x- K* x4 n2 _: `4 m* ?7 O5 R
- LL_FLASH_Program_TwoBtye((flash_addr + (2U*index)), (uint16_t)(data >> (16U*index)));2 V) t6 W( J: _7 ]2 m7 g9 J
- }
9 h. p0 F: h' D# A' U3 @; @6 F - 2 t6 o, Q9 q* w Y
- while (LL_FLASH_IsActiveFlag_BSY(FLASH))
" r4 n# j3 a7 P& E+ A/ H% \ - {4 C: T5 _7 Q- w/ u W9 |" s; H) i4 i
- }6 i: D! R/ {) U; y
- if (LL_FLASH_IsActiveFlag_EOP(FLASH)) + R, y% ], M$ w6 y1 b3 ?
- {& e. S& J* X7 d. x% w N0 q& H
- LL_FLASH_ClearFlag_EOP(FLASH);
6 S+ k6 D+ \4 c1 _4 A. J, j- _. ]( s: u - }
) }- M% s# v! e; E9 b - else# Q J$ N& }3 F7 l, s( `# w
- {
( k% ]( {# W, Q6 H3 Q5 r - return LL_ERROR;
7 V. |& g# ?. Z1 `) a - }
2 g8 r9 I- o _6 J/ C - LL_FLASH_DisenableProgram(FLASH);" g# ]8 `& \- m, r* s6 A
- return LL_OK;- n, U( S0 A* }. s7 A6 Q* J
- }6 z, ^! s) L( Y' Y
复制代码 & Y7 Y: m4 ~4 [. K( v* i
% c' h- G1 C0 i* |3 v
|