你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32,仿照LL库,编写FLASH的LL库(内有完成代码)(STM32F0)

[复制链接]
STMCU小助手 发布时间:2021-11-13 23:00
不知道为为什么,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
  1. __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
    $ z* v( r; _! F1 G
  2. {
    4 r) B* Y6 n, S
  3.   WRITE_REG(GPIOx->BSRR, PinMask);6 c* b8 R: `# M# R
  4. }
复制代码
于是我根据这种风格,已经常用的操作写了一个.h和.c文件
# |& A& C, I! X" ?& ?. {  V! Q! [$ _7 P) r) t7 [
头文件代码3 d8 ~3 `9 ?8 o3 }" _, z" Y
  1. #ifndef __STM32F0xx_LL_FLASH_EX_H% m, W! A5 W: b  p- R+ n
  2. #define __STM32F0xx_LL_FLASH_EX_H
    ' e$ `  B$ e+ ^1 c/ f5 j

  3. # y( B$ c6 s) o5 b1 ^( ~, h
  4. #include "stm32f0xx.h"( ]4 Q; T( w# ?6 T6 s

  5. 4 g% O4 S# n: G3 T( r

  6. ) L+ [! A+ p9 m4 C8 o3 R. [1 [
  7. #define FLASH_FLAG_BSY             FLASH_SR_BSY            /*!< FLASH Busy flag                           */ & R2 Q  U+ Y* o5 B" k  t" Z
  8. #define FLASH_FLAG_PGERR           FLASH_SR_PGERR          /*!< FLASH Programming error flag    */
    , q! }5 _3 d# o4 q1 M$ {3 }
  9. #define FLASH_FLAG_WRPERR          FLASH_SR_WRPERR         /*!< FLASH Write protected error flag          */# Z* m) ?; O3 }- y
  10. #define FLASH_FLAG_EOP             FLASH_SR_EOP            /*!< FLASH End of Operation flag               */
    & C9 S. E/ t/ H8 E
  11.   |+ x2 q/ J2 t3 Y" Q2 v
  12. #define FLASH_TYPEERASE_PAGES          FLASH_CR_PER         /*!< FLASH_CR_PER          */
    + r  M& I  U) x, J5 l& O
  13. #define FLASH_TYPEERASE_MASSERASE      FLASH_CR_MER            /*!< MASSERASE              */
    : q" l$ p* n5 e- c
  14. , @6 S5 D3 n* d2 N4 {' a, B
  15. * _+ [- b5 b: I* S' X* e
  16. #if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \
    : w3 y$ G9 q5 }( b
  17. || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)
    $ p7 ]/ T8 r# {( n& }% s; q4 W, J
  18. #define FLASH_PAGE_SIZE          0x400U
    ! p) V0 g5 X$ E4 l- ?) ~, `  z
  19. #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */' Z, z0 Z- o- E8 H" Q# R/ z
  20. ; ^2 T8 s; n$ m, p/ Z% v
  21. #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \4 h( G9 u: L# d& j. w/ ~6 P
  22. || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)/ d- t8 C  J7 R; x! B" ?; r
  23. #define FLASH_PAGE_SIZE          0x800U% x# [2 T7 j: m" ^& V
  24. #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */) K$ j& b$ U2 n: \( q# F

  25. ( Z: p3 F  v1 ^! H; O2 i
  26. typedef enum {% {: c! j2 J5 }( [
  27.         ProgaraType_DATA64,! ^8 i0 J/ m! J0 t
  28.         ProgaraType_DATA32,: L- }0 R; }1 b: T6 Q$ X0 _
  29.         ProgaraType_DATA16, i! j2 z) _$ [1 \2 `7 ~/ V8 [
  30. }ProgaramDataType;
    , H. I% a& Q/ s% B6 x' i

  31. 9 ^, u6 X' k7 \( t$ P4 B  b; L, }) G
  32. typedef enum {\0 ?/ u5 d$ U7 I/ j
  33.         FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\
    1 H  b: ?5 s& t4 e- r" j2 `4 M- S
  34. }FlashStates;
    . }" A8 F' g: M% T) v

  35. , P: T0 i! x0 c
  36.   /* Set the OBL_Launch bit to launch the option byte loading */
      \+ f# `2 q' }3 U; C
  37. __STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)
    * e" K! ~8 H7 `
  38. {8 X$ k2 |/ s  p6 F- T3 d' E2 }/ A
  39.   SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);3 t1 w7 `, r$ Z6 {: W3 C" a3 f
  40. }, H2 Y5 k3 c" ^
  41. __STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx)/ k% u) z+ f/ l/ W( n% Y) `; _: l# A% Y
  42. {
    , d3 O, s9 z3 M5 _% S
  43.   SET_BIT(FLASHx->CR, FLASH_CR_LOCK);
    + F6 E, `) f) E9 G  T8 M+ T
  44. }8 Q! O- N$ ?/ E" a6 w
  45. 5 t% y/ |9 u( @) j1 g/ D
  46. - R& G7 \% ]/ Y) {
  47.   /* @brief  Set flash erase type.& ^" ?0 I1 S% ?9 R/ H
  48.   * @param  FLASH_TYPEERASE specifies the FLASH flags to clear.
    . {* a' w* R" ~) G( [, _$ m/ p
  49.   *          This parameter can be any combination of the following values:: z: y! s, {- d5 s1 b1 r) I* U
  50.   *            @arg @ref FLASH_TYPEERASE_PAGES         PAGES Erase* {4 C) i) C. Z; E! ?+ a
  51.   *            @arg @ref FLASH_TYPEERASE_MASSERASE      FLASH Write protected error flag ! c5 j: n% Y. o7 g& f  p
  52.   * @retval none*/7 Z# {- Y3 j+ L  S

  53. 4 [# m/ h% J  V+ z7 `
  54. __STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)! Z( ?& t6 p7 R' P. y  z  W1 T4 Q
  55. {$ ^# F9 E7 O7 |  ?( I
  56.   SET_BIT(FLASHx->CR, FLASH_TYPEERASE);3 N" B2 U) V6 u3 k
  57. }
      z# F- W- t" l' \
  58.   /* @brief  Set flash erase ADDR.
    ! [, {' G& H) O
  59.   *          This parameter can be any combination of the following values:4 M7 {, \1 a9 W
  60.   *            @arg @ref EraseADDR         uint32_t value" E4 I: u( i7 R; B5 S" [2 t
  61.   * @retval none*/( |2 o1 t/ v, N9 P# _
  62. # D5 R, }0 N9 w8 r; j, q3 I# `
  63. __STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR)2 R1 Q. K/ X4 j' b& r% x
  64. {& A# @6 s5 K' e' |
  65.   WRITE_REG(FLASHx->AR, EraseADDR);
    0 N0 S0 `0 L2 n* u
  66. }
    $ f4 l  _) _1 H, q! v' [4 X; Z+ G) n
  67.   /* @brief  Set flash erase ADDR.8 ]$ q- N" C$ I* z) j+ N
  68.   *          This parameter can be any combination of the following values:
    ; s1 D7 Q' t- }1 \6 @5 M# u/ Z
  69.   *            @arg @ref EraseADDR         uint32_t value# c4 G; A; d/ A+ g; q; e# I7 d& T
  70.   * @retval none*/$ S# {' O' k% J' v
  71. 8 B6 L7 j2 S; H. D, q
  72. __STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)
    9 p  s  T4 Z* y. m! k4 m, c
  73. {
    . H7 i& B4 J' n4 E
  74.   SET_BIT(FLASHx->CR, FLASH_CR_STRT);4 e) Z" F7 X: _) A# Y# f) R
  75. }
    9 h" L- q+ Z$ }

  76. 5 h1 q  k! [# O; L7 ^; z: e- t
  77.   /* @brief  Clear the specified FLASH flag.
    + s, J8 l. ?; m
  78.   * @param  __FLAG__ specifies the FLASH flags to clear.) C# Z$ \4 ~8 }+ }% u
  79.   *          This parameter can be any combination of the following values:) r6 M+ J; i6 c3 \1 E" y
  80.   *            @arg @ref FLASH_FLAG_EOP         FLASH End of Operation flag
    ; H5 B' M4 ^: y- Z) T* @
  81.   *            @arg @ref FLASH_FLAG_WRPERR      FLASH Write protected error flag
    2 B( Z3 p- e9 [7 U; g
  82.   *            @arg @ref FLASH_FLAG_PGERR       FLASH Programming error flag
    & Q* X  c7 E# S; k) C5 i" z
  83.   * @retval none*/
    ( I* w) k6 M% ~/ w4 h  u
  84.   r3 c1 K+ W3 M! W' D/ @
  85. __STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG)
    2 O  u1 ~# ]* |3 n
  86. {! X# z) y1 t2 s9 j3 n
  87.   WRITE_REG(FLASHx->SR, STATE_FLAG);5 L2 q/ n% [2 B
  88. }
    ( r: k; e$ D/ [7 |9 ~" i9 U

  89.   \6 |. P$ F5 j- r
  90.   /*get bit flash bsy*/) R; s, }: k% {9 `
  91. __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)- B/ q, S% Z  ?; ~: c
  92. {6 g9 [; O6 D' r8 w
  93.   return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));
    & g! m9 K" c$ c. c1 u& k
  94. }
    * l! ?+ [* g' Z/ {& E0 d) m9 \
  95. /*get end of operation bilt*/" Y  w8 H- X9 N0 J- B
  96. __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx)
    1 m' }- l* p7 W. j
  97. {; U' L1 G& h# n9 X& }9 y
  98.   return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));+ i) ~) Y. N3 a) {! h
  99. }/ V1 f$ @1 |9 p* c6 O8 _$ o
  100. /*clear end of operation bilt*/! H6 A9 S) H; R0 r( |, V) x
  101. __STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx)
    # I! b7 U- u. k) u8 c6 T' s
  102. {
    % O8 p9 }3 w5 U. {$ h, p
  103.   SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear
    6 A$ B% _0 z$ q) r  J
  104. }3 a. A5 O# M1 x. ?
  105.   /* @brief  Set flash erase type.* Y$ N7 c# P4 e3 G
  106.   * @param  FLASH_TYPEERASE specifies the FLASH flags to clear.
    ( _, p0 t' |: S+ U; W( D
  107.   *          This parameter can be any combination of the following values:( E/ C4 B* H$ d9 @
  108.   *            @arg @ref FLASH_TYPEERASE_PAGES         PAGES Erase) Z4 Z, ?2 _# ?; W# g
  109.   *            @arg @ref FLASH_TYPEERASE_MASSERASE      FLASH Write protected error flag
    3 P- n" K" s4 L5 {
  110.   * @retval none*/! i$ b9 @6 v4 q" e/ k0 ~
  111. __STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)* M7 w" \! t0 q2 A
  112. {
    9 m' Y/ Q/ K: c1 y
  113.   CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);
    ; ^% e5 Y2 k: V% |# @
  114. }
    . U, o7 j$ M7 o( o

  115. 8 F6 F! J0 m8 a$ j0 U4 q
  116. /*EnableProgram*/
    7 p; O. o) T4 Y0 v) S1 U/ n3 o# t
  117. __STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)0 i. S- E# F; M& @3 @! m- Q
  118. {) F2 N6 N3 o7 |& N& C
  119.   SET_BIT(FLASHx->CR,FLASH_CR_PG);* j; j$ `/ x  _' h; k7 g* }
  120. }' s( l: E8 v# u8 ^. G
  121. /*DisenableProgram*/
    * M6 H5 z& S5 E
  122. __STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx)
    + w  ?- g8 b! S8 r
  123. {  I1 a3 t  p+ Z( u4 N# r
  124.   CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);, I" ~4 Z- i4 j$ y1 ]5 [- j( v6 _
  125. }
    5 W5 U; {. N5 X4 V2 s- Y6 `( y5 L: c
  126. /*read flash's states of lock or unlock*/
    " b1 r4 i3 X$ Q; J0 u5 |% o
  127. __STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx)
    ' K0 o& t: X+ T( P0 t
  128. {
      A3 j% e* S/ g: O& u# t4 S
  129.         return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));
    $ k! ~/ y. g7 y2 d6 C
  130. }  z, L$ ?8 g3 b* K( T& u
  131. /*set key for flash*/
    + i  Z' C1 f3 {& ]6 W2 d
  132. __STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key)
    - l- O$ \* |+ H2 p- b
  133. {" x9 d7 G- _$ B1 j! M
  134.         WRITE_REG(FLASH->KEYR,key);2 B! ]( D5 A9 y
  135. }
    $ K1 t$ X# b; l2 @1 A, x

  136. 2 q# V4 l$ J$ d# d7 J

  137. % h7 |! w9 E; ]6 j5 V% n
  138. LL_StatusTypeDef LL_Flash_Unlock(void);, i3 [5 a$ ?8 l$ T+ K
  139. LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);
    6 z. K, x- y$ v
  140. LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data);
    $ J! m0 h9 h* A) W
  141. #endif
复制代码

; c+ E( l1 w+ u) h2 JC文件代码
1 o8 F6 b2 y( v
  1. #include "stm32f0xx_ll_flash_ex.h"
    3 W4 X4 o, a1 p1 W! a; U
  2. ) ~, |: u5 d! }) `1 O

  3. . B6 W5 i# k$ Y5 d2 O
  4. void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data)
    ! o/ C9 B( o# u) a- B4 n. a
  5. {8 }( B! e$ Q2 f- f6 Q9 t. B1 I1 T
  6.         LL_FLASH_EnableProgram(FLASH);
    ; Z' U* Z$ t7 L/ V$ Z2 g
  7.         *(__IO uint16_t*)(flash_addr) = data;
    4 ?5 G; Y& }, t) s0 J6 Y- x
  8. }$ _" S6 D; y0 n; R  U- [* P
  9. / @0 ?5 ?4 _- F2 C( t
  10. LL_StatusTypeDef LL_Flash_Unlock(void)
    3 H# G& C; N, D* e
  11. {
    ; D! t! y" ]6 a7 G; @% a1 u
  12.         while (LL_FLASH_IsActiveFlag_BSY(FLASH))  
    9 V! _4 X. l! k  c
  13.         {
    4 ~" p8 c: O" k3 ?0 g/ B# y
  14.         } ; W  i2 w4 {* k  Z* j
  15.         if (LL_FLASH_LockState(FLASH)) ( g# X% ]- Z) H1 r
  16.         { 8 _! W* T. w7 K7 P, T+ M
  17.                 LL_FLASh_SetKey(FLASH,FLASH_KEY1);% Y# h3 C8 x3 ]8 N
  18.                 LL_FLASh_SetKey(FLASH,FLASH_KEY2);) _" [: {: [+ q6 ^7 G0 c) u
  19.         }
    5 c; G! D  r2 U
  20.         return LL_OK;
    , I# G- m+ v( w$ T5 L8 r
  21. }9 F' G( @! F" g# a' i3 T0 |, Z0 ?! N
  22. 0 @; N8 x+ c) j! G4 Q( z
  23. LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)6 U; n$ H4 Y# S5 l
  24. {: j5 }6 F: J+ R9 [$ p
  25.         uint32_t End_addr =  10* FLASH_PAGE_SIZE +page_addr;
    7 @* ^" f! m1 t( S7 d$ H6 J
  26.         uint32_t Start_addr = page_addr;: `2 b  z$ w) Y0 V( I
  27.         for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE))
    ! U2 c3 c) G, q0 N& O$ p' c
  28.     {( S7 {7 i$ s7 i7 V6 M' |
  29.         LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);% F) ^7 Y. A* s
  30.                 LL_FLASH_SetEraseADDR(FLASH,Start_addr);
    1 D7 [6 \1 t" @. B+ i% D
  31.                 LL_FLASH_StartErase(FLASH); 8 a% N1 X  F! R
  32.                 while (LL_FLASH_IsActiveFlag_BSY(FLASH)) # k" _, J  y% O" W8 }1 H2 F6 V8 _3 s
  33.                 {
      O0 n; a' l4 u( `; d' Y( u' X
  34.                 }
    5 R5 B) I4 f7 ]# R. L4 `* t
  35.                 if (LL_FLASH_IsActiveFlag_EOP(FLASH))
    4 }. M9 [& E: Z2 f5 z
  36.                 { 6 M- d+ |2 z- l
  37.                         LL_FLASH_ClearFlag_EOP(FLASH);;
    ' ~: K; B8 v& B" S5 J& j0 |0 m8 c8 U+ n
  38.                 }
    8 H- h4 c) w/ O' K. R8 X
  39.                 else
    4 y$ b2 ^0 O4 u" [& D
  40.                 {
      e' u& ?/ f0 z# {  X
  41.                         return LL_ERROR;4 ]! r  j2 I6 d- o
  42.                 }
    4 z& o" |) y2 \2 C# k2 p
  43.                 LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);2 z# m7 ^% J0 y: P; |
  44.     }5 p% s. M3 g4 F7 {9 V
  45.         return LL_OK;  {: u. F5 H" y% _7 q
  46. }  ~, u9 ^; Z! u  Y9 m* L1 \! J

  47. % g$ h9 s6 m8 j* j
  48. LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data). B0 l* s& g* v, u1 S
  49. {
    " [2 V) ^$ _! D! j
  50.         / p+ A! ^6 G- t* T7 c; R% |
  51.         uint8_t index = 0U;
    ' \8 \7 k9 J$ o
  52.         uint8_t nbiterations = 0U;
    + o7 ~, l" s* ~! Q4 D9 N* k  y
  53.         
    ; D9 H$ z0 P9 x; w- X
  54.         if(ProgramType == ProgaraType_DATA16)0 e0 `3 w0 H4 t- t; l  Q
  55.                 nbiterations = 1U;
    . ?2 K; C5 |2 u5 l) @
  56.         else if(ProgramType == ProgaraType_DATA32)! W6 l! l4 d8 X5 W
  57.                 nbiterations = 2U;
    ! ~+ o+ f- i  r: _2 ?. o  \
  58.         else% C5 U% r( a, U$ G0 \" a
  59.                 nbiterations = 4U;
    . |' U$ D  Y7 F0 R/ u% U
  60.         for(index = 0U; index < nbiterations; index++)
    2 a8 g2 o, I$ W* r
  61.         {
    " ~3 t. P/ k3 t$ k/ a/ i
  62.                  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
  63.         }
    ( u+ P$ A+ a1 L( X8 f6 L. u9 c8 E; h
  64.         
    , F  |( ^7 O+ ]) X' }
  65.         while (LL_FLASH_IsActiveFlag_BSY(FLASH)) * O7 I7 x4 Z( T: Z  U+ s
  66.         {: U3 \! F. E" z- g3 S3 R
  67.         }% z  c) A! {4 q2 F8 ?7 r. q; e
  68.         if (LL_FLASH_IsActiveFlag_EOP(FLASH))        . y( T/ t0 ?% P1 u
  69.         {1 M& Q, K& m2 u- {* ?
  70.                 LL_FLASH_ClearFlag_EOP(FLASH);
    3 `) U9 P0 r* X: W) V
  71.         }5 Q0 N2 f" A' P- M
  72.         else' Q; v5 N5 b" x; X" ^) G8 K
  73.         {
    + Y: X4 o& h/ V2 U$ c
  74.                 return LL_ERROR;4 a+ ]- b% h4 F+ ^# C7 `5 P" S: {
  75.         }' C* n% B) F; {& {. w8 Q
  76.         LL_FLASH_DisenableProgram(FLASH);! X) G/ M# K1 I( B& w
  77.         return LL_OK;9 ]3 A+ _+ L/ p% i3 _
  78. }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
收藏 评论0 发布时间:2021-11-13 23:00

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版