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

【经验分享】STM32F7 内部flash操作启动

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
总体来说与STM32F4操作是一样的,就是扇区大小变化了,测试过程中发现当PG=1之后立即写入数据到flash会造成编程顺序错误,通过增加一个nop的延时即可解决此问题,还可以通过将多个数据连续烧写的方式避免此问题,就是当PG=1之后,把所有数据都烧写完成后再将PG=0,不要频繁的开关。0 M/ k: U9 B' f
- q$ ~+ H9 U5 i7 Y. e
  1. /*************************************************************************************************************, K2 ?% p+ X. g, J" Z8 O+ i
  2. * 文件名:                        stm32f7_flash.c
    $ @" u& `  R/ r; t4 U: u
  3. * 功能:                        STM32F7 内部FLASH编程驱动函数
    ' w9 g5 n+ C) Q
  4. * 作者:                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    - Y! j9 @, \) t& b
  5. * 创建时间:                2013-10-20/ \& z8 Z9 Q' J; L0 r
  6. * 最后修改时间:        2020-02-07% `1 G# f/ R( h! q! s
  7. * 详细:                        用于STM32F7内部flash读写驱动
    ! m- A. }+ M0 Y& J! ^# j8 ]
  8.                                         默认为3.3V供电,并且宽度为32bit;
    6 J% i. e2 i* ]' _8 c6 f
  9.                                         扇区擦除最长时间:32KB扇区500ms;128KB扇区1.1秒;256KB扇区:2秒+ p- z  B! ^- s. A2 ^% }$ k
  10.                                         修复STM32F7开始写入数据时,PG=1后没有延时导致异常,增加批量写入多个字的数据函数STM32FLASH_WriteMultipledWord()支持。
    ( Y9 r6 _. p  v* Z4 ~
  11. *************************************************************************************************************/
    4 t# r+ H" C% r9 k  O9 q* ?5 X
  12. #include "stm32f7_flash.h"6 `8 `) \1 Q, t! C! \9 e
  13. #include "system.h"
    4 j( X" ]# Z) R, m: j0 z+ A
  14. #if(SYS_WDG_EN_) //使能了看门狗- x) B% L0 ^0 ~. ]2 K5 e% X
  15. #include "wdg.h"
    : `* }. v' F9 x# ?2 N& T) G
  16. #endif //SYS_WDG_EN_
    * d8 K. P8 R6 d% V, |: H$ B
  17. 9 h) J7 Y8 g( l  \2 _7 }

  18. ) A3 w3 K; f8 c. b
  19. 0 p: f+ @: [+ w3 T$ Z3 T* ~

  20. : v+ `2 {3 W% ?; E# K/ B9 Z) Z* u3 ~, A
  21. /*************************************************************************************************************************8 x; v: v6 `- S
  22. * 函数                        :        void STM32FLASH_Unlock(void)
    , ]' F' Y4 d) }3 l1 N% e
  23. * 功能                        :        解锁STM32的FLASH
    3 n& b! r6 w! }7 X4 R4 ^6 W
  24. * 参数                        :        无1 R  X% e5 F* S! h9 s1 E2 v
  25. * 返回                        :        无! \2 t( k  S8 t( H  O. A
  26. * 依赖                        :        底层
    4 J9 }# O5 j. h: h, a4 `+ c- D
  27. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>8 I+ ^. p$ |8 p8 e
  28. * 时间                        :        2013-10-20; d9 R% H2 g% f/ J$ N3 ^! G4 z
  29. * 最后修改时间         :         2013-10-20
    ' d) r# l; c9 T! l% k0 U
  30. * 说明                        :         
    ( l4 L: n% J% g0 j1 T8 D7 M
  31. *************************************************************************************************************************/0 N) M) h2 M3 z3 ]
  32. void STM32FLASH_Unlock(void)
    1 W6 D) |1 P1 T
  33. {7 y" J4 C( o# O4 j0 ~
  34.         FLASH->KEYR=FLASH_KEY1;        //写入解锁序列.
    " ]: j; e  q1 z! q) M7 O& R/ B
  35.         FLASH->KEYR=FLASH_KEY2;6 c% Y# _' ?* U7 M# |
  36. }
    3 Z* k' f+ B* y, @3 q; _! Z6 M4 \
  37. 1 a- |& `$ T  q: W

  38. 9 q& m+ w. L) M3 l8 u) `

  39.   \6 q, d3 q" n
  40. /*************************************************************************************************************************
    5 @/ W0 e! h& Z4 _
  41. * 函数                        :        void STM32FLASH_Lock(void)6 r2 |8 l$ {* N* w* R
  42. * 功能                        :        上锁STM32的FLASH
    . Y4 e+ G' x1 I6 Y
  43. * 参数                        :        无
    4 |6 p) P% r- V$ ^% _& X
  44. * 返回                        :        无& g4 a& E/ q4 h! g9 X
  45. * 依赖                        :        底层. Z7 T! E% [  [6 f- m& y
  46. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>$ d8 _4 |* |( V( u
  47. * 时间                        :        2013-10-204 C2 ^  Y7 z* h, O) ~
  48. * 最后修改时间         :         2018-01-13
    3 b' l/ I- v% S: t! B& p
  49. * 说明                        :         
    5 L" a* @2 ]) j
  50. *************************************************************************************************************************/
    9 M7 L2 x' M; w3 p% |
  51. void STM32FLASH_Lock(void)' k0 @. }& ~. k( g/ K
  52. {
    1 o" D: e$ Y9 t3 B3 S: z+ y
  53.         FLASH->CR|=(u32)1<<31;                        //上锁; {5 ], y; R5 v5 p& @% h1 r
  54. }+ m" M$ U. o  A3 H( ^
  55. 4 _0 L, k  f* o" n2 v0 e& o$ F7 l8 a

  56. 6 S& P6 \" W# y5 Y& V6 q' ~; o

  57. : O/ p  D/ E) A' s3 v

  58. 9 `  t2 u: ~+ E3 O1 s
  59. /*************************************************************************************************************************2 f2 l5 N, y7 N1 Z, A  n) |8 a
  60. * 函数                        :        STM32FLASH_STATUS STM32FLASH_GetStatus(void)0 m* a0 K' t  ?, |5 f
  61. * 功能                        :        得到FLASH状态
    ' l) |0 x+ G& K# b( l) y
  62. * 参数                        :        无
    4 v! |: q1 q2 J
  63. * 返回                        :        STM32FLASH_STATUS
    5 {. Z8 w9 `' L  U: C1 x7 q
  64. * 依赖                        :        底层
    4 W) r1 [0 z, N! o
  65. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>4 x! m- M1 ]; `" z( B2 y& \8 Q1 p
  66. * 时间                        :        2013-10-20
    - M2 k  t2 D) J# c5 l
  67. * 最后修改时间         :         2018-01-03
    ( ?7 ?* E* w& c) e
  68. * 说明                        :         - @' z/ O* ~. L7 s* {# y; x% B
  69. *************************************************************************************************************************/$ `% ?( @8 B( [$ O, h9 ?2 b
  70. STM32FLASH_STATUS STM32FLASH_GetStatus(void)7 F4 V7 b: J9 M& a+ @
  71. {        6 x+ |  ~) e1 v; O1 _
  72.         u32 temp=FLASH->SR; * R: {! D( b1 O/ p
  73.         
    2 F6 f# U$ v2 x7 `
  74.         if(temp&(1<<16))return STM32FLASH_BUSY;                        //忙9 O1 m, B# I# H% W0 a
  75.         else if(temp&(1<<4))return STM32FLASH_WPRERR;        //写保护错误3 Z9 E. ?) {- Y- @
  76.         else if(temp&(1<<5))return STM32FLASH_PGAERR;        //编程对齐错误9 U& X( y% q$ e' s
  77.         else if(temp&(1<<6))return STM32FLASH_PGPERR;        //并行位数错误
    6 v# _7 e! t% L6 M  Z' V
  78.         else if(temp&(1<<7))return STM32FLASH_PGSERR;        //擦除顺序错误5 Y) d) M  \2 y; [2 O4 Z
  79.         else if(temp&(1<<1))return STM32FLASH_OPERR;        //操作错误1 v8 k1 o8 R! p: F
  80.         return STM32FLASH_OK;                                                        //操作完成
    7 y! q  L) t$ a6 @* f- ~
  81. }2 {4 ~) C# s; |' }8 Z. }
  82. + m& \/ t  m1 T& W5 k( \" A) O
  83. # |  }' _5 }+ k5 x" z
  84. # V% [8 p1 t& @8 l3 M- _
  85. /*************************************************************************************************************************( f" X+ u# s% f; J9 [
  86. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)
    8 g: \( G% g% n/ f5 r
  87. * 功能                        :        等待操作完成
    - H% U4 n/ r' b8 F9 j4 U5 B
  88. * 参数                        :        time:要延时的长短,单位us/ E7 i! @$ s0 J  _0 c8 B8 @
  89. * 返回                        :        STM32FLASH_STATUS
    / J% q$ A+ ^9 o' r
  90. * 依赖                        :        底层
    / _% T# F. k# V. S5 w3 `( z, _
  91. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>/ d( ~/ [6 a; H
  92. * 时间                        :        2013-10-20
    0 \( q$ F( W6 L8 O
  93. * 最后修改时间         :         2018-01-037 q, f6 G$ z- Z
  94. * 说明                        :         2018-03-24:增加清除看门狗功能
    ! C( d. `9 o) I2 S1 l/ ^$ y
  95. *************************************************************************************************************************/
    5 _8 ^8 w: a3 |$ f5 d
  96. STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)* v4 }5 R5 {+ W8 ~/ A) N
  97. {. [/ J; _% `) Q$ c
  98.         STM32FLASH_STATUS status;
    , |+ V; A4 {0 g2 q4 Y" Y( V0 ]
  99.         : k0 W4 ?  {' x& `+ |# H% i5 B1 V
  100.         if(time < 1) time = 1;
    # B" X& |8 O2 C
  101.         do$ s$ z9 ]) `8 A3 D/ R9 Q
  102.         {7 R7 a) i0 f- i8 N7 U$ T9 @
  103.                 status=STM32FLASH_GetStatus();                        //获取状态
    + g. e9 z2 U6 J0 Y- F: v
  104.                 if(status!=STM32FLASH_BUSY)break;                //非忙,无需等待了,直接退出." z! }, ?( y/ a
  105.                 Delay_US(1);
    ' n6 `/ e+ G" V
  106.                 time--;
    ) U6 G% @, }$ ^2 n* q5 c7 X7 F! ]! N
  107.                
    9 G* F  u  b2 X1 t% h0 b
  108. #if(SYS_WDG_EN_) //使能了看门狗
    " S! ]2 L! x# r; k  m
  109.                 IWDG_Feed();
    : J0 |) ^: [0 g' j0 H
  110. #endif //SYS_WDG_EN_        ) Y) @' }9 h" v: t4 |
  111.                 + e& r6 ~+ y: s. r; j+ l: _# e
  112.          }while(time);  u" [3 q% P  r2 H
  113. * T2 U& C+ l2 s% E* T8 u
  114.          return status;0 S! ]. B+ ^5 U: Z. Z, D! P
  115. }
    0 `% H# W& H4 H5 p' W2 L

  116. . O, J! S3 d, S; G3 G

  117. ' S* A; m6 R5 h  w! z$ }5 H5 d

  118. ! e. ~/ _: g7 g( B* |" z; E
  119. /*************************************************************************************************************************8 O; Q: J* I% J: C3 Q; j
  120. * 函数                        :        STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)3 d% K4 K$ ]7 L! }: X
  121. * 功能                        :        扇区擦除- U: P# W; N4 u- r: W: r& x
  122. * 参数                        :        sectoraddr:扇区地址,0-113 a; k$ T* H( ?2 a0 N8 x' Q
  123. * 返回                        :        STM32FLASH_STATUS3 ?& W+ z8 [6 k
  124. * 依赖                        :        底层
    ; M" ^2 {% o6 p- o) S4 y; u
  125. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>+ g7 J9 Y4 [! C0 z5 U
  126. * 时间                        :        2018-01-03
    5 c- r9 [# ?5 l/ l
  127. * 最后修改时间         :         2018-01-03
    ; Y- r! ^# C7 K8 {% R
  128. * 说明                        :         扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区- s: i  O# G1 ~7 x$ a5 p
  129.                                         128KB扇区擦除足最大2秒
    , f$ X3 p, @$ j; R. ^
  130.                                         2018-01-16:修复扇区擦除时没有解锁问题. v* l6 i- T2 o0 k* a
  131. *************************************************************************************************************************/
    8 C9 e9 P0 C, w4 h" n
  132. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr). c+ P; C7 ~4 G
  133. {, _# _( Z/ d7 B+ x4 s
  134.         STM32FLASH_STATUS status;
    + l8 K) ?$ x0 I/ D0 M
  135.         
    ! D* F2 _4 y* P) o/ X& r
  136.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    ( T& A; D$ X% ^* k1 t0 s: t
  137.         {8 S3 @; G9 B9 ~3 }' \, ?% g& H
  138.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    ( F# n$ U# C3 Z5 \: Z' e
  139.                 FLASH->SR |= FLASH->SR;
    2 j0 y+ E% R5 l1 X- e; ~) f  d
  140.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    $ _# e. n! u0 K! }. {5 i; Q
  141.         }7 F  u6 `  g0 }! Q) q
  142.         
    * s7 b, U8 I6 D4 h; t
  143.         status=STM32FLASH_WaitDone(2100000);        //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过$ a8 y' p4 H& L9 L- C5 \4 u
  144.         
      s. ?' Q5 _; |7 p$ x
  145.         STM32FLASH_Unlock();                                        //解锁 : u7 ~* G0 p5 Z# ?: R
  146.         if(status==STM32FLASH_OK)                                //没有错误
    ! e3 X9 @+ A6 z. k; x4 A2 V/ L
  147.         {
    . @7 ]8 ~  ?2 J/ X4 {
  148.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置" |' ~' m' S  @4 q- o/ y5 {( o+ c
  149.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    : Y# Q4 ?, k" c$ T) d# E
  150.                 FLASH->CR&=~(0XF<<3);                                //清除原来的设置
    ( }# m5 W& `7 S1 [0 @- Y
  151.                 FLASH->CR|=(sectoraddr&0x7)<<3;                //设置要擦除的扇区
    ) W* h9 `0 J# S9 l- K* [! q
  152.                 FLASH->CR|=1<<1;                                        //扇区擦除
    & @0 K: W$ W4 n9 P$ p
  153.                 FLASH->CR|=1<<16;                                        //开始擦除; d8 h2 b: K9 K" `! j5 t
  154.                 status=STM32FLASH_WaitDone(2300000);//等待操作结束,最大2s  0 f; t% X* _+ o
  155.                 if(status!=STM32FLASH_BUSY)                        //非忙) d# k. b9 t. J3 g! p1 y& `
  156.                 {, l; N3 z  ]4 p
  157.                         FLASH->CR&=~(1<<1);                                //清除扇区擦除标志.
    1 X8 y! o% ^+ C# s
  158.                 }
    * U8 d( b4 m/ e2 r. C
  159.         }
    8 \5 G9 e3 m& D7 s
  160.         //DEBUG("扇区擦除状态:%d\r\n", status);. X$ K1 y8 r0 D% w6 n
  161.         //DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n", FLASH->SR, FLASH->CR);
    3 c3 t5 i& u7 U, M, F8 S) _1 f! K5 l& h( a
  162.         ; s- a% E( M/ F- I
  163.         STM32FLASH_Lock();                                                //上锁" f& F% G7 a- Z! l! \& e
  164.         if(status != STM32FLASH_OK)
    ( U& M  V+ \: D" _1 Y; Z/ [& p
  165.         {
    8 N9 J$ R4 e. F' x& K
  166.                 DEBUG("擦除扇区%d失败(错误:%d) FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",sectoraddr, status, FLASH->SR, FLASH->CR);; w1 D3 l. A' h
  167.         }
    ; G5 K4 `! Y# M# q5 N" Y: B2 V
  168. 4 l% f6 _' X  P6 s8 h4 u
  169.         return status;                                                        //返回状态1 ^! e- ~$ A& h- {! G
  170. }! e  y' J- d5 i' x; s

  171. & {4 s% `8 n& V4 j+ g
  172. # y# ]5 e1 W$ p- q. ?* k" O- A' u

  173. ) k0 K7 u5 U' x' k3 n

  174. 3 \; p" O2 _" b; j
  175. /*************************************************************************************************************************% {  i" B: \' a& _5 {
  176. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)& t' P6 W4 c' K9 d. l
  177. * 功能                        :        在FLASH指定地址写入一个字的数据(32bit写入)8 a$ J8 C7 ]* G- J2 D) e2 b
  178. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据
    : R4 ?& A% z7 L( q9 a% u* H8 u
  179. * 返回                        :        STM32FLASH_STATUS8 P; r/ N/ ?% Y/ O
  180. * 依赖                        :        底层# d2 s. E6 G8 I3 n" d$ m
  181. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    1 S  C6 U, v/ U/ E+ `8 K! D' e
  182. * 时间                        :        2018-01-03
    % W8 `+ S* b! Q2 l: `
  183. * 最后修改时间         :         2018-01-03' n$ j; G  O) u. r; p1 l- G
  184. * 说明                        :         警告,地址必须为4的倍数
    0 x4 G6 E9 J" p: _" q$ k/ G
  185.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    ! }+ d: R& r  z
  186.                                         不会判断是否能写入
    $ _) M) E/ ]7 Y6 d1 X! i. O+ }/ P
  187. *************************************************************************************************************************/
    ) `7 c, C/ F$ [+ D! w# z6 [
  188. STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)' q4 O" j  A9 B' p' i) B- u( B5 w9 ]
  189. {
    + ^" X" e0 U# K  N, b. v; u9 |
  190.         STM32FLASH_STATUS status;0 w' k; z! n2 ]) V3 x1 N
  191.         
    # o" o; W( s  Z7 y9 @+ Z
  192.         status=STM32FLASH_WaitDone(200);                 //判断状态+ o5 c, p  _7 d' x- o" E% H6 t
  193.         if(status==STM32FLASH_OK)                                //没有错误
    : }5 g' _9 ^( ~) Z& Y3 U
  194.         {. P# p+ C" K2 m% C$ j3 g
  195.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置2 R; O1 Q' z, N' Y
  196.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!$ @8 P0 a7 ^- R; ?! l  b0 ?7 `" L
  197.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误
    ; [6 \  `2 M, x( D+ B$ `
  198.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        ' q- O# N4 d+ u5 k0 Y% H
  199.                 *(vu32*)faddr=data;                                        //写入数据0 D: W/ y& e) v  J. u
  200.                 status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.- e5 E$ J2 J6 l( `5 n+ I$ N" F& C
  201.                 if(status!=STM32FLASH_BUSY)                        //非忙
    1 _8 ?  x! S- n
  202.                 {        7 x2 e. Y7 K* L; h# U8 V" ^; v+ \' m
  203.                         FLASH->CR&=~(1<<0);                                //清除PG位
    / ]  |/ b" u. e4 j5 u
  204.                 }# {. T; p- `. a. ?% G  W
  205.         }
    6 y/ k" {' u, ?2 B; k+ D& \
  206. 8 w! q& c  o* y$ ~( F: `
  207.         if(status != STM32FLASH_OK)% u/ x3 H$ U5 r2 t
  208.         {( u, m; `9 n# w& g4 y3 [' |
  209.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
    ' t6 J" x8 L7 O- w5 a. i) R: D- P
  210.         }
    ) h: f( D# b6 W  W3 {2 a9 B  t
  211.         / L! F& _3 N! Z+ ~; k! w
  212.         return status;6 ~) H& k8 M* y4 x# o& r
  213. } + F( }/ Z$ K$ x& m- X$ v  R7 w5 @

  214. 2 ]/ L0 N6 V' g4 T5 v
  215. % C' a* {3 ^, r4 g" Y
  216. /*************************************************************************************************************************5 M9 _7 L& ~) Q& Z; [1 B" v% @3 ]
  217. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)
    7 w5 O+ y9 W/ t2 Y% k( B& k2 t. B
  218. * 功能                        :        在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)
    " N' V0 a% o( W9 v& J2 f8 c8 D7 U) l
  219. * 参数                        :        faddr:指定地址(此地址必须为4的倍数);data:要写入的数据2 K. V4 I( o; Q# f
  220. * 返回                        :        STM32FLASH_STATUS
    1 G) k  {6 |0 J, G1 ^
  221. * 依赖                        :        底层' e4 W1 X. n1 v
  222. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    5 V' v- o- ~$ T7 Q) `% D
  223. * 时间                        :        2020-02-08
    / k2 r5 z2 k0 C) k! a! p
  224. * 最后修改时间         :         2020-02-08. Q* W1 |# d; Y# g( N
  225. * 说明                        :         警告,地址必须为4的倍数
    3 p, P/ S" y9 s' M  @1 l: `! B2 l2 w
  226.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    3 b9 T+ n9 G; t5 i3 A
  227.                                         不会判断是否能写入+ i" P# o' n, n8 y
  228. *************************************************************************************************************************/
    ' s4 ]) \0 D5 k8 [* f
  229. STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)8 x" c# l9 m/ y
  230. {
    , ], S8 Y' Z/ V* ?/ p
  231.         STM32FLASH_STATUS status;6 g4 O% o7 H! c! Y% A
  232. # J* h2 H; E3 ]" T
  233.         status=STM32FLASH_WaitDone(200);                 //判断状态
    3 V3 S/ @' L4 }, K7 q* H
  234.         if(status==STM32FLASH_OK)                                //没有错误
    . V; J& v* R! Z4 n
  235.         {. f0 ]' Q, ?8 w3 C% A
  236.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置/ N; r) h% J/ E9 l% l2 L9 Z9 A
  237.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    & Q2 Y& e* e6 t5 \0 E
  238.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误3 s3 [; G; }/ u( t8 _- Q
  239.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    : ?. [0 Y; Q3 S* g: u9 g
  240.                 while(dWordCount --)
    8 T0 ?0 b/ v9 G$ f9 F; E6 @7 G
  241.                 {
    , E; V' n  `0 B
  242.                         *(vu32*)faddr=*data++;                                //写入数据
    * t1 v& F3 ?6 o7 Q
  243.                         faddr +=4;                                                        //地址自增+4' n* T7 {* J' p1 T& q( H* L6 `3 F
  244.                         status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.4 ~1 M9 K) I1 d  e  ~% G. v+ N
  245.                         if(status!=STM32FLASH_OK)                        //有错误
    , ^' W- c( a8 @3 b6 M
  246.                         {, l4 O! q6 j$ }+ i! Z: A6 [
  247.                                 break;
    9 u( n. c8 F# ^) G$ Z3 L
  248.                         }/ }' d0 x" u; p% S) l1 s1 \+ c( E( r
  249.                 }5 X2 M& }/ k. I. a2 _

  250. . _' ^( m8 _. o7 g; V" ^' w
  251.                 if(status!=STM32FLASH_BUSY)                        //非忙8 ^7 |: C' B5 O4 r% j" _% D
  252.                 {        / ^7 h* ?# F1 {( f% x7 y) ]( L
  253.                         FLASH->CR&=~(1<<0);                                //清除PG位% F* ~$ P8 v# H% F9 N
  254.                 }
    9 H3 [! H! D+ @- g6 T2 `
  255.         }
    + E- j6 R, S5 [
  256. 8 Q& s0 _+ N: C+ q- {& [1 J
  257.         if(status != STM32FLASH_OK)' Y3 G* J4 G/ ]6 E
  258.         {
    ( V* @# l/ r* z1 N
  259.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);5 }; v# ?% Z! F; }
  260.         }
    % m& r. R( L3 x" P
  261.         
    3 ?' [" P1 M2 S% W0 c& D8 M
  262.         return status;- T) I& ?9 `8 R  k! _' _' K
  263. }
    5 v; v; `5 q$ r

  264. 2 Z& W9 u2 `5 z

  265. 2 O: |- ]  Q, g  Y
  266. /*************************************************************************************************************************) L" \( _% c2 G! C0 R1 G
  267. * 函数                        :        u32 STM32FLASH_ReadWord(u32 faddr)
    , U1 `( Z0 b( C( P& H' l# u
  268. * 功能                        :        读取指定地址的一个字(32位数据)
    7 P( _9 v4 s6 Q& t( e* N
  269. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);
    % {0 O; a) K9 N. ?! w0 s8 w
  270. * 返回                        :        数据
    . m/ y, b3 O* A4 F2 X& I! p. Z
  271. * 依赖                        :        底层3 N/ W' z. Y! Q( `  Y( w. [% i
  272. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    $ S7 l1 g/ V# [2 G, d8 a5 l
  273. * 时间                        :        2018-01-03
    4 _2 J8 _7 W5 ?, f7 ?* J- r
  274. * 最后修改时间         :         2018-01-03
    6 ~( J8 u8 T: P0 h" o
  275. * 说明                        :         警告:地址必须是4的整数倍
    " Z7 B. d) _0 Q+ O- x4 i# n1 X! D
  276. *************************************************************************************************************************/
    $ d5 K& Q( B# \$ @* j2 s
  277. __inline u32 STM32FLASH_ReadWord(u32 faddr)
    / Y  M+ O& z. T+ G
  278. {; T( W% F, T1 L6 e
  279.         return *(vu32*)faddr; * Q/ Q: T! W( I" o
  280. }% ~* f! s. `3 g7 q
  281. + `6 }" ~7 ?  R# Y# L2 a. A' _
  282. 0 a# P& f; s3 b5 S3 c8 x! X
  283. /*************************************************************************************************************************: w5 L, v  M% ?8 b/ D
  284. * 函数                        :        u8 STM32FLASH_GetFlashSector(u32 faddr)
    % s+ S  O: H3 X) f8 Q! Z
  285. * 功能                        :        获取某个地址所在的扇区+ T, t. M% G+ D* Z% h/ p2 J0 C
  286. * 参数                        :        faddr:指定地址8 X0 v* P8 A, S; p* c4 g; C( A
  287. * 返回                        :        删除编号,0-6,如果超出了也会限制到6- t1 j- g# I1 |1 ^. L4 `% G
  288. * 依赖                        :        底层
    # p+ N0 j; V3 D; p$ ?4 X
  289. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ) D; f5 N3 i5 ~1 e7 `
  290. * 时间                        :        2018-01-03
    ! s* A9 U4 \9 V6 k0 e/ n6 ]
  291. * 最后修改时间         :         2018-01-03' i# U4 I1 n5 U2 Q  v. j: F: y
  292. * 说明                        :         地址请不要超出范围
    # ^! W+ t+ P* O9 \7 B8 X% E
  293. *************************************************************************************************************************/; ?7 `! R, e3 I* A; U$ s
  294. u8 STM32FLASH_GetFlashSector(u32 faddr)
    3 W9 Z4 c" S& M9 N2 _
  295. {- {: W" l: T: x: G4 A
  296.         if(faddr<ADDR_FLASH_SECTOR_1)                return 0;- r3 W4 Q7 Z- P. W& M
  297.         else if(faddr<ADDR_FLASH_SECTOR_2)        return 1;
    6 A$ @) w- a& v. C# y
  298.         else if(faddr<ADDR_FLASH_SECTOR_3)        return 2;# C8 N. ]5 X8 t( Q: b/ Z
  299.         else if(faddr<ADDR_FLASH_SECTOR_4)        return 3;
    % e5 D5 {* A0 M: l/ t6 R9 W
  300.         else if(faddr<ADDR_FLASH_SECTOR_5)        return 4;9 i1 W! ]# o0 h
  301.         else if(faddr<ADDR_FLASH_SECTOR_6)        return 5;
    4 W) A' n. q& m6 [. F
  302.         else if(faddr<ADDR_FLASH_SECTOR_7)        return 6;
    - M3 v% T1 R  P% a( {* n7 N
  303.         else return 7;        
    - G, f2 u2 f/ I; n8 L  l6 |8 D. W
  304. }6 c) {6 K) g" K% ~

  305. ( Y& m# \; J* @: p( B) f6 ^
  306. 5 L5 D) a( ?. n8 q  N- ^: h2 d
  307. /*************************************************************************************************************************
    " [3 b! j; K! m3 ~4 W9 x
  308. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  1 }0 X, O3 D' _1 B
  309. * 功能                        :        不检查的写入6 l) O5 K, U  p% w
  310. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数
    1 z3 o/ c% w4 K/ y. a4 M: c6 u1 x
  311. * 返回                        :        状态
    / u' ~% _# q3 K9 o8 J  d2 j/ I, R
  312. * 依赖                        :        底层9 H& g+ c/ B5 g& _
  313. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    . v( G- r9 E4 m' i7 W' r
  314. * 时间                        :        2013-10-20- h! Q8 D# S" y+ s' n
  315. * 最后修改时间         :         2018-01-03
    ' w2 k" V1 Z! p2 d
  316. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)
      q/ x3 {6 E5 P
  317. *************************************************************************************************************************/
    / f# r6 g- [4 K* k, K0 q6 J  \
  318. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   
    , T& P, b/ N$ J, }* d6 K
  319. {                                          
    3 `* w& P, x3 }5 g1 Q
  320.         STM32FLASH_STATUS status;5 J# j$ H5 v; S* W1 E8 o6 Z
  321.         . }! k5 d5 M& |) i/ c
  322.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误7 d8 I% s4 A: p4 c
  323.         STM32FLASH_Unlock();                                                //解锁 7 q, B7 x% d( M
  324.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    % Y1 e- q8 g2 _! \% K; I
  325.         {& t" \8 \; H' k4 O% A
  326.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);. P0 @. k( T: y# a
  327.                 FLASH->SR |= FLASH->SR;
    % b! d' p9 Q4 O4 ^, G3 A
  328.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);* u0 Q% P0 e8 ]9 r. V9 C
  329.         }
    " S0 T# O: v0 ?3 u* T$ d" [4 L3 r6 g
  330.         status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据. L& l  g, c. f! y+ m7 B* k) G
  331.         STM32FLASH_Lock();                                                        //上锁
    . j" @$ B/ i/ E0 w5 p$ W. ]9 C, L7 Q
  332.         return status;5 o8 a' D4 f3 h; I: ?; P! N
  333. } / w2 t4 F" d8 G

  334. $ f2 p- K4 h3 b! m$ M

  335. 2 F- x) J! g$ e* G" p3 ~/ b
  336. /*************************************************************************************************************************$ R+ w: D  g3 x8 j" U3 R
  337. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   % H. q: Z8 b! e& K9 y3 Z- p
  338. * 功能                        :        不检查的写入一个字
    ! i. s8 x$ `! M  N4 P' X
  339. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);data:要写入的数据值
    & S$ `% o8 v; c+ }" P
  340. * 返回                        :        状态
    ; _5 o- X# j- Y6 y
  341. * 依赖                        :        底层/ X  k9 i( c1 q* T5 Q) l8 G3 Q
  342. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>- J+ v: p  s# x/ U1 K2 X
  343. * 时间                        :        2020-02-08% r% M) l8 j; F6 U9 ]: o
  344. * 最后修改时间         :         2020-02-08: A" W' m1 B# p( s  a
  345. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)
    # @. s7 E+ j9 j% L
  346. *************************************************************************************************************************/
    , i5 x5 ^" @4 _- h. E1 r) o# `; r
  347. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   6 e8 U/ u9 y  \# d& M
  348. {                                           6 k* t% x0 Q; Y8 M
  349.         STM32FLASH_STATUS status;
    1 ]/ G4 l# J3 w- `; j. g3 A
  350.         % Z: D9 y. ^0 E5 o
  351.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误
    ' W  u7 B3 d: ~
  352.         STM32FLASH_Unlock();                                                                                                        //解锁 8 X1 U& v9 t* a5 D8 e6 v/ a. ^) y7 S
  353.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    , g2 l0 W) l4 A! |% e
  354.         {8 s  D+ u8 @) z: f' s2 N
  355.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    * ^# X1 D% a/ O
  356.                 FLASH->SR |= FLASH->SR;
    0 O+ ?* Z8 h3 R$ K) N
  357.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);' d* t  Y" n9 e7 i
  358.         }* n( S/ p" z' ^# W1 e
  359.         status = STM32FLASH_WritedWord(WriteAddr, data);                                                //写入1个字的数据+ U3 {( I+ l5 j! ?+ l  p% J
  360.         STM32FLASH_Lock();                                                                                                                //上锁
    4 x3 g3 \' B- [  e# x4 ]
  361.         return status;
    , F$ m6 ~3 F' @  \! g5 x
  362. } ! e+ A0 r3 X* G! d8 O2 k) [8 u

  363. % n* c1 ]& V7 f" }
  364. . V1 d, |4 t) A
  365. /*************************************************************************************************************************
    2 G6 T$ P3 C/ D) ?+ }2 N9 O
  366. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        
    2 m$ @/ ~1 Q, R* x9 ~6 x8 y3 }& C
  367. * 功能                        :        从指定地址开始写入指定长度的数据(数据长度字为单位)
    4 o4 m6 E! b8 Y: u& T! E. Q5 r* d
  368. * 参数                        :        WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.), W4 o: L, q! V4 Q2 {( ]
  369. * 返回                        :        0:完成;1:忙;2:错误;3:写保护& ]6 s3 L* P1 F5 f' L
  370. * 依赖                        :        底层7 ]( C( A2 S1 i0 i2 @
  371. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>% P! p$ x* r7 C& Q+ q8 E
  372. * 时间                        :        2013-10-20+ p5 o/ B/ r8 i
  373. * 最后修改时间         :         2016-01-07, D) a& |; u/ L* a2 r
  374. * 说明                        :         警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据
    0 J! \' q( w" A8 r4 `
  375.                                         如果需要保存其他的数据,请在应用层进行实现(比如:先读取扇区,修改扇区,擦除扇区,写入扇区,需要大内存支持)9 K$ o. o/ ^8 i
  376. *************************************************************************************************************************/ + g/ X! E0 y6 g. W1 Z
  377. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        
    + V( `( ]8 g5 F5 n- q* }* l
  378. {
    4 L& \0 H: f, [- Q
  379.         STM32FLASH_STATUS status;7 L, |2 t( `  @' F( N) B: ?$ o0 ^
  380.         u32 addrx=0;. p" S4 C( f% ~7 Y/ w0 z
  381.         u32 endaddr=0;        9 U; w% }2 ^! z% |% X
  382.          
    & k8 _- T% {/ `+ C5 }
  383.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR;        //非法地址, b3 l, M6 S* N$ D: _+ C
  384.         * J) {5 v( a1 V' M
  385.          FLASH->ACR&=~(1<<10);                                                                //FLASH擦除期间,必须禁止数据缓存!!!搞了我两晚上才发现这个问题!
      L4 j; O9 [* W, E& U5 P2 u
  386.         addrx=WriteAddr;                                                                        //写入的起始地址6 ?7 l/ a: I% k1 d- |3 V
  387.         endaddr=WriteAddr+NumToWrite*4;                                                //写入的结束地址
    ; A* Y0 S  t# I3 O  ]
  388.         / Y2 s8 c- \% B( \, V
  389.         if(addrx<0X1FFF0000)                                                                //只有主存储区,才需要执行擦除操作!!
    1 W- G1 l7 _3 T3 e6 A. ?  W
  390.         {: F5 P5 X2 S9 B% U, r; I5 _
  391.                 while(addrx<endaddr)                                                        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)' n6 W0 e  z9 }/ J4 Z( M
  392.                 {$ [5 l) P5 {5 ^% H) Z1 x' a8 `( U
  393.                         if(STM32FLASH_ReadWord(addrx)!=0XFFFFFFFF)        //有非0XFFFFFFFF的地方,要擦除这个扇区
    ) x$ R$ J# Q. z+ n8 J+ f: v
  394.                         {   0 O) N  C5 u! w3 P
  395.                                 status=STM32FLASH_EraseSector(STM32FLASH_GetFlashSector(addrx));
    ; f/ j+ k% ^* E5 c8 L- C
  396.                                 if(status != STM32FLASH_OK)break;                //发生错误了
    , [0 u$ w" Q8 H) w
  397.                         }else addrx+=4;
    + r% ^) S7 R7 j
  398.                 }
    . T& r5 c5 C6 ~; ~2 t8 H3 r6 ?
  399.         }
    8 y  V3 X  A  c2 k- X. B; S4 d4 y2 d+ |
  400.         if(status==STM32FLASH_OK)& e% h3 `0 a% v; q( t
  401.         {( ?6 m0 j, |! g7 z
  402.                 STM32FLASH_Unlock();                                                        //解锁 7 b* }& i; @2 g- S4 z# k
  403.                 if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现) y) U" X; j! I0 N: P* S, E
  404.                 {& R7 ?" H! K: Y& j* T: E; w0 j
  405.                         DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    : e- V# V0 H3 a5 |- E1 n/ o& F
  406.                         FLASH->SR |= FLASH->SR;
    4 G3 X9 s, i% Y0 x- J
  407.                         DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    * q6 p# j) U4 ]2 y
  408.                 }
    1 k5 m# M) t8 r9 I( G! r
  409.                 status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据
    , H# P( E) u# ~
  410.                 STM32FLASH_Lock();                                                                //上锁
    5 j6 ?( r; V7 D/ n- v' t& K
  411.         }) ~1 _7 N1 O7 F" e5 ~3 c
  412.         FLASH->ACR|=1<<10;                                                                        //FLASH擦除结束,开启数据fetch
    , }/ p- @% _% \2 i& c4 T4 x9 V
  413.         
    1 b$ l; D. i" L  M; k# ]
  414.         - g' p& h4 G( G8 y& |( |& s& Q' J1 y) w
  415.         return status;$ q1 A& t# T1 J* ^! R
  416. }  p+ m) f& ^$ U/ `7 z
  417. 0 x1 U8 ?! O) J  Z" l: r

  418. * I  P0 O' A9 n& W5 r3 P
  419. & T: `% \0 P* x) f) S
  420. # u% x8 @  K; t
  421. 1 u) W2 p4 O( e; j6 p
  422. /*************************************************************************************************************************
    4 |  w5 Q2 ^1 w, r9 Q2 Q$ s
  423. * 函数                        :        u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)
    ) O. f/ g, q1 b& s
  424. * 功能                        :        从指定地址开始读出指定长度的数据
    ! g" N8 [6 @# c
  425. * 参数                        :        ReadAddr:起始地址;pBuffer:数据指针;NumToWrite:字(32位)数
    " U9 d/ g/ {2 h% a) @7 l
  426. * 返回                        :        读取的数据长度(字为单位)
    ! T) R+ i4 e6 r# V, J# o
  427. * 依赖                        :        底层+ ~6 z4 K  M1 D7 t" I" A
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>! o4 H) q. Z1 _  e0 b
  429. * 时间                        :        2013-10-20+ U" J( T* [. Q: {9 ?2 p$ N% v  q
  430. * 最后修改时间         :         2016-01-076 w; }8 \) s: x& f+ m# ^8 j
  431. * 说明                        :         地址必须为4对齐
    4 ~2 I3 z8 L+ k
  432. *************************************************************************************************************************/
    % s( R' z7 p3 q* t9 O
  433. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)             \7 |3 z5 a, ~& z4 ?) s
  434. {
    # l$ Q# {% E7 h" m9 ?
  435.         u16 i;
    4 ?& O5 K  D# e. Z' G
  436.         u16 cnt = 0;
    1 z9 k( U8 K0 e9 t- y; V$ s
  437.         6 i7 K9 w' M, [9 t0 P4 Z, X
  438.         if(ReadAddr<STM32_FLASH_BASE||ReadAddr%4)return 0;        //非法地址5 n; [. c* z$ D3 T( D
  439.         
    ( V* S9 b. @5 @& |! m7 }" L, m
  440.         for(i=0;i<NumToRead;i++)/ c, }$ ~6 u% A; V8 b, h
  441.         {
    ) h& q5 h  W- z4 X1 S: ^# p
  442.                 pBuffer=STM32FLASH_ReadWord(ReadAddr);                //读取4个字节.5 K+ R9 e* W1 P
  443.                 cnt++;
    : Y1 i& C$ h4 [+ W* E
  444.                 ReadAddr+=4;                                                                        //偏移4个字节.        2 G& t. u4 o- W" ]
  445.         }
      w2 q- V+ [5 ?  ~3 \
  446.         return cnt;
    ( K" v+ T# H7 w0 K8 f
  447. }
    * d  f6 r0 C2 X: a( L& t0 F2 s+ x
  448. 7 P! N7 B* P4 m4 H7 z; Q

  449. 7 n# d* U% j9 I2 R# C8 Y! f" n! o
  450. /*************************************************************************************************************! S% u" a5 K1 c% N2 x4 u$ y
  451. * 文件名:                        stm32f7_flash.H
    ! L# g- G6 R9 V7 l
  452. * 功能:                        STM32F7 内部FLASH编程驱动函数; [( g, L/ [+ Z: Z
  453. * 作者:                        <a href="mailto:cp1300@139.com" style="">cp1300@139.com</a>
    5 ~$ q; j  S/ _7 @5 N  f- X3 ~
  454. * 创建时间:                2013-10-20) h* @! t- c$ b1 N6 |
  455. * 最后修改时间:        2020-02-079 A0 p3 D# b, X9 Y) j$ X/ o& e, ?
  456. * 详细:                        用于STM32F7内部flash读写驱动
    : w; r; u* t! I6 R1 R( r
  457. *************************************************************************************************************/
    6 g0 `) U9 k/ H/ g* c! t( r/ ?5 g! b
  458. #ifndef __STM32F7_FLASH_H__
    5 w5 c/ ~9 u1 A* `% I
  459. #define __STM32F7_FLASH_H__% V" [4 d9 Z6 q  H
  460. #include "system.h"  5 o8 O7 X3 ]% c; f; J1 B
  461. * C) \8 s2 ?  p- I. @
  462. //FLASH起始地址- d& J- j# [) _) t# |/ t) ^% V) z
  463. #define STM32_FLASH_BASE                 0x08000000                         //STM32 FLASH的起始地址6 k, c. G- k4 O7 d2 p2 h) T; q3 V! U
  464. * \7 {) s4 I6 Z9 l2 C& l
  465. //FLASH 扇区的起始地址
    6 \' Y4 s- l3 V
  466. #define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)         //扇区0起始地址, 32 Kbytes  ! @5 O1 p. C6 ~6 b' C
  467. #define ADDR_FLASH_SECTOR_1     ((u32)0x08008000)         //扇区1起始地址, 32 Kbytes  . V  t2 y5 h5 Z7 s) _3 ?, Z5 X
  468. #define ADDR_FLASH_SECTOR_2     ((u32)0x08010000)         //扇区2起始地址, 32 Kbytes  
    " A3 J" j. i6 n' {6 w! S
  469. #define ADDR_FLASH_SECTOR_3     ((u32)0x08018000)         //扇区3起始地址, 32 Kbytes  
    . f0 _) E) B1 a3 |) x- {( N" I$ m
  470. #define ADDR_FLASH_SECTOR_4     ((u32)0x08020000)         //扇区4起始地址, 128 Kbytes  1 w" j0 f# Z1 l8 j
  471. #define ADDR_FLASH_SECTOR_5     ((u32)0x08040000)         //扇区5起始地址, 256 Kbytes  
    8 L  @3 ?) K0 P9 \5 w! H
  472. #define ADDR_FLASH_SECTOR_6     ((u32)0x08080000)         //扇区6起始地址, 256 Kbytes  
    6 f3 E% [8 _2 c5 C. B
  473. #define ADDR_FLASH_SECTOR_7     ((u32)0x080C0000)         //扇区7起始地址, 256 Kbytes  
    * ?, x: j% r9 K+ L" ?
  474. 8 i  H: D1 c0 F5 H4 [& q

  475. $ f) y% t+ q. p5 r3 ~
  476. //FLASH解锁键值
    # x. \1 R. z8 I2 @# r
  477. #define RDP_KEY                  0x00A5
    ( c8 J0 h( q" U, _  I
  478. #define FLASH_KEY1               0X45670123
    1 u2 P+ u0 ^+ a$ ~
  479. #define FLASH_KEY2               0XCDEF89AB0 i# b9 ^$ E) t& C' y
  480. #define FLASH_OPT_KEY1           0x08192A3B& s& X% c: n/ g% C
  481. #define FLASH_OPT_KEY2                         0x4C5D6E7F
    5 l5 k2 y& f/ l2 `
  482. 4 [/ ?, F: m# `: R  e
  483. //STM32F7 Flash操作状态) e- J& u& o# U/ w6 {
  484. typedef enum
    4 T" e* }9 a2 D4 W, k# i' K+ t$ Z8 U
  485. {; `. r" g' K' D
  486.         STM32FLASH_OK                        =        0,        //操作完成
    3 Y! f& G5 {: I0 ^- U2 Z9 s& J
  487.         STM32FLASH_BUSY                        =        1,        //忙
      B  ]/ y) |$ C, _7 l
  488.         STM32FLASH_WPRERR                =        2,        //写保护错误
    5 p0 v: r( H( ~, P0 V  A
  489.         STM32FLASH_PGAERR                =        3,        //编程对齐错误,必须128位对齐$ E% X- w" Y8 ~# R5 d- ?
  490.         STM32FLASH_PGPERR                =        4,        //并行位数错误
      W& A3 u8 S3 X. A8 i5 R. O! O
  491.         STM32FLASH_PGSERR                =        5,        //擦除顺序错误/ C8 }0 N; S& @4 A4 J3 t  Y
  492.         STM32FLASH_OPERR                 =        6,        //操作错误$ N+ r* ~0 n, ^: J( a/ D
  493. }STM32FLASH_STATUS;) S" C, I  {: p) t5 B

  494. , l& ^" P. A% k9 T& [* [  E
  495. //常用接口
    3 A# `9 _) a+ w( J: T
  496. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr);                                                                  //擦除扇区
    / b1 k6 g- a- {' q
  497. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite) ; //不检查的写入多个字的数据" t* R3 d. v- p# i
  498. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data) ;                                //不检查的写入一个字的数据
    3 U9 E7 `. S. x0 @3 i( ^, M7 }
  499. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite);                        //从指定地址开始写入指定长度的数据(数据长度字为单位)5 n/ n% Y6 p. L, _
  500. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead);                                                        //从指定地址开始读出指定长度的数据
    3 Y( ?' _% P2 `8 M% n6 t$ {/ A  F

  501. , c" E" ~/ c0 u; k- N( u
  502. //不常用接口7 i8 P8 d+ R, X" N8 P
  503. void STM32FLASH_Unlock(void);                                                                                                                        //FLASH解锁4 K" p1 W+ c" j3 q/ g9 B( i, v
  504. void STM32FLASH_Lock(void);                                                                                                                                  //FLASH上锁7 I5 ?. f  W" O% c9 |3 K- r
  505. STM32FLASH_STATUS STM32FLASH_GetStatus(void);                                                                                          //获得状态" e  t* g8 X. D

  506. ) P. m$ Z- O1 J: c; o$ v9 n2 k2 A

  507.   }4 ?+ G6 x! E8 }' K! w# u: p3 m
  508. #endif        //__STM32F7_FLASH_H__
    " x  ?6 t+ F( t0 i3 v; h
  509. ! g3 R8 h( s+ `6 W; O- }# F* t' B
复制代码
# d- ?' N% e) g/ o+ q9 m9 \
收藏 评论0 发布时间:2021-12-11 12:00

举报

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