不知道为为什么,STM32 LL库并没有FLASH的库函数,于是决定写一个7 T& u# h- }+ Z' u
3 L1 K a/ s" Q; Y/ {6 ]
LL库的特色,就是一个函数,只占用一个指令周期,比如,设置GPIO输出的状态,就是LL_GPIO_SetOutputPin();
, A" @: V+ h9 @; b8 v- __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask): m4 |7 ?3 y5 M. N
- {
2 ?" v0 E# B% I - WRITE_REG(GPIOx->BSRR, PinMask);) Z9 [ r9 D; H9 R0 j: C5 ]
- }
复制代码 于是我根据这种风格,已经常用的操作写了一个.h和.c文件
8 C s& \! Y6 G, V3 X
( K9 O& g6 U5 t T8 ^% O头文件代码
' S& X* g1 s0 D9 N, L- R: f; ], ~- #ifndef __STM32F0xx_LL_FLASH_EX_H' w2 ?; ?+ b4 y; _: Y: w
- #define __STM32F0xx_LL_FLASH_EX_H: \. u& V w. N
& C1 F5 V: N9 }- #include "stm32f0xx.h"+ y- b: F( O: P+ E3 {6 L
' k' P$ a$ F" V* ^) C3 V5 q- e; Z4 A. r# W& s; _+ C% O# A
- #define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */
9 c" l! p. X a0 Q( ?, _ - #define FLASH_FLAG_PGERR FLASH_SR_PGERR /*!< FLASH Programming error flag */
. |# ]3 S/ S; Y& K - #define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */
0 U. f6 {+ ?+ F4 M - #define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */5 b( G1 M! J- t2 t) d2 U: T
- {2 I# d/ r5 K1 I* y6 d- #define FLASH_TYPEERASE_PAGES FLASH_CR_PER /*!< FLASH_CR_PER */
+ F. y4 r @3 J# m+ Y/ J! M9 e4 i - #define FLASH_TYPEERASE_MASSERASE FLASH_CR_MER /*!< MASSERASE */
( I' u) l% m" i! \ I c/ ` - 8 O. }' t# w' I0 Q# v' Z
4 h5 ~0 i" t+ w& K- t1 Q9 M8 ~- #if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \& q5 u8 z* @+ [ C
- || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)
3 ~5 P0 [& q5 V" `% j3 d+ ~, g2 A z - #define FLASH_PAGE_SIZE 0x400U
( I; `: k1 \) M3 m3 V/ o - #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */
& N8 Z' v! y$ ^4 }/ t
# v# q4 ? l2 Q0 [0 j# u- #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \
! M z8 m5 g$ }7 M. ^ - || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)4 K! Y- v3 u$ d9 r6 u& ?6 G- c2 a2 Y# x
- #define FLASH_PAGE_SIZE 0x800U: W7 {: _8 T3 Q- o
- #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */; U: Q8 O% d' g9 m* `
5 L; i- V% c# T s1 p$ G- typedef enum {+ F3 w" k. _) i. h
- ProgaraType_DATA64,
3 J3 U% D" W, z. @! _% R! s. E: C' z - ProgaraType_DATA32,
3 d5 e% e- _' Z: ^ - ProgaraType_DATA16: Q+ C2 h- L. d* M. u
- }ProgaramDataType;9 U8 J' b' ~' }# R! x/ W7 U
$ R& k1 K6 ]: F2 P- typedef enum {\
9 U9 H. X k: Z' k - FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\
1 C' r9 J* T5 |9 y$ c - }FlashStates;
. e' P D8 t4 e: R3 }' M2 J
1 a) c7 R0 U& N- [: I% J( C y; Z5 r- /* Set the OBL_Launch bit to launch the option byte loading */
3 }. w" l" |- v8 _1 M* W - __STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)
5 q8 f0 V1 |9 J) f% B& Q1 B - {
0 E) K7 \3 _ c5 D/ H2 A6 W) f5 o - SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);5 N" w: D2 N) k
- }- B" [, S3 O. d+ N1 ^$ p4 b
- __STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx)
' ^; n+ [: L6 S0 ` - {/ A( |! M8 G! Z
- SET_BIT(FLASHx->CR, FLASH_CR_LOCK);
4 H" k0 _2 [. b0 v9 I1 R - }
4 N9 z% {- B9 q6 _" u3 w" g2 s - ' j, ?" B- h# n! s( r) z
- / Y/ }9 d! h+ [% v) h. F
- /* @brief Set flash erase type.- Y: h$ c1 g6 R$ Q, D' k" n2 G4 _
- * @param FLASH_TYPEERASE specifies the FLASH flags to clear.
# V& P$ N7 V- ]7 G( {! D - * This parameter can be any combination of the following values:
' {% a( ^1 O% ?% u2 v+ h3 Z - * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase
' Z1 ^2 }9 z1 {+ I6 d5 l - * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag
& R$ l+ K! n8 e# r U2 v# U c - * @retval none*/, \( ?- _, e6 H! v/ U
0 K5 C/ a/ T b) X2 ]- __STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)& o! `9 I3 q( r! A0 }+ x
- {
+ ^1 s& p& Y, u& L1 Y - SET_BIT(FLASHx->CR, FLASH_TYPEERASE);
4 f0 Z" J' R4 m( W* [; w8 z- D. E - }
! H# l0 r; C C+ S9 t - /* @brief Set flash erase ADDR.1 z7 J- |- s$ {* F8 S* J
- * This parameter can be any combination of the following values:1 _* K0 ~5 i) f- T( y% d& a% q
- * @arg @ref EraseADDR uint32_t value5 v A2 O9 V" }5 _! y2 c
- * @retval none*/
2 u, _8 f* j) r
5 B1 K2 \# ^6 g& O/ O- __STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR)8 Z B; s) h3 ^; r0 S
- {! A D3 U$ G2 p& m5 y/ \/ g* U
- WRITE_REG(FLASHx->AR, EraseADDR);
2 }: U& {9 n. H$ Y+ m, C - }! W& \( u9 Z( o( @
- /* @brief Set flash erase ADDR., l0 f$ c/ u H3 }8 x1 g) a
- * This parameter can be any combination of the following values:5 C) C; w( Q. K
- * @arg @ref EraseADDR uint32_t value
5 Q, f9 P& p, i, i) r$ K - * @retval none*/
" ]1 |1 m5 O8 E. M) q9 ^4 g - 5 c) y8 n- |& U4 L" ^& ~" X: O
- __STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)
3 U3 X) _9 j% K V6 Z+ q) } - {( ~' t6 }1 Q* [0 f% T7 N0 @# @7 C
- SET_BIT(FLASHx->CR, FLASH_CR_STRT);6 g0 Y9 w! E# G6 L/ X! Y' U- x/ M; j
- }
/ R' ~5 c4 B: ~8 T& J# {# Z - L3 |) w8 r/ n( I& p
- /* @brief Clear the specified FLASH flag.& [( Q& Y3 q4 g/ ~8 |" P% K
- * @param __FLAG__ specifies the FLASH flags to clear." h5 ?6 l. ?9 b
- * This parameter can be any combination of the following values:
# c' A9 ?# u4 v! H& |5 H - * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag " \0 O5 }2 t# A
- * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag
0 \3 b( S- P: S2 F' \ - * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
" T% J7 W! n1 j8 i! D* } - * @retval none*/1 x) R6 q5 e; T* n! X$ I
- , Z* T0 u# W( r
- __STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG) u1 k9 B4 W1 |. j( U3 ~
- {6 b; z; M! F- i. [+ \
- WRITE_REG(FLASHx->SR, STATE_FLAG);+ i% \2 K/ n; F* Y4 L2 F
- }$ R6 O' a9 j+ Y* y: K
- 7 D( c! a$ _' Y. H/ ]
- /*get bit flash bsy*/
t+ {" o7 ?' D3 R/ P# I$ U - __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)
* ~/ N; M# H% l - {
# M) w0 j+ o s - return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));
6 P7 A# b) P% x( R* z' @* u+ ]4 L - }+ m4 ]: f( [) V
- /*get end of operation bilt*/3 x3 |' x* t3 i
- __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx)
$ ^" N/ Y1 p; z% w! @" P l - {
1 ^9 M, V/ Q C# J - return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));7 E2 |$ ~0 {' G6 _8 R
- }
% A' O( ?2 Q4 {5 o% q4 D - /*clear end of operation bilt*/$ [( u- [$ J/ O% K
- __STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx)
" N" W2 n& z6 K: E9 F - {6 C# g" [- l# b7 o5 w& V
- SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear
) F& K# ^) k" r3 C - }- x) q' i/ |4 `# F. K6 z: g
- /* @brief Set flash erase type.
' C. ~" O, b) J$ ` - * @param FLASH_TYPEERASE specifies the FLASH flags to clear.
& B" g# O6 q$ K9 Z2 v% a - * This parameter can be any combination of the following values:& D+ t2 }- G1 F( Q) P1 C$ K
- * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase/ w# G( l* C" X
- * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag 9 g9 X/ N4 G g, j$ V
- * @retval none*/
) t2 z# b$ R% j8 {$ o/ M5 b( }- n - __STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
+ z! ]# n. I5 _) |. Y5 M - {8 H8 _+ M+ u" T0 s4 N, a
- CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);
+ v# C4 I/ K V6 a - }
* `% g+ Q; J `% h; s8 X4 V - ) ]( K0 B$ O, `# R
- /*EnableProgram*/0 p" {0 C7 f E8 J
- __STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)
5 ]9 p) s1 C0 s; _ - {
2 l. V i/ ~- T6 k( m8 m5 ~* k9 E - SET_BIT(FLASHx->CR,FLASH_CR_PG);1 f0 v# L* `) C9 A5 [
- }
5 l. D! X6 p! m& c9 U0 Q - /*DisenableProgram*/
7 o8 x2 X x0 e( ~& ]- O* J9 T - __STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx)2 Q( C9 ]+ Q. X( K3 A9 T, {
- {/ U2 P. R5 A6 t4 [4 m
- CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);: u1 c; o4 L( c) @+ _0 {& a9 I
- }" y5 w( J& J& s+ t4 J, D' Z
- /*read flash's states of lock or unlock*/
0 @- F0 q9 ?4 V# P, f* M - __STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx). |5 H% k6 s9 ^0 M
- {
9 f. ~0 Q# r6 I* S1 Y. ?2 `* | - return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));' c4 V X$ e2 c) D: t9 I
- }
) |. L) s1 x! H8 P6 C3 U* B. ~ - /*set key for flash*/
! K$ x! ]( e2 ^ - __STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key)# A/ t7 x% A3 A2 d
- {
& ` o6 R, L d% o( x& T - WRITE_REG(FLASH->KEYR,key);
1 z$ p# @/ \; b! A, Y% N - }
( t- F) E% ~. |, ? - 7 _$ C& T6 i u
& @/ O# X* @+ d3 C- LL_StatusTypeDef LL_Flash_Unlock(void);
4 r3 _' W$ i; }1 C - LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);% R m2 i" J. V/ m
- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data);
4 `% Z6 T8 h' \+ D0 X% k' n - #endif
复制代码
* s. D' ?) l% U, g( M" u* hC文件代码5 K( f2 q' o% [- W- }
- #include "stm32f0xx_ll_flash_ex.h"
1 n7 B( l1 K% W8 e3 I - v& m0 z6 P, R5 O$ D; D. m
$ b) H, A: U/ x% h4 j! x' z- void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data)/ G3 b0 S z) Q6 M4 A+ H. v
- {7 F0 f! {! X8 i, C
- LL_FLASH_EnableProgram(FLASH);
; H! |# e2 E7 w0 F* q- ~ - *(__IO uint16_t*)(flash_addr) = data;2 C' ?6 F1 @' m( e! |$ Q$ r/ a
- }* m1 {9 L7 z2 k* t4 M9 m
- 2 K% I! z- v s4 Q: i5 y$ i! F9 N
- LL_StatusTypeDef LL_Flash_Unlock(void)& A2 R! D, G7 L* E
- {
) }0 Y' R" F* T. e# Z4 h' J - while (LL_FLASH_IsActiveFlag_BSY(FLASH)) * R C2 z0 X, \4 \
- {4 F! T; L: M- p% B: v
- }
4 g7 v d; k( D; t6 r - if (LL_FLASH_LockState(FLASH)) 4 n# v$ p' e3 p5 F
- { ! ^ p' b2 h1 t1 Q5 @$ [+ o
- LL_FLASh_SetKey(FLASH,FLASH_KEY1);
; e* F. B- \6 [8 O7 S( d2 z - LL_FLASh_SetKey(FLASH,FLASH_KEY2);
2 k2 i, a1 [- j8 p; G: i - }
: u" p n( F7 w' }) S3 f4 l - return LL_OK;' V A; i; k/ r- P/ _' N2 a
- }
$ C$ l3 c1 |3 U9 ]
4 y7 X7 e( M" ?0 E$ L- LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)
9 Q! {5 {4 ?2 o; s4 |& S - {
% T2 J1 E5 T" p4 [) T - uint32_t End_addr = 10* FLASH_PAGE_SIZE +page_addr;' t3 s1 u6 n/ D! H- E
- uint32_t Start_addr = page_addr;. d7 @8 ?- \4 o( F2 H2 }
- for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE))) \3 v7 M% ]& b) G& r
- {9 x( G/ A5 Z. h9 Y
- LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);2 _2 o; I5 z& ?" r
- LL_FLASH_SetEraseADDR(FLASH,Start_addr);
3 R v+ U# o& G - LL_FLASH_StartErase(FLASH); 8 B2 E- y2 D$ E4 H& T/ ]& Z
- while (LL_FLASH_IsActiveFlag_BSY(FLASH)) + ^7 o% r8 X* w) m, c' q5 S( |1 ]
- { . ]5 ?/ ~$ h, z0 w2 a1 o0 ]
- } * _$ O* H0 _ \8 ?1 ~
- if (LL_FLASH_IsActiveFlag_EOP(FLASH))
4 k) q6 m5 r. K" o& { - { 9 i3 k+ T! |2 x
- LL_FLASH_ClearFlag_EOP(FLASH);;
8 W- [3 J$ r! V - }
7 j% D# z4 J2 D4 I9 l - else- E0 v: h( B; R# n* H I8 N& O% d
- { . Y6 j3 d; g+ M; F5 d; a
- return LL_ERROR;. W. |4 t$ h9 E' ^% U0 y% p
- }
& M: |% F1 y0 c2 Z - LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);
+ |2 P) O& r! t$ Y# r1 A - }
9 K. `5 [# I* B* f - return LL_OK;
' c5 @7 W: e( E5 x8 n+ M) K - }- z+ x" c5 j9 n5 ^( K
$ f) q1 D: }8 z! G. K0 h% @- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data): W( Q' ^7 g, G, `: c" ~
- {
& @" q) {; c0 Z9 @9 n - 5 V; {5 Q" H* U/ O
- uint8_t index = 0U;0 v$ k, I) g6 N* g, {
- uint8_t nbiterations = 0U;5 u6 W9 k; {9 M
-
- v- N4 t; }1 X% _ - if(ProgramType == ProgaraType_DATA16)0 q8 U& g/ C9 B6 D/ V6 {
- nbiterations = 1U;
5 J8 Q) r; d# T/ j* W' ?8 d( t - else if(ProgramType == ProgaraType_DATA32); w" s$ A5 p) ?/ h7 j
- nbiterations = 2U;
' ]) p" S0 i5 `8 S - else! n0 n8 e( i5 K/ ~6 J
- nbiterations = 4U;
! |; \1 `' T; f9 |! R8 T T - for(index = 0U; index < nbiterations; index++)
I) ^# D( L! e9 A: l' f - {. L- H" t: P' L# O) J+ r7 C
- LL_FLASH_Program_TwoBtye((flash_addr + (2U*index)), (uint16_t)(data >> (16U*index)));
l& l" t9 L/ b, S - }3 A( O1 d/ a5 H5 @; c
-
$ R# I/ T/ _2 T, c - while (LL_FLASH_IsActiveFlag_BSY(FLASH))
/ |0 p9 ]3 N' ?! y - {
| @% N# s, d+ B - }
. k: t* ~/ E" @" ~3 J - if (LL_FLASH_IsActiveFlag_EOP(FLASH))
: v& `: u4 D8 D2 a, [6 o1 h6 h - {
" F4 x2 }4 i5 w/ b( K; [ - LL_FLASH_ClearFlag_EOP(FLASH);
: e2 S( |7 Q6 L D% C1 w2 h - }) M8 l `2 |; s
- else9 [1 V, V$ |, }9 T/ ]
- {
) }! x" ~, C4 x* r - return LL_ERROR;3 k/ @, Y0 U3 H
- }3 p$ `2 O/ t/ Q
- LL_FLASH_DisenableProgram(FLASH);/ G R% I$ I# O2 Y% k2 L2 N/ M
- return LL_OK;* s1 j5 A4 S2 s, x- i* }2 R. S- `
- }/ a6 ?* J& Z5 T, p, M Z1 L
复制代码
! W2 ^! P8 M) a% D" a/ U* h7 w% U* L3 J+ [
|