不知道为为什么,STM32 LL库并没有FLASH的库函数,于是决定写一个
& }+ }6 W+ L8 \& g# {
- e; `& \% g7 e5 @2 O2 TLL库的特色,就是一个函数,只占用一个指令周期,比如,设置GPIO输出的状态,就是LL_GPIO_SetOutputPin();
- y; i; U1 W- Y# q& ]4 S8 p2 d- __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
2 p1 j+ t8 m/ P - {& a( b& G+ Z* ~+ e# X3 D! ^
- WRITE_REG(GPIOx->BSRR, PinMask);
. M7 w. L* r; a4 w2 l - }
复制代码 于是我根据这种风格,已经常用的操作写了一个.h和.c文件7 ?2 L6 s0 M+ G( J% C
0 ]* m. A7 b* t9 N" c3 K
头文件代码
0 Z2 g! k5 p6 C: v- #ifndef __STM32F0xx_LL_FLASH_EX_H
8 M3 P( f+ h+ L+ c - #define __STM32F0xx_LL_FLASH_EX_H4 y5 A% b7 x9 \3 D( [: E' P
2 l! L6 L2 [8 F* J S0 m- #include "stm32f0xx.h"
6 x. w3 \: {0 T; S
9 p+ s7 r& i6 k0 J3 h
l! U4 \& w3 y/ p) Z2 \5 o- #define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */ 4 P, p8 }3 f& H: X4 c
- #define FLASH_FLAG_PGERR FLASH_SR_PGERR /*!< FLASH Programming error flag */
9 O- u6 j5 \+ Y, x s( l - #define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */& f5 ]6 r& X* P- J0 Q# v) e$ e i3 ^6 N
- #define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */
" _: O2 w% ~( E6 H! ]
8 @. z3 }' ] K- #define FLASH_TYPEERASE_PAGES FLASH_CR_PER /*!< FLASH_CR_PER */5 I: H( |8 l" [9 Y$ Z6 E* n
- #define FLASH_TYPEERASE_MASSERASE FLASH_CR_MER /*!< MASSERASE */) Q3 { q8 [5 ?$ Q
, e; |8 M' L( o/ h' p. b
0 X* M+ N3 ]* A/ m, @- #if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \; e5 R7 ], }2 @9 a% a
- || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)* W9 }; U& R2 n4 J, x& D- L% @6 L
- #define FLASH_PAGE_SIZE 0x400U6 Y0 _3 J& q, {1 Y3 S2 z; \
- #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */0 u- a& e( o$ R& p' [
- ; s7 }7 Z3 _. V" A
- #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \
_- e; f5 b* T( x - || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)/ s1 z6 A6 s* { R2 P2 j/ D1 e6 _
- #define FLASH_PAGE_SIZE 0x800U
$ r% ~: m7 f' A# A, w - #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */
" q, r. { M7 V& x, N6 U- q
0 L8 p' ]: s) i% N7 V t- typedef enum {: Y8 q2 z. G# l& J5 T2 j! H W7 V
- ProgaraType_DATA64,
# F* I. q; X6 }. T3 X - ProgaraType_DATA32,
9 N9 Z& `/ t7 U; `9 X0 I5 H - ProgaraType_DATA16
) ~" K% x* M. h4 ?/ e% |# r - }ProgaramDataType;( {" Z9 Y* I4 O1 m W
- $ S; Q, R; X) k2 v
- typedef enum {\
& S a- ^) M% l! H - FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\
r; _) B# Q( o9 `: }1 C) P% S0 ? - }FlashStates;( T. K3 U j, Y" B
$ C ]0 n+ g; B% W" E# w6 m, ?- /* Set the OBL_Launch bit to launch the option byte loading */' b$ ^% s$ h0 a; J! t- u
- __STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)' a: T+ Z8 i( x$ ]) I
- {
9 C! _/ e& ^- D - SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);
1 q" [: s" g$ J- x1 Q - } R* r3 R: z i1 d( c
- __STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx)6 p1 w0 {( o2 n0 O! @, u
- {
* a* c+ G/ I- w* R - SET_BIT(FLASHx->CR, FLASH_CR_LOCK);/ e- h1 W: Q/ i& P: M
- }
+ L; c( h& O4 S7 d, V
% k1 a9 E& Q7 E; ~- E! s- e- 0 R% x9 \' r0 P/ d( v, X
- /* @brief Set flash erase type.1 @& x" m- O; q3 K
- * @param FLASH_TYPEERASE specifies the FLASH flags to clear.1 o+ t% h- n" P8 [" k( i
- * This parameter can be any combination of the following values:; K7 P- ]: x x7 @0 s
- * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase$ j3 s( w7 @% a5 A: f3 ~$ @" \
- * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag
; J( K$ W3 Y. d' ?- L; D - * @retval none*/
) Z1 d6 r& I$ f" } E% k! D
: v h+ O& ]. }; V- __STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)+ v. W' r7 M4 r1 H8 \) M' \$ j, {
- {
, Y9 P; F/ j! M6 j, [ - SET_BIT(FLASHx->CR, FLASH_TYPEERASE);0 {) @- F! k& w
- }
4 h, F u+ z- J9 B0 Y( l6 q - /* @brief Set flash erase ADDR.
0 A c$ A: P. F& j - * This parameter can be any combination of the following values:
- g0 z0 t7 l/ w3 \6 O; j) v. D- ~ - * @arg @ref EraseADDR uint32_t value7 y' |8 H0 _: D2 p9 Z8 S0 `2 i
- * @retval none*/! a* U( @0 r+ O( u9 Q2 T- @
+ S2 b5 W0 g8 M4 c- __STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR); P' a' r# w6 f1 Q2 O
- {: A. r: I: N9 s+ D" \7 l: p( g
- WRITE_REG(FLASHx->AR, EraseADDR);
* _; L% r c/ {" ^ - } j# \5 c- x' _% Z9 i( ?4 M
- /* @brief Set flash erase ADDR.
% V. x( N! [, t1 p" |( L - * This parameter can be any combination of the following values:; e ]/ Q/ _* T e
- * @arg @ref EraseADDR uint32_t value
, M8 o$ `8 I1 W1 V5 P: J4 I - * @retval none*/8 w4 B. M7 `( H" G; R
& ?( k7 w, n# ~1 B( N6 O- __STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)
0 n' l) z" F2 p W+ ^$ a0 R - {
3 Y* S+ g% h; [$ ^/ B3 s - SET_BIT(FLASHx->CR, FLASH_CR_STRT);' z( G2 @5 U G% C& o9 j
- }
K/ _0 Z, t% J9 N1 a6 h A
4 c1 o, Y1 K& T* n( x& b( ?- /* @brief Clear the specified FLASH flag.- G8 V0 K- E) K
- * @param __FLAG__ specifies the FLASH flags to clear., b# J# n0 t" e. o4 x5 B3 Y9 h
- * This parameter can be any combination of the following values:0 q) E$ m8 ~& j+ m! p
- * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag + _( S/ N; y6 J
- * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag 4 k4 _4 j; \. L; h7 z0 f- {7 K
- * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
5 @1 g! D2 y) C, B - * @retval none*/- l" R9 u2 B! Y! s" L
" f9 B$ h6 O/ j- __STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG)! m4 a& t4 E! a* f
- {) J! L/ s1 T* A2 J
- WRITE_REG(FLASHx->SR, STATE_FLAG);
/ `& r/ \! B+ x5 r* Q4 g% T* | - }. b8 ~' ^3 W+ W7 t4 K" b9 i
- [3 D! ]) J& B( P {# M
- /*get bit flash bsy*/
+ r. v* J1 L7 t9 M+ @* l2 j - __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)3 w; `6 l. F* ^& i
- {
7 Y8 }5 n6 w+ A V: Y# G# H - return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));
8 g& _; A7 v0 ~# e! K- g* { - }) m: h; Y7 D" F G$ c6 o) x' K
- /*get end of operation bilt*/$ Y# K+ t) R7 t, G1 _
- __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx)
9 P* s2 _) C4 G- K C! X3 R1 W; F - {
# p7 {9 a( i) b: p8 u# F R - return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));; n d1 m' q# A( b- R# x
- }" R2 f/ z0 ~3 w( r) @9 x; N6 a
- /*clear end of operation bilt*/
2 D5 e/ P# E6 N7 t4 U" v - __STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx)
& Y+ u" \ z5 U0 j& B5 t& J3 C - {- v1 M7 W+ A+ n6 }
- SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear, e; V1 k( K9 t$ w7 Q" k
- }
. N: `0 i$ `( a6 r! b( ~) B; ? - /* @brief Set flash erase type.* }& ?1 v6 p: T M/ E w
- * @param FLASH_TYPEERASE specifies the FLASH flags to clear.) Q- x5 w# z% }
- * This parameter can be any combination of the following values:
; ^# G. |" v& F6 e4 q) R; T - * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase/ M ?3 S& b( D) c1 |* q
- * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag
8 q5 b; g+ [2 I8 J$ R - * @retval none*// n+ [6 j6 E) Q3 t: Q, n
- __STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
* v! W( _8 Z; \9 F - {
* ]1 D ~4 Q. h- Z - CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);: E7 u) |4 S x* ]+ c; X6 r& |* c
- }
6 |3 W5 m) J+ j9 e7 \" y5 a3 Z
9 \0 Q3 @7 B' o- /*EnableProgram*/
( }/ v( p' J- s/ I6 } - __STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)* b% y6 _' {: m+ F
- {
, W& ?0 Z8 K1 p$ P+ \0 E - SET_BIT(FLASHx->CR,FLASH_CR_PG);
: q& q4 f( c' J" y - }
# g" o- s5 M% {8 k% R0 `0 x/ j - /*DisenableProgram*/
" {- e& W- d* N+ L$ w5 w# Q1 P - __STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx)
1 l% J+ W$ j; j - {8 W) y+ |+ C5 i; M0 N& @3 ?& M1 ]
- CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);
$ s% B; V9 K4 L, h8 K% O - }, g6 h8 L5 L. w7 W. J
- /*read flash's states of lock or unlock*/3 d z! y5 I) g- h u5 O0 e
- __STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx)
7 f, n6 E( N% D! r- I - { s3 T$ O2 W( N5 v+ r: A1 `7 t
- return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));- F6 H8 b8 n) b7 m
- }/ V6 d: L! m5 {6 p
- /*set key for flash*/+ V9 t0 D6 @3 X: W! X
- __STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key)
/ S; |$ s7 a) R1 v - {. ~1 N* r$ p7 y8 D' `5 _' H
- WRITE_REG(FLASH->KEYR,key);
* z, w0 r1 G$ c. s5 h t' u - }
( X* ^0 l2 [0 G% m1 ?
" `3 t) D+ y: \4 F6 q: Z$ S
8 q3 q& C( G3 f/ l5 b7 J* L- LL_StatusTypeDef LL_Flash_Unlock(void);* g) s) E1 s6 J- v9 L% ]' E
- LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);3 y, m! i2 e w/ [
- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data);+ J+ z E; O( m" Y- `
- #endif
复制代码
7 m6 N& \/ T: A3 W# r: ~C文件代码
( {: Y6 H) m2 A1 N/ ?8 ~- #include "stm32f0xx_ll_flash_ex.h"
~; ~- H& e- a. @5 G - ( \' d" V% C0 S0 C6 `7 {% {
- & {. Y& {1 {; T2 f" `; {
- void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data) ]+ \+ K2 ]5 D$ e% ^6 f
- {6 e( n; m$ C$ a: I% ]* ~2 F; U
- LL_FLASH_EnableProgram(FLASH);
6 f2 T; \' s& k0 I" F6 b. W - *(__IO uint16_t*)(flash_addr) = data;0 ?" A/ B0 j0 U$ o* y( p, [
- }9 c8 l6 \6 b% G4 e
- " c5 n: S+ J2 v- Y# b3 d
- LL_StatusTypeDef LL_Flash_Unlock(void)
/ T j- T% Z3 x- T: X: G& M! }4 L- g - {
8 l6 q/ W6 ^+ \$ J* L3 ]# B - while (LL_FLASH_IsActiveFlag_BSY(FLASH))
2 U: _ ?0 b# C - {0 V. p, z- U% X2 P9 B
- } ' g* P( x4 ~# r& s$ ]8 _& w
- if (LL_FLASH_LockState(FLASH)) - n0 |9 @; J- d5 D
- { - D9 @5 M$ J" k" u! ]: D: n
- LL_FLASh_SetKey(FLASH,FLASH_KEY1);
1 K( k+ W. x# I% z+ q - LL_FLASh_SetKey(FLASH,FLASH_KEY2);
, _+ {& D/ w) T+ `* A$ b$ O3 F; M - }; ?& Z4 J9 K* r! W/ k
- return LL_OK;0 k, @# U: q* U- m
- }' b0 P, |5 ^- e. ^) K7 \
- : G9 Z" g4 V+ p5 H6 K. B2 b. R
- LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)( Q0 ^% j- X# y
- {6 q& V. _6 p, ?, _8 L4 L
- uint32_t End_addr = 10* FLASH_PAGE_SIZE +page_addr;
+ ?- l% h6 Z6 b4 S/ ]5 W - uint32_t Start_addr = page_addr;% R8 k& B8 y+ ^
- for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE))0 R/ {9 e% d) b; R
- {% ]1 p% m X7 W6 V
- LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);
. ]* {' X E, s, t7 g8 i - LL_FLASH_SetEraseADDR(FLASH,Start_addr);) [+ ~, T& `6 f# H% X& x* \5 k
- LL_FLASH_StartErase(FLASH); + z5 H0 j9 ?# c7 J: I
- while (LL_FLASH_IsActiveFlag_BSY(FLASH)) " i8 j1 t" I; F0 ?# \8 c' o! s
- { / o" n% l) |& I# u
- }
3 q9 O" j0 h. e/ c - if (LL_FLASH_IsActiveFlag_EOP(FLASH))
( V. P6 L0 k# p- D$ S* { - {
- u. C6 o: W8 O! \1 s4 O8 r - LL_FLASH_ClearFlag_EOP(FLASH);;
: y" k" G) U4 r, M/ Q - }
. r. a# j) C" }% q4 u& s0 X4 n - else
, P7 S5 y% s0 e" b. _( \2 F. `+ C - { ! V5 x; [. S9 S* g6 I% d W( x: w
- return LL_ERROR;/ L0 b7 n& c* m; d( l0 Z
- }
# F; \, p G& X - LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);
- z4 o! _9 r' G" ]$ a+ o - }
2 Q9 g* ]3 a3 X/ w n5 o+ F- \ - return LL_OK;) P% q+ Y+ @+ P+ Z
- }* u, i, P0 N. s' O9 n. k t
9 v9 B5 o, [' P7 w4 U4 d- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data): a0 o# b8 {7 Q- ~" ]$ Z* U, b8 A
- {
0 `2 V7 t* \0 j8 M; l% o) A: U -
% m7 U3 s$ T! \: ^: E7 [+ y; y - uint8_t index = 0U;, d& ~6 o6 s, U; D7 u$ ~* q
- uint8_t nbiterations = 0U;% \2 U" S/ x5 D8 Q0 M n/ ^" O
-
( a! ^- F2 [. N: \. S6 q8 l - if(ProgramType == ProgaraType_DATA16)* F$ s, G1 K0 ~" b- B
- nbiterations = 1U;
6 c* y( H- Q: m$ j T, X# E - else if(ProgramType == ProgaraType_DATA32)4 t) a' e7 q: e) j+ [+ Q
- nbiterations = 2U;4 p: a8 |5 _6 ^0 P" f; H% H% e0 x* @' g
- else0 s& E2 R- D9 x, L) W" z2 N7 q
- nbiterations = 4U;; r& p" i" k; z6 m
- for(index = 0U; index < nbiterations; index++) E4 ?/ j: J$ K. A
- {6 b$ s% J# `1 p* f A/ ]1 H
- LL_FLASH_Program_TwoBtye((flash_addr + (2U*index)), (uint16_t)(data >> (16U*index)));& S1 ?. g0 L5 ]0 x
- }
1 u1 W/ I2 m" E% M - 0 w( @# _3 M& X' q: R: e( X% b m
- while (LL_FLASH_IsActiveFlag_BSY(FLASH)) : L/ f7 T0 m& W* O5 }
- {" W3 L& U" B- d( X$ p: B
- }
( Z4 ]1 l+ ~3 [: m - if (LL_FLASH_IsActiveFlag_EOP(FLASH)) - @+ J- r4 b( K/ i) ~
- {9 e9 o/ v) u2 P* p; D; O n
- LL_FLASH_ClearFlag_EOP(FLASH);# R# P; P. N$ {; u- W
- }
4 e& e# Y0 {7 `" g. g, m+ ? - else s; `6 K1 i7 W8 y; f
- {! V' X2 H: \7 \. j
- return LL_ERROR;
2 G* @; o% E ^) t8 H; n - }! }" g2 O( H$ S
- LL_FLASH_DisenableProgram(FLASH);
9 E3 `: Q. \: J$ S* ` - return LL_OK;2 x; l0 G) U) }1 `
- }0 U" L* V& j% @0 M! l# o+ ]
复制代码
* S7 f+ K ]3 z* ~' D
- G3 a* ]5 [2 |/ [4 p |