不知道为为什么,STM32 LL库并没有FLASH的库函数,于是决定写一个
8 X8 @# N" q1 J7 Y8 A! N- z# @" Q) z: o+ w
LL库的特色,就是一个函数,只占用一个指令周期,比如,设置GPIO输出的状态,就是LL_GPIO_SetOutputPin();
6 w' R* H1 A5 F: g, f- __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)/ d& P: X2 l* L5 g4 x7 V5 s3 @, j
- {! M' |2 h2 X! w( w
- WRITE_REG(GPIOx->BSRR, PinMask);; Y3 {( w% \% P) p* U) |' l
- }
复制代码 于是我根据这种风格,已经常用的操作写了一个.h和.c文件! F. D! x8 r; {' d
% K' L9 T( _& W4 t; _7 \8 ~头文件代码) b; P, V. `# d c1 P
- #ifndef __STM32F0xx_LL_FLASH_EX_H
8 |* h$ [! r6 L2 B- ] - #define __STM32F0xx_LL_FLASH_EX_H. n# l- b3 ~5 z( K. L
h$ T2 W6 j% ?# h6 [/ _- #include "stm32f0xx.h"
9 d, e# l2 U: ~ - $ Y7 F; b2 ^) |1 T
# {& W( C3 m& a- E& O6 w8 ]- #define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */
! V% e5 o& l9 S; M - #define FLASH_FLAG_PGERR FLASH_SR_PGERR /*!< FLASH Programming error flag */4 |4 \* W& j: X Q C
- #define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */8 q3 @1 H6 A- I- ~1 e. r- |
- #define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */) V7 o# A" P R7 |/ Y; f5 t, d
- ! q7 \. w8 C1 R) z3 I+ s$ s
- #define FLASH_TYPEERASE_PAGES FLASH_CR_PER /*!< FLASH_CR_PER */1 r1 c# V6 B: G- V; t: h
- #define FLASH_TYPEERASE_MASSERASE FLASH_CR_MER /*!< MASSERASE */
h8 P0 d' Z4 y. B4 j
$ l+ Q# W7 z' C w
, J {9 v+ l% R9 J% C7 p; ]- #if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \: ?* e5 ~" N7 M# e4 G7 d: ]
- || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)! |$ g. Z4 U5 [
- #define FLASH_PAGE_SIZE 0x400U1 h. p7 E; D% G: b( k3 N: B
- #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */
8 z" O! G4 D8 x- a# a+ v
# h! ~" W$ ?) A2 l3 N- #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \' a+ j8 F& i% k
- || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
! E4 G# W2 |+ J - #define FLASH_PAGE_SIZE 0x800U
' C" I6 M" S: Y$ C$ x1 x Y- S9 _9 R7 k+ O - #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */
5 Y* g( ]! O- f/ K
9 U8 `7 a, u) I. | r- typedef enum {
+ H8 i W; y4 I1 ]' d - ProgaraType_DATA64,8 y/ ]9 _ W2 U/ B
- ProgaraType_DATA32,
# z4 L: ~$ m0 o& T8 p - ProgaraType_DATA165 m$ S" F# L/ a/ l0 b2 f5 I% b7 L
- }ProgaramDataType;( k/ Z) Y7 K9 ]! n& Z
- * X1 L. D+ e+ ^
- typedef enum {\
) D8 B9 u% @4 C' |$ D/ ~, J - FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\
5 X4 ^# n, |& ^1 k7 d$ w - }FlashStates;
/ F2 T7 Q& y3 S0 M' L# ~4 T/ v - 9 |5 s( j+ C8 P, e/ N4 x( O
- /* Set the OBL_Launch bit to launch the option byte loading */4 A+ N* k# I9 @: x1 D2 B1 L8 ?
- __STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)
: A [* @2 C" D& l - {4 v) @; J( a! E: E2 W. [
- SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);
( a! K" v- o$ \- k" u - }
" W1 M" U3 a/ K& W - __STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx); x8 c6 h7 }2 X, E! {
- {
9 d6 L" ]1 b: e3 Y$ E8 y - SET_BIT(FLASHx->CR, FLASH_CR_LOCK);
+ S/ S3 a# C2 L8 S: p% g - }
5 K+ |( `$ b' f0 x% W - " |5 w, F2 Y& [! C3 D
A1 M- R- `" T+ C7 p/ N- /* @brief Set flash erase type.& U) ^4 ^4 @0 U/ r" @- o
- * @param FLASH_TYPEERASE specifies the FLASH flags to clear.
; I% v; v9 k) C: F( j# A0 r - * This parameter can be any combination of the following values:, h' `' V" y" D: ?5 I8 z3 |
- * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase
/ t" ^( \/ m5 _- [ - * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag
' i$ M, |( o \; \# [1 z - * @retval none*/
4 [& b( c3 O! k' B - 2 d5 K+ s$ Y. x/ M' e& A" C/ ^
- __STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
: f" U3 H7 O) A L - {0 O2 `) \" s8 ? D' T* g
- SET_BIT(FLASHx->CR, FLASH_TYPEERASE);, c0 H: V N8 S% d: k+ z: f
- }
7 G7 q* l: C+ ~) o1 U* E: c5 b - /* @brief Set flash erase ADDR.. { b6 T# B( r8 ~% _/ Z
- * This parameter can be any combination of the following values:! [" E. i6 d! I5 B3 ~9 A* _
- * @arg @ref EraseADDR uint32_t value E4 O3 m" h% r
- * @retval none*/7 [$ X2 v5 |. p9 P% z a8 L" {
- ( F6 t3 i/ D0 }+ W5 D5 x
- __STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR)
3 r, M# x' y3 U# ?# D - {/ s* J: ?9 Y* W5 M
- WRITE_REG(FLASHx->AR, EraseADDR);% F3 P& L, X7 l0 ^+ v- ~
- }
1 [0 _: s7 j5 J - /* @brief Set flash erase ADDR.
6 `& S: _( G: l - * This parameter can be any combination of the following values:- D# I9 ]) I3 k$ y$ L7 v8 u
- * @arg @ref EraseADDR uint32_t value3 ]- y1 f7 R/ _: S' X1 f% m4 o
- * @retval none*/
) B9 [+ Y% A% E$ d& y
2 f8 Z, X) k) ^7 P- __STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)0 g" B* y0 ]1 Y d/ C) p
- {
/ c2 @- x3 t3 b4 `& d% F - SET_BIT(FLASHx->CR, FLASH_CR_STRT);5 Z& ?1 Z- S2 T" g7 ?4 a
- }
\2 o* W, Z) d4 H' B5 H! B
/ V8 T, x& d% c f6 ?- /* @brief Clear the specified FLASH flag.
9 x/ n8 [ C7 {4 l - * @param __FLAG__ specifies the FLASH flags to clear.- r7 _6 ^/ p. s
- * This parameter can be any combination of the following values:4 {' S* J7 }7 K5 x# o
- * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag
3 |% w1 s ~8 N/ v w8 ]8 D - * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag # ? X; z0 U' E" f/ e3 A6 m
- * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag5 H7 a/ c% T3 W
- * @retval none*/: c9 i" I+ N& o- R5 \% O& K
+ B- c6 }; t( F( E- __STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG)
. ~, @; e. Z3 m5 W u5 s - {. Y! D% e0 P: [ [/ K% r8 m7 S
- WRITE_REG(FLASHx->SR, STATE_FLAG);
- ]# F7 T+ o W& b6 k4 Z$ B _ - }6 K$ j8 z9 n; \; F& W) K
- , P3 ? \9 K. L. q3 S
- /*get bit flash bsy*/
: e3 n1 k4 p9 K' j- J - __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)
5 Q9 Z9 x9 u6 A6 ~* r& Z - {
6 \# E4 y3 M1 {) l - return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));: h) |* b7 L" H. w& m2 o* y
- }
' i& f/ ^# M" K/ R& ~6 L5 E - /*get end of operation bilt*/
/ W& [+ M. k. x - __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx)3 E2 N7 j- n2 s4 ?- n" h
- { U8 V! G( Z! P |! }7 j
- return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));
0 W0 I# `( x' `. s7 F A8 H - }6 B2 ~# g+ R) f
- /*clear end of operation bilt*/' f( g. _1 D/ l
- __STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx) I( Z( L9 P& Q/ F m- P9 h
- {) B" A; W1 M* t+ j6 n0 y& n! _) v7 @
- SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear
& h, ?/ g; N; X9 p$ r - }
; C3 |# y& ^2 Z+ B" G7 a' Z - /* @brief Set flash erase type./ A" }* r7 a% u/ q, j) M* p* W
- * @param FLASH_TYPEERASE specifies the FLASH flags to clear.
/ ]6 D. {' I& W D3 J - * This parameter can be any combination of the following values:
0 }& E( u" n4 s B9 v6 [/ r, E+ i - * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase
3 h" g, R; p) {$ x9 c" I* Q - * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag + ?, f9 P$ d1 M6 V) w+ u* m
- * @retval none*/* o/ \0 r6 a! y1 X1 o, F" F
- __STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
* A0 h/ Z) k: s% r- c - {
0 U$ B2 E+ S% T' u' s C; ?+ I - CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);/ Z) ]6 O0 c& A9 |% {" S* I
- }
* _, d0 R7 c3 [5 `+ P% j2 M
1 \5 {( Q& Y/ o4 } q- /*EnableProgram*/! a( W5 l/ `( h2 ~& [! j' J
- __STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)
R' s' I. J, F& a - {
9 V$ w# s. H4 M, P" ` - SET_BIT(FLASHx->CR,FLASH_CR_PG);( I4 }3 V! \6 y+ B
- }
1 a: [! x- h/ L# n - /*DisenableProgram*/
+ F" M d6 e! M9 } - __STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx). [! g# f! H0 j3 k+ `
- {
: @4 a% v* l1 R - CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);
8 H' Z9 T( Q, Z' k4 G7 ?3 a - }
! G1 n/ e7 r- \5 t) p - /*read flash's states of lock or unlock*/
. H/ Y! U2 D# q/ C8 w - __STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx) k# d9 n- g7 K" I# j! ?
- {. W" \& f$ k1 q: q
- return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));
5 f0 N( K3 n3 }2 |3 s! q) K+ Y - }
# ]4 O' D# P; T5 B& J, X1 n. N - /*set key for flash*/
7 r% D# k7 s0 G! G( j - __STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key)" I7 ~! D5 o* Y; e; i
- {
9 R- i/ K% C x - WRITE_REG(FLASH->KEYR,key);
1 i1 }5 R& U1 e4 Q C$ | - }
4 h, _9 C& N% Y7 W& g
" O/ L4 Q( A/ v! b# e& B) Y, v
/ }7 Y9 x s3 O$ I# Y- LL_StatusTypeDef LL_Flash_Unlock(void);
& j4 |. y w" J - LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);
8 `/ b0 R. }; {8 j" a& m2 v3 J/ \ - LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data);
9 R" {6 N! p' ?8 } - #endif
复制代码
( ^: n2 k) @; R0 dC文件代码1 U$ z8 Y- q+ `" p5 h
- #include "stm32f0xx_ll_flash_ex.h"
( `) F& X3 q. ^9 I - 3 p7 L2 A; | X3 D$ F
- 4 E! D# K0 j( M/ p. e% N5 m. V
- void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data)7 F% S. ? ]0 E. o
- {6 @4 S- Y( C; `6 g# D! E r. ]
- LL_FLASH_EnableProgram(FLASH);
& P F4 T$ x) f& n2 a# ~6 m/ T - *(__IO uint16_t*)(flash_addr) = data;/ j# [8 O* W* V5 A
- }+ w. u0 l2 G" f. W: P6 ^
2 A; `/ S7 r Y- LL_StatusTypeDef LL_Flash_Unlock(void)- i& o0 `# |! a% D. j7 A
- {5 f& M1 \ V. A- X3 f- B$ v
- while (LL_FLASH_IsActiveFlag_BSY(FLASH)) # i+ |' }" x: ?" n
- {
- d& Y W4 v: _) V3 \1 i - }
" M3 b! W% ?$ _! \2 \* B( t - if (LL_FLASH_LockState(FLASH))
# S/ r5 i1 E# F6 U0 c6 T* Y9 X - {
) I; t9 j6 S& Y" Y. U - LL_FLASh_SetKey(FLASH,FLASH_KEY1);0 l# `. P+ L1 L |
- LL_FLASh_SetKey(FLASH,FLASH_KEY2);, \2 t/ h' ~! J- }4 H4 H8 U9 S
- }7 g( V7 r: O1 @+ l
- return LL_OK;) P' P6 Q/ J# p; z( a, z7 F
- }
; U% `/ d, l/ x+ A2 |
) P+ {' W% b: r3 `- LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)' l7 t1 L' C& S! i1 ^
- {
7 b t1 V" X; [. N* P - uint32_t End_addr = 10* FLASH_PAGE_SIZE +page_addr;
9 e* J6 O$ O( D3 l/ `5 ` - uint32_t Start_addr = page_addr;- d. l+ j7 x6 k L5 q
- for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE)) S0 m8 d/ l) |9 ^: G! z
- {
3 J' W' Q% J' d' k- @. E7 A - LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);
- B5 p2 h5 A! I6 K4 p& | - LL_FLASH_SetEraseADDR(FLASH,Start_addr);
" ]1 M5 `+ T0 z) U, o( ]! ~ - LL_FLASH_StartErase(FLASH);
; {3 L: d% [' q& F3 b - while (LL_FLASH_IsActiveFlag_BSY(FLASH)) * i, K9 V4 Y0 X- |
- { / U4 i4 u( J' w8 a% y D; [
- }
$ g& \ `2 k0 x7 M; J - if (LL_FLASH_IsActiveFlag_EOP(FLASH))
1 _. |8 | T+ Y* e' g5 I2 w0 f/ n+ _ - { 7 }8 A( x0 |1 x1 b5 Z! o
- LL_FLASH_ClearFlag_EOP(FLASH);;
* Q! S% n7 y* c, B - } 9 ?- U' @0 Z5 m
- else
, m/ i8 g$ y# y" i# E; W - { ) Y6 p( R; B/ ?' U
- return LL_ERROR;0 ?" H* {! V/ `6 y1 F) h
- }3 S/ g, v$ ?+ h5 }3 s
- LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);! i, Q) l, v5 d+ _ M. `
- }
9 t+ u" M- H( U+ \. {9 g1 p: X* G2 R - return LL_OK;& _, w% d2 @4 x7 ]. y: `$ K' ^
- }, I% r8 M! Y+ r1 O J
# n$ ~# m# L5 h$ p! w7 x0 r6 D- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data)+ k# K' U+ ^+ k. r6 J0 \9 E# a+ ?9 \' p
- {
/ B- T' C9 u! U - 6 N3 B5 p% Y) v2 i: {+ j2 m
- uint8_t index = 0U;# V/ y$ K3 J y& s
- uint8_t nbiterations = 0U;4 ?2 h6 c8 E3 d2 z' N
-
8 l Q: G9 P/ r/ t2 G - if(ProgramType == ProgaraType_DATA16)4 }( e! v9 j, j8 i* x
- nbiterations = 1U;2 `' F' |$ R+ c) J
- else if(ProgramType == ProgaraType_DATA32)
. A1 a# z5 o/ {6 [8 {' N - nbiterations = 2U;
; _/ v1 w3 f/ c! D. R - else6 q* w- N O& D3 F {0 u
- nbiterations = 4U;
$ B6 {# P/ b) u% C$ ] L - for(index = 0U; index < nbiterations; index++)9 |+ }/ k' A! |% r# D
- {8 y5 K( A. u0 c) w$ f/ D
- LL_FLASH_Program_TwoBtye((flash_addr + (2U*index)), (uint16_t)(data >> (16U*index)));
7 Q. B# n% D- w3 v6 | | - }- G6 t9 a' O6 l
-
4 M" i( R3 e" t1 s+ F4 d - while (LL_FLASH_IsActiveFlag_BSY(FLASH))
# q K! _+ O$ C$ l$ {3 M - {
$ F- U1 ]: Z0 a+ O3 S* o. O$ s - }
/ M, @& W! Y- M - if (LL_FLASH_IsActiveFlag_EOP(FLASH)) ) R; h- ?; }- M, e# N- `3 @
- {3 ^- E( ]2 t+ E* |
- LL_FLASH_ClearFlag_EOP(FLASH);) Z3 N6 J; J( |. j* f# Z
- }' e. {) ^, b! Y& o0 B9 g; H
- else5 H9 o) ]9 c" E% O' F3 ?8 D U+ _
- {" Z& u9 ^9 t8 G6 Z& d& D$ w. M
- return LL_ERROR;9 D$ K w, Y: z. i! q4 _
- } l v9 h5 a8 Y
- LL_FLASH_DisenableProgram(FLASH);
5 I) a( D% @3 S# i. n - return LL_OK;) v d# U+ [: R6 z* K0 _# k' R
- }0 }2 j" V/ l* u! R
复制代码
) ~0 L) _ ] F5 c8 D$ o1 a& r$ M% x/ ^" a+ [" |
|