不知道为为什么,STM32 LL库并没有FLASH的库函数,于是决定写一个
C' @8 v) a- Y0 h3 q) ]" r3 ?
' t4 ?! F& a5 A3 q' _1 F( ^1 CLL库的特色,就是一个函数,只占用一个指令周期,比如,设置GPIO输出的状态,就是LL_GPIO_SetOutputPin();& r) m( J' X$ U5 Q3 d0 X
- __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
$ z* v( r; _! F1 G - {
4 r) B* Y6 n, S - WRITE_REG(GPIOx->BSRR, PinMask);6 c* b8 R: `# M# R
- }
复制代码 于是我根据这种风格,已经常用的操作写了一个.h和.c文件
# |& A& C, I! X" ?& ?. { V! Q! [$ _7 P) r) t7 [
头文件代码3 d8 ~3 `9 ?8 o3 }" _, z" Y
- #ifndef __STM32F0xx_LL_FLASH_EX_H% m, W! A5 W: b p- R+ n
- #define __STM32F0xx_LL_FLASH_EX_H
' e$ ` B$ e+ ^1 c/ f5 j
# y( B$ c6 s) o5 b1 ^( ~, h- #include "stm32f0xx.h"( ]4 Q; T( w# ?6 T6 s
4 g% O4 S# n: G3 T( r
) L+ [! A+ p9 m4 C8 o3 R. [1 [- #define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */ & R2 Q U+ Y* o5 B" k t" Z
- #define FLASH_FLAG_PGERR FLASH_SR_PGERR /*!< FLASH Programming error flag */
, q! }5 _3 d# o4 q1 M$ {3 } - #define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */# Z* m) ?; O3 }- y
- #define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */
& C9 S. E/ t/ H8 E - |+ x2 q/ J2 t3 Y" Q2 v
- #define FLASH_TYPEERASE_PAGES FLASH_CR_PER /*!< FLASH_CR_PER */
+ r M& I U) x, J5 l& O - #define FLASH_TYPEERASE_MASSERASE FLASH_CR_MER /*!< MASSERASE */
: q" l$ p* n5 e- c - , @6 S5 D3 n* d2 N4 {' a, B
- * _+ [- b5 b: I* S' X* e
- #if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \
: w3 y$ G9 q5 }( b - || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)
$ p7 ]/ T8 r# {( n& }% s; q4 W, J - #define FLASH_PAGE_SIZE 0x400U
! p) V0 g5 X$ E4 l- ?) ~, ` z - #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */' Z, z0 Z- o- E8 H" Q# R/ z
- ; ^2 T8 s; n$ m, p/ Z% v
- #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \4 h( G9 u: L# d& j. w/ ~6 P
- || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)/ d- t8 C J7 R; x! B" ?; r
- #define FLASH_PAGE_SIZE 0x800U% x# [2 T7 j: m" ^& V
- #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */) K$ j& b$ U2 n: \( q# F
( Z: p3 F v1 ^! H; O2 i- typedef enum {% {: c! j2 J5 }( [
- ProgaraType_DATA64,! ^8 i0 J/ m! J0 t
- ProgaraType_DATA32,: L- }0 R; }1 b: T6 Q$ X0 _
- ProgaraType_DATA16, i! j2 z) _$ [1 \2 `7 ~/ V8 [
- }ProgaramDataType;
, H. I% a& Q/ s% B6 x' i
9 ^, u6 X' k7 \( t$ P4 B b; L, }) G- typedef enum {\0 ?/ u5 d$ U7 I/ j
- FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\
1 H b: ?5 s& t4 e- r" j2 `4 M- S - }FlashStates;
. }" A8 F' g: M% T) v
, P: T0 i! x0 c- /* Set the OBL_Launch bit to launch the option byte loading */
\+ f# `2 q' }3 U; C - __STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)
* e" K! ~8 H7 ` - {8 X$ k2 |/ s p6 F- T3 d' E2 }/ A
- SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);3 t1 w7 `, r$ Z6 {: W3 C" a3 f
- }, H2 Y5 k3 c" ^
- __STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx)/ k% u) z+ f/ l/ W( n% Y) `; _: l# A% Y
- {
, d3 O, s9 z3 M5 _% S - SET_BIT(FLASHx->CR, FLASH_CR_LOCK);
+ F6 E, `) f) E9 G T8 M+ T - }8 Q! O- N$ ?/ E" a6 w
- 5 t% y/ |9 u( @) j1 g/ D
- - R& G7 \% ]/ Y) {
- /* @brief Set flash erase type.& ^" ?0 I1 S% ?9 R/ H
- * @param FLASH_TYPEERASE specifies the FLASH flags to clear.
. {* a' w* R" ~) G( [, _$ m/ p - * This parameter can be any combination of the following values:: z: y! s, {- d5 s1 b1 r) I* U
- * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase* {4 C) i) C. Z; E! ?+ a
- * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag ! c5 j: n% Y. o7 g& f p
- * @retval none*/7 Z# {- Y3 j+ L S
4 [# m/ h% J V+ z7 `- __STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)! Z( ?& t6 p7 R' P. y z W1 T4 Q
- {$ ^# F9 E7 O7 | ?( I
- SET_BIT(FLASHx->CR, FLASH_TYPEERASE);3 N" B2 U) V6 u3 k
- }
z# F- W- t" l' \ - /* @brief Set flash erase ADDR.
! [, {' G& H) O - * This parameter can be any combination of the following values:4 M7 {, \1 a9 W
- * @arg @ref EraseADDR uint32_t value" E4 I: u( i7 R; B5 S" [2 t
- * @retval none*/( |2 o1 t/ v, N9 P# _
- # D5 R, }0 N9 w8 r; j, q3 I# `
- __STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR)2 R1 Q. K/ X4 j' b& r% x
- {& A# @6 s5 K' e' |
- WRITE_REG(FLASHx->AR, EraseADDR);
0 N0 S0 `0 L2 n* u - }
$ f4 l _) _1 H, q! v' [4 X; Z+ G) n - /* @brief Set flash erase ADDR.8 ]$ q- N" C$ I* z) j+ N
- * This parameter can be any combination of the following values:
; s1 D7 Q' t- }1 \6 @5 M# u/ Z - * @arg @ref EraseADDR uint32_t value# c4 G; A; d/ A+ g; q; e# I7 d& T
- * @retval none*/$ S# {' O' k% J' v
- 8 B6 L7 j2 S; H. D, q
- __STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)
9 p s T4 Z* y. m! k4 m, c - {
. H7 i& B4 J' n4 E - SET_BIT(FLASHx->CR, FLASH_CR_STRT);4 e) Z" F7 X: _) A# Y# f) R
- }
9 h" L- q+ Z$ }
5 h1 q k! [# O; L7 ^; z: e- t- /* @brief Clear the specified FLASH flag.
+ s, J8 l. ?; m - * @param __FLAG__ specifies the FLASH flags to clear.) C# Z$ \4 ~8 }+ }% u
- * This parameter can be any combination of the following values:) r6 M+ J; i6 c3 \1 E" y
- * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag
; H5 B' M4 ^: y- Z) T* @ - * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag
2 B( Z3 p- e9 [7 U; g - * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
& Q* X c7 E# S; k) C5 i" z - * @retval none*/
( I* w) k6 M% ~/ w4 h u - r3 c1 K+ W3 M! W' D/ @
- __STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG)
2 O u1 ~# ]* |3 n - {! X# z) y1 t2 s9 j3 n
- WRITE_REG(FLASHx->SR, STATE_FLAG);5 L2 q/ n% [2 B
- }
( r: k; e$ D/ [7 |9 ~" i9 U
\6 |. P$ F5 j- r- /*get bit flash bsy*/) R; s, }: k% {9 `
- __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)- B/ q, S% Z ?; ~: c
- {6 g9 [; O6 D' r8 w
- return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));
& g! m9 K" c$ c. c1 u& k - }
* l! ?+ [* g' Z/ {& E0 d) m9 \ - /*get end of operation bilt*/" Y w8 H- X9 N0 J- B
- __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx)
1 m' }- l* p7 W. j - {; U' L1 G& h# n9 X& }9 y
- return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));+ i) ~) Y. N3 a) {! h
- }/ V1 f$ @1 |9 p* c6 O8 _$ o
- /*clear end of operation bilt*/! H6 A9 S) H; R0 r( |, V) x
- __STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx)
# I! b7 U- u. k) u8 c6 T' s - {
% O8 p9 }3 w5 U. {$ h, p - SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear
6 A$ B% _0 z$ q) r J - }3 a. A5 O# M1 x. ?
- /* @brief Set flash erase type.* Y$ N7 c# P4 e3 G
- * @param FLASH_TYPEERASE specifies the FLASH flags to clear.
( _, p0 t' |: S+ U; W( D - * This parameter can be any combination of the following values:( E/ C4 B* H$ d9 @
- * @arg @ref FLASH_TYPEERASE_PAGES PAGES Erase) Z4 Z, ?2 _# ?; W# g
- * @arg @ref FLASH_TYPEERASE_MASSERASE FLASH Write protected error flag
3 P- n" K" s4 L5 { - * @retval none*/! i$ b9 @6 v4 q" e/ k0 ~
- __STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)* M7 w" \! t0 q2 A
- {
9 m' Y/ Q/ K: c1 y - CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);
; ^% e5 Y2 k: V% |# @ - }
. U, o7 j$ M7 o( o
8 F6 F! J0 m8 a$ j0 U4 q- /*EnableProgram*/
7 p; O. o) T4 Y0 v) S1 U/ n3 o# t - __STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)0 i. S- E# F; M& @3 @! m- Q
- {) F2 N6 N3 o7 |& N& C
- SET_BIT(FLASHx->CR,FLASH_CR_PG);* j; j$ `/ x _' h; k7 g* }
- }' s( l: E8 v# u8 ^. G
- /*DisenableProgram*/
* M6 H5 z& S5 E - __STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx)
+ w ?- g8 b! S8 r - { I1 a3 t p+ Z( u4 N# r
- CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);, I" ~4 Z- i4 j$ y1 ]5 [- j( v6 _
- }
5 W5 U; {. N5 X4 V2 s- Y6 `( y5 L: c - /*read flash's states of lock or unlock*/
" b1 r4 i3 X$ Q; J0 u5 |% o - __STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx)
' K0 o& t: X+ T( P0 t - {
A3 j% e* S/ g: O& u# t4 S - return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));
$ k! ~/ y. g7 y2 d6 C - } z, L$ ?8 g3 b* K( T& u
- /*set key for flash*/
+ i Z' C1 f3 {& ]6 W2 d - __STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key)
- l- O$ \* |+ H2 p- b - {" x9 d7 G- _$ B1 j! M
- WRITE_REG(FLASH->KEYR,key);2 B! ]( D5 A9 y
- }
$ K1 t$ X# b; l2 @1 A, x
2 q# V4 l$ J$ d# d7 J
% h7 |! w9 E; ]6 j5 V% n- LL_StatusTypeDef LL_Flash_Unlock(void);, i3 [5 a$ ?8 l$ T+ K
- LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);
6 z. K, x- y$ v - LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data);
$ J! m0 h9 h* A) W - #endif
复制代码
; c+ E( l1 w+ u) h2 JC文件代码
1 o8 F6 b2 y( v- #include "stm32f0xx_ll_flash_ex.h"
3 W4 X4 o, a1 p1 W! a; U - ) ~, |: u5 d! }) `1 O
. B6 W5 i# k$ Y5 d2 O- void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data)
! o/ C9 B( o# u) a- B4 n. a - {8 }( B! e$ Q2 f- f6 Q9 t. B1 I1 T
- LL_FLASH_EnableProgram(FLASH);
; Z' U* Z$ t7 L/ V$ Z2 g - *(__IO uint16_t*)(flash_addr) = data;
4 ?5 G; Y& }, t) s0 J6 Y- x - }$ _" S6 D; y0 n; R U- [* P
- / @0 ?5 ?4 _- F2 C( t
- LL_StatusTypeDef LL_Flash_Unlock(void)
3 H# G& C; N, D* e - {
; D! t! y" ]6 a7 G; @% a1 u - while (LL_FLASH_IsActiveFlag_BSY(FLASH))
9 V! _4 X. l! k c - {
4 ~" p8 c: O" k3 ?0 g/ B# y - } ; W i2 w4 {* k Z* j
- if (LL_FLASH_LockState(FLASH)) ( g# X% ]- Z) H1 r
- { 8 _! W* T. w7 K7 P, T+ M
- LL_FLASh_SetKey(FLASH,FLASH_KEY1);% Y# h3 C8 x3 ]8 N
- LL_FLASh_SetKey(FLASH,FLASH_KEY2);) _" [: {: [+ q6 ^7 G0 c) u
- }
5 c; G! D r2 U - return LL_OK;
, I# G- m+ v( w$ T5 L8 r - }9 F' G( @! F" g# a' i3 T0 |, Z0 ?! N
- 0 @; N8 x+ c) j! G4 Q( z
- LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)6 U; n$ H4 Y# S5 l
- {: j5 }6 F: J+ R9 [$ p
- uint32_t End_addr = 10* FLASH_PAGE_SIZE +page_addr;
7 @* ^" f! m1 t( S7 d$ H6 J - uint32_t Start_addr = page_addr;: `2 b z$ w) Y0 V( I
- for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE))
! U2 c3 c) G, q0 N& O$ p' c - {( S7 {7 i$ s7 i7 V6 M' |
- LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);% F) ^7 Y. A* s
- LL_FLASH_SetEraseADDR(FLASH,Start_addr);
1 D7 [6 \1 t" @. B+ i% D - LL_FLASH_StartErase(FLASH); 8 a% N1 X F! R
- while (LL_FLASH_IsActiveFlag_BSY(FLASH)) # k" _, J y% O" W8 }1 H2 F6 V8 _3 s
- {
O0 n; a' l4 u( `; d' Y( u' X - }
5 R5 B) I4 f7 ]# R. L4 `* t - if (LL_FLASH_IsActiveFlag_EOP(FLASH))
4 }. M9 [& E: Z2 f5 z - { 6 M- d+ |2 z- l
- LL_FLASH_ClearFlag_EOP(FLASH);;
' ~: K; B8 v& B" S5 J& j0 |0 m8 c8 U+ n - }
8 H- h4 c) w/ O' K. R8 X - else
4 y$ b2 ^0 O4 u" [& D - {
e' u& ?/ f0 z# { X - return LL_ERROR;4 ]! r j2 I6 d- o
- }
4 z& o" |) y2 \2 C# k2 p - LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);2 z# m7 ^% J0 y: P; |
- }5 p% s. M3 g4 F7 {9 V
- return LL_OK; {: u. F5 H" y% _7 q
- } ~, u9 ^; Z! u Y9 m* L1 \! J
% g$ h9 s6 m8 j* j- LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data). B0 l* s& g* v, u1 S
- {
" [2 V) ^$ _! D! j - / p+ A! ^6 G- t* T7 c; R% |
- uint8_t index = 0U;
' \8 \7 k9 J$ o - uint8_t nbiterations = 0U;
+ o7 ~, l" s* ~! Q4 D9 N* k y -
; D9 H$ z0 P9 x; w- X - if(ProgramType == ProgaraType_DATA16)0 e0 `3 w0 H4 t- t; l Q
- nbiterations = 1U;
. ?2 K; C5 |2 u5 l) @ - else if(ProgramType == ProgaraType_DATA32)! W6 l! l4 d8 X5 W
- nbiterations = 2U;
! ~+ o+ f- i r: _2 ?. o \ - else% C5 U% r( a, U$ G0 \" a
- nbiterations = 4U;
. |' U$ D Y7 F0 R/ u% U - for(index = 0U; index < nbiterations; index++)
2 a8 g2 o, I$ W* r - {
" ~3 t. P/ k3 t$ k/ a/ i - LL_FLASH_Program_TwoBtye((flash_addr + (2U*index)), (uint16_t)(data >> (16U*index)));
0 A8 o4 c/ Z) r* W: c( U% B1 G$ t - }
( u+ P$ A+ a1 L( X8 f6 L. u9 c8 E; h -
, F |( ^7 O+ ]) X' } - while (LL_FLASH_IsActiveFlag_BSY(FLASH)) * O7 I7 x4 Z( T: Z U+ s
- {: U3 \! F. E" z- g3 S3 R
- }% z c) A! {4 q2 F8 ?7 r. q; e
- if (LL_FLASH_IsActiveFlag_EOP(FLASH)) . y( T/ t0 ?% P1 u
- {1 M& Q, K& m2 u- {* ?
- LL_FLASH_ClearFlag_EOP(FLASH);
3 `) U9 P0 r* X: W) V - }5 Q0 N2 f" A' P- M
- else' Q; v5 N5 b" x; X" ^) G8 K
- {
+ Y: X4 o& h/ V2 U$ c - return LL_ERROR;4 a+ ]- b% h4 F+ ^# C7 `5 P" S: {
- }' C* n% B) F; {& {. w8 Q
- LL_FLASH_DisenableProgram(FLASH);! X) G/ M# K1 I( B& w
- return LL_OK;9 ]3 A+ _+ L/ p% i3 _
- }0 j( b, T6 |/ ^8 W# N% S) b2 O T
复制代码
) |, K" E" h( | m% q9 I8 A' J: V
( t7 Z. x5 v, E5 x+ O |