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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
总体来说与STM32F4操作是一样的,就是扇区大小变化了,测试过程中发现当PG=1之后立即写入数据到flash会造成编程顺序错误,通过增加一个nop的延时即可解决此问题,还可以通过将多个数据连续烧写的方式避免此问题,就是当PG=1之后,把所有数据都烧写完成后再将PG=0,不要频繁的开关。
1 [" j" z" G; Y7 I1 ]9 y
& _3 g# G  E0 h
  1. /*************************************************************************************************************6 I. ?9 Y3 M% q- N* b* D0 ^
  2. * 文件名:                        stm32f7_flash.c% S) m* C9 ]/ y+ m$ v- L( t+ r
  3. * 功能:                        STM32F7 内部FLASH编程驱动函数
    7 D8 d6 {5 a9 Z9 o
  4. * 作者:                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>- v0 s6 w. f1 [0 g. _
  5. * 创建时间:                2013-10-20
    2 c! z1 S% P! d, q/ n
  6. * 最后修改时间:        2020-02-07
    8 u3 v) V+ c; f& t
  7. * 详细:                        用于STM32F7内部flash读写驱动
    $ o1 v  Z. r4 X4 K/ v5 Y5 b( p/ R
  8.                                         默认为3.3V供电,并且宽度为32bit;
    * l- q" ]' ]2 r  S) W6 {; f
  9.                                         扇区擦除最长时间:32KB扇区500ms;128KB扇区1.1秒;256KB扇区:2秒# U4 _* V$ I5 B6 |0 G# d7 g2 G
  10.                                         修复STM32F7开始写入数据时,PG=1后没有延时导致异常,增加批量写入多个字的数据函数STM32FLASH_WriteMultipledWord()支持。+ O( e  U# `# m+ r4 Y! M2 @- o7 I
  11. *************************************************************************************************************/4 w  Z9 _2 O! ^2 F6 I0 g
  12. #include "stm32f7_flash.h"
    ! k$ ^" \9 k! n- t7 i  J) `' ~
  13. #include "system.h"* D/ A7 _. q4 {3 ?, z" b6 I% R; N
  14. #if(SYS_WDG_EN_) //使能了看门狗( u' h6 e0 E3 ~4 b5 E, E
  15. #include "wdg.h"
    2 t* F) v( s% I' g% q
  16. #endif //SYS_WDG_EN_6 _3 V6 R  \1 k% `" d

  17. 7 [' S2 O) ~$ n2 F

  18. 9 l/ V6 N/ s3 R* j  b+ S

  19. - \" e4 {% r( A" ?' I# L
  20. 5 Y5 C: ~% K" @  [
  21. /*************************************************************************************************************************
    1 u5 f% O0 R& h# }1 u- @3 {- G
  22. * 函数                        :        void STM32FLASH_Unlock(void)" C8 N" R8 j1 g3 e) v" c+ v! f
  23. * 功能                        :        解锁STM32的FLASH& ^* j2 v# |, v( x+ R. {
  24. * 参数                        :        无; }- q: y1 ^# z. k
  25. * 返回                        :        无: y. [. G( ?6 w9 q, ]9 X
  26. * 依赖                        :        底层8 O  \( D3 }  |' s
  27. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>3 D8 A$ v, m; v  d* o
  28. * 时间                        :        2013-10-20+ u0 y* J7 a: C0 \. Q# |
  29. * 最后修改时间         :         2013-10-206 t4 ~" M, s5 |: E' B( m
  30. * 说明                        :         
    / N  Z" \; x& K  U! S( ~/ v
  31. *************************************************************************************************************************/
    9 L6 |5 b. e) B( Y! {* e
  32. void STM32FLASH_Unlock(void)
    4 V* [- d, @, G
  33. {/ x4 ]2 S; H" G0 b& U
  34.         FLASH->KEYR=FLASH_KEY1;        //写入解锁序列.$ q: R+ ?4 l# d& x) Y) [
  35.         FLASH->KEYR=FLASH_KEY2;2 h# S9 U( ~  x1 c# y
  36. }! u5 ^% r4 o' c3 E( F

  37. 1 D0 F; A& C. Q# F

  38. 8 a/ f$ m& N  N$ J8 k4 `, N
  39. 0 G9 x$ I8 D; J+ F- V+ t; L' V
  40. /*************************************************************************************************************************6 W4 Q. D# a: B3 |# ^
  41. * 函数                        :        void STM32FLASH_Lock(void): p) ^( m2 G# \) ~6 s
  42. * 功能                        :        上锁STM32的FLASH6 u9 u( l7 s2 Z
  43. * 参数                        :        无$ R/ w! H: }" W! ?8 M
  44. * 返回                        :        无6 d/ v, H5 i) W2 |5 {
  45. * 依赖                        :        底层! g" F2 y& N' O2 o
  46. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    : _* l7 R9 j' d5 W
  47. * 时间                        :        2013-10-203 s* P( a2 E' F
  48. * 最后修改时间         :         2018-01-13. b3 q1 G) B. c: }+ o4 a: d! y3 e
  49. * 说明                        :         4 [# Q3 r/ u3 o+ P" S, j( v
  50. *************************************************************************************************************************/" w7 `8 Y# t' C  d4 j$ n- M
  51. void STM32FLASH_Lock(void)
    $ W6 U$ z& _1 F6 G( O( f# }
  52. {9 v( f+ C- F  ?) t4 ?: a3 F
  53.         FLASH->CR|=(u32)1<<31;                        //上锁
    : M, _* G: C0 \1 C; z
  54. }: D5 n' V' j: S1 ?- @6 e7 o
  55. # b5 M* a  \  M! h
  56. 8 z  i; d1 P; d2 V# j
  57. : ?2 c5 b2 W5 c" r9 Z

  58. * p5 _9 I* d+ T2 O; i8 C
  59. /*************************************************************************************************************************7 X$ r! A- z# v4 z
  60. * 函数                        :        STM32FLASH_STATUS STM32FLASH_GetStatus(void)6 a% q; D! j$ A$ ^. ^+ L+ g: A
  61. * 功能                        :        得到FLASH状态; F2 P+ a# S+ g( [9 C8 p3 H1 a
  62. * 参数                        :        无
    $ [/ s8 O% E3 v: M; ]
  63. * 返回                        :        STM32FLASH_STATUS
    . m+ I6 K4 o, @! z- u$ a
  64. * 依赖                        :        底层4 @" v+ ]/ A5 Z
  65. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>) E7 B( s! s' @, x
  66. * 时间                        :        2013-10-20: ^- A/ j6 q9 j6 o, r( m# u
  67. * 最后修改时间         :         2018-01-03
    6 _0 W! K  ~1 O: {8 T0 `( f
  68. * 说明                        :         8 Z6 ], ], V4 f
  69. *************************************************************************************************************************/
    * h3 O0 G+ t/ w
  70. STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    & O  d4 W* l+ [$ I+ D
  71. {        
    + ]+ M% G, }$ e* p
  72.         u32 temp=FLASH->SR;
    $ ]- U0 Q- ?6 O& @  N9 @; T
  73.         9 S1 d% @; x3 B# i1 i) f9 H; h
  74.         if(temp&(1<<16))return STM32FLASH_BUSY;                        //忙
    : }; Y& W% t5 m$ J6 e% s/ U
  75.         else if(temp&(1<<4))return STM32FLASH_WPRERR;        //写保护错误
    * D, p2 g1 j# r( M
  76.         else if(temp&(1<<5))return STM32FLASH_PGAERR;        //编程对齐错误7 L6 g6 D  K! S6 N5 b
  77.         else if(temp&(1<<6))return STM32FLASH_PGPERR;        //并行位数错误
    5 X. F9 L: w6 d% h0 o" }. A. O& J
  78.         else if(temp&(1<<7))return STM32FLASH_PGSERR;        //擦除顺序错误) D1 @. \& K9 H: o, D  M' S
  79.         else if(temp&(1<<1))return STM32FLASH_OPERR;        //操作错误3 N' D& I' r. j7 Z  I
  80.         return STM32FLASH_OK;                                                        //操作完成+ u0 O# ]) H. V: M; f7 y7 K' G
  81. }
    9 }4 d" z; G/ J
  82. 0 e& u9 K! n: f, V0 f  F

  83. & @" `& R8 ]. q7 }2 s0 e

  84. 5 X- G% D& I* O) }3 n
  85. /*************************************************************************************************************************
    * K; T. L" N+ |# Y5 @
  86. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)' s' T2 H7 n" c7 @: P, @
  87. * 功能                        :        等待操作完成
    2 w7 J/ w3 n& ~5 y3 h
  88. * 参数                        :        time:要延时的长短,单位us3 Q  S' K5 p0 P5 Y& B# V6 q
  89. * 返回                        :        STM32FLASH_STATUS$ W% }8 d: a% y" i# a2 k2 h
  90. * 依赖                        :        底层$ b: G! c6 \: w- u+ [* n( n3 c/ [6 C
  91. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ) s# @% E( s/ _1 k* t
  92. * 时间                        :        2013-10-20/ Y: \# f1 \* @- w
  93. * 最后修改时间         :         2018-01-034 M0 v  F0 \0 J; V# i
  94. * 说明                        :         2018-03-24:增加清除看门狗功能
    3 N7 E4 `2 f7 P3 b  p% k9 ?$ Y
  95. *************************************************************************************************************************/
    1 s1 ]7 f/ A- K2 a% I# A+ J
  96. STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)1 z" y& A% h2 V, A6 f
  97. {( o) a& n4 [: c3 u
  98.         STM32FLASH_STATUS status;, b/ i5 p% \$ s
  99.         
    3 t  E. r. ]! Q( W- n* g
  100.         if(time < 1) time = 1;
    ) I8 O" [" u1 z, a5 x
  101.         do
    ! s6 u; C4 u/ q, i
  102.         {
    ' L! H' C& H: u8 w" V, v! X
  103.                 status=STM32FLASH_GetStatus();                        //获取状态- k- L1 u- A/ e2 X5 N5 q6 |
  104.                 if(status!=STM32FLASH_BUSY)break;                //非忙,无需等待了,直接退出.  ?/ W; M' _9 ~9 ^. v9 Z* f9 S
  105.                 Delay_US(1);
    1 e* i' K) N0 [9 n/ C% u' m
  106.                 time--;3 ^% M$ P! X- X/ L* E% e; [& p
  107.                 3 h3 c3 M, [  [- k0 @# m
  108. #if(SYS_WDG_EN_) //使能了看门狗
    ( p$ f9 `4 D8 m) u9 q! f
  109.                 IWDG_Feed();2 ^3 o" N. R# |/ X4 H( ]5 W
  110. #endif //SYS_WDG_EN_        
    3 S9 L/ E. l: N( _5 p1 {6 `- M
  111.                
    * g# }( [# X  t2 _  o: l4 d0 I% `
  112.          }while(time);
    ( A, w, |! P! q3 P8 \

  113. 7 ?  p  [8 y/ @4 R- w
  114.          return status;+ R0 ?5 v  t* e, p
  115. }: v; s/ L& A# ?
  116. % S' }" }* o9 p' g+ ^  J) M3 L

  117. : L$ k: n* D  c, w; B! `; |

  118. 5 H- ^. S/ G, n% o& J
  119. /*************************************************************************************************************************. L( |. n6 ~% a$ _3 A! j" V. v% v
  120. * 函数                        :        STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)
    0 A. e, N" c; P) W  }- K( F; M
  121. * 功能                        :        扇区擦除! D; d6 r3 v# `. E- n) B: v
  122. * 参数                        :        sectoraddr:扇区地址,0-11
    . ^: U7 K4 x2 Y9 A! k
  123. * 返回                        :        STM32FLASH_STATUS8 w, B& p& j8 e. X- I. m2 U, ^
  124. * 依赖                        :        底层8 X: J+ t9 ~4 Y" t. W- F
  125. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>. {# H/ o) k' ]
  126. * 时间                        :        2018-01-03
    - E& i$ {  S8 J- p
  127. * 最后修改时间         :         2018-01-03
    ( f- J+ e7 w3 C" N) J" p+ I
  128. * 说明                        :         扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区. F- p/ b: S! |' f
  129.                                         128KB扇区擦除足最大2秒8 y4 g" d, A$ x2 V% S" ^9 E6 p
  130.                                         2018-01-16:修复扇区擦除时没有解锁问题% g- k, \5 g' D# W
  131. *************************************************************************************************************************/9 w7 b  |3 Y7 v+ w; U2 M7 X
  132. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)- ~2 u" r0 z" T* T+ x
  133. {/ e( ?9 m* n) j5 p& }
  134.         STM32FLASH_STATUS status;. S" ]* b) U6 o6 w/ X3 B# b1 t
  135.         
    6 o& l: K; v0 A+ v7 t+ @# t$ Z  v
  136.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现3 Z; j1 b" ]7 c5 ]3 r6 T$ E
  137.         {
    2 _% r, f- C4 n5 J% j* _
  138.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    : k* e6 @2 ^3 j
  139.                 FLASH->SR |= FLASH->SR;( ?5 k3 {# R* x5 y+ p2 Y5 n$ x4 J
  140.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);1 }3 e4 @& v5 X" U0 j
  141.         }" q$ G& M" s- W0 @+ L
  142.         
    - B' w8 y* t6 I* F& ~3 N8 z0 C4 t
  143.         status=STM32FLASH_WaitDone(2100000);        //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过' `2 C0 ~5 k9 P1 F7 r1 E. t# w% |
  144.         ( @, S- f0 R( a' [9 y
  145.         STM32FLASH_Unlock();                                        //解锁 9 g/ S) I  {  t; Y3 T8 `
  146.         if(status==STM32FLASH_OK)                                //没有错误
    - p3 Y4 Z! g( @2 l2 X/ A% T7 S
  147.         { & H% o) {. Q) Y4 E, M
  148.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    + Q, }# b) u+ W
  149.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    ! T! T$ ]" [$ W+ v; ?' T
  150.                 FLASH->CR&=~(0XF<<3);                                //清除原来的设置
    1 O5 p+ C( k, b* u; W% A0 A9 F
  151.                 FLASH->CR|=(sectoraddr&0x7)<<3;                //设置要擦除的扇区 3 D2 y( N& J, ~4 N$ G
  152.                 FLASH->CR|=1<<1;                                        //扇区擦除
    3 Z7 n( S7 H0 M
  153.                 FLASH->CR|=1<<16;                                        //开始擦除
    4 ]5 @( a( p; m+ q1 `3 G
  154.                 status=STM32FLASH_WaitDone(2300000);//等待操作结束,最大2s  
    9 z6 F; X5 N7 W1 f
  155.                 if(status!=STM32FLASH_BUSY)                        //非忙0 I: {- B/ Z3 V! v$ E: c) I' A8 R0 Q* p
  156.                 {
    $ U4 g% k- o: X* p' O
  157.                         FLASH->CR&=~(1<<1);                                //清除扇区擦除标志.7 r$ P' k$ A6 R9 L
  158.                 }
    2 L& I+ K0 i) c! K% j* T9 e0 u
  159.         }
    & ~7 ~- D7 O& r% R
  160.         //DEBUG("扇区擦除状态:%d\r\n", status);& }! ]3 c; i# T& s4 t
  161.         //DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n", FLASH->SR, FLASH->CR);6 }2 V$ B9 r( e* m: I
  162.         $ t2 L9 y: c' J" A1 ^
  163.         STM32FLASH_Lock();                                                //上锁
    , x) v( n9 q" |" z
  164.         if(status != STM32FLASH_OK)
    / |; |% y0 f' Q. b' ~# r. ?
  165.         {
    7 F. \0 v' K3 U8 ?& u$ t
  166.                 DEBUG("擦除扇区%d失败(错误:%d) FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",sectoraddr, status, FLASH->SR, FLASH->CR);
    * B, P, b* ^- N0 h' t
  167.         }
    ! q/ S2 f& z5 ]# d8 |

  168.   O7 v" W/ t# B* \
  169.         return status;                                                        //返回状态
    % y: R  u0 u& z$ ]
  170. }
    # X% D0 G, T- u) b: u' l
  171. 1 u6 d6 Z: e  n* x
  172. ; l5 N5 C. o/ K" U1 t
  173. 3 \8 a. F1 |- H' }$ p7 M6 U- L) X
  174. " G3 Q9 d& h8 X) `
  175. /*************************************************************************************************************************
    * M2 u9 B* L& f; V/ Y9 z
  176. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)# s) G) s1 h1 o5 o# \% b
  177. * 功能                        :        在FLASH指定地址写入一个字的数据(32bit写入)
      t! m6 A  R) }
  178. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据( R+ j" k" M6 G3 Z& [3 C; w
  179. * 返回                        :        STM32FLASH_STATUS) z5 R! r9 p& R9 Z# P
  180. * 依赖                        :        底层
    6 o0 T. @8 d! ~- E% a
  181. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    + j# R  K( L! O) @& r
  182. * 时间                        :        2018-01-03
    2 T* y# D6 F4 ?" A0 U% A: t& V- ?
  183. * 最后修改时间         :         2018-01-03
    ' M9 m" M! k: D2 G
  184. * 说明                        :         警告,地址必须为4的倍数
    0 N0 c$ N, Y1 N1 E1 X# _
  185.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    3 i' U2 `7 Q: t( t' E1 Z2 g
  186.                                         不会判断是否能写入
    & |9 V( h+ y! b3 j; u
  187. *************************************************************************************************************************/
    ) B2 V6 w5 U$ W) Q( o( L9 J% ^
  188. STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)
    ; {' p5 r  r' S
  189. {9 L) R# |5 j: L; ^# T
  190.         STM32FLASH_STATUS status;+ `6 L9 k6 j$ M' V+ E- L  K
  191.           k8 v/ {& g* f/ X0 D0 b# c! Y* O
  192.         status=STM32FLASH_WaitDone(200);                 //判断状态+ _: t: n. Z' n8 s1 v
  193.         if(status==STM32FLASH_OK)                                //没有错误' E( ~4 B0 e9 U  e$ u2 ~  k8 a
  194.         {
    . c3 n# v: ^- m* Z; x3 o8 t
  195.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    6 [( h7 r8 P: ?: ]
  196.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!6 A6 n1 F: ]& R8 \) H$ g5 v  y
  197.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误, X5 ?: @9 n; C' w
  198.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    6 l7 m+ P2 v1 u! h, ?; D5 h  P
  199.                 *(vu32*)faddr=data;                                        //写入数据% z; _* o, T: o" I; q
  200.                 status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.
    & M: F9 K4 |, o& s& q
  201.                 if(status!=STM32FLASH_BUSY)                        //非忙
    2 u3 [/ ?9 Z( C
  202.                 {        , }6 t3 G3 i4 Z+ E/ Y+ d
  203.                         FLASH->CR&=~(1<<0);                                //清除PG位
    " ]) x3 h" B2 O( X# x1 l$ [5 U
  204.                 }
      f$ @5 a! c2 w; W+ W+ K) j
  205.         } ( H5 v4 Y- @8 _. d0 F+ q0 n

  206. " U9 v4 l! ^. s+ ^% e  ?
  207.         if(status != STM32FLASH_OK)$ @5 O! S( e( x( j
  208.         {
    5 e6 D3 S3 a" Y$ k, X/ d, q
  209.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
      R' H+ u5 F# }+ y" I! W1 M9 k2 J4 B
  210.         }
    ; f  o* C  [4 X* s- j; W, O* b
  211.           w5 w# _% s$ l
  212.         return status;: }' }8 ~) j  W+ G2 k+ Z/ P& A8 }
  213. } + Q% J" j# u: b6 V" v0 z

  214. 8 @( U$ ^; X% U8 z
  215. $ W8 v$ ], \1 p# x6 u8 Y
  216. /*************************************************************************************************************************
    , X- n% r9 {. {
  217. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)5 \5 \1 ]* p8 |( |) t
  218. * 功能                        :        在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)1 _4 h6 m' ?: ?
  219. * 参数                        :        faddr:指定地址(此地址必须为4的倍数);data:要写入的数据
    ; s) M8 r& I9 p( r. w+ _
  220. * 返回                        :        STM32FLASH_STATUS
    1 Q: B' _6 I4 _) J8 U( {/ d7 q
  221. * 依赖                        :        底层
    0 L* w& W) C" G1 l7 r' [0 q. c0 J: T
  222. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>2 ]" `- B. E8 [5 Y4 P& s$ x
  223. * 时间                        :        2020-02-08
    ; D6 ]5 M% b, K7 F
  224. * 最后修改时间         :         2020-02-08
    " b+ q, h/ M6 E; Z. X
  225. * 说明                        :         警告,地址必须为4的倍数$ o. U) m/ \  ^
  226.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    2 @: Y4 a& M3 ^3 o
  227.                                         不会判断是否能写入
    9 Y" F, I" a  Z% w/ u
  228. *************************************************************************************************************************/2 `& D! `9 `5 y/ K! f* e+ C+ a
  229. STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)2 ^0 ]7 ]% I: o. W2 D2 g" P5 i
  230. {
    . |0 ^. Y/ k4 g4 z
  231.         STM32FLASH_STATUS status;" _  l* \+ C1 ^' e6 \$ h1 M& ~

  232. ( q' V" ?" q1 }7 P  ^5 l6 d2 z
  233.         status=STM32FLASH_WaitDone(200);                 //判断状态
    8 w0 F+ S2 @9 o+ k$ Z9 E
  234.         if(status==STM32FLASH_OK)                                //没有错误
    . z  o; {+ P8 f' C9 g" \" ?! z2 c
  235.         {
    " P+ \) Y# c: h3 c9 M1 n7 b& J, X" Q: a
  236.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    / A. m4 C) {0 t+ k% z, t
  237.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!# y3 q. R3 F, l3 h& `9 ]" l: J
  238.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误( X' @7 l6 ?, ]' ]
  239.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    , f3 m9 |5 R0 J( b, q
  240.                 while(dWordCount --)
    # j7 ]% T+ {3 C3 W$ n, \8 l
  241.                 {3 |* d$ m0 E. I
  242.                         *(vu32*)faddr=*data++;                                //写入数据
      M6 f2 A( ~8 Z& z, M+ G' R1 u4 Z
  243.                         faddr +=4;                                                        //地址自增+4/ n, ~* T. L/ a0 d) p7 }: o, a4 A
  244.                         status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.9 w" t6 S4 S& x
  245.                         if(status!=STM32FLASH_OK)                        //有错误2 D8 k5 _! i. A# Z# h; {  v- _" n2 ]
  246.                         {
    / z/ A) s. Q8 J( t2 |1 E
  247.                                 break;
    # s: K/ R3 T  p' S
  248.                         }
    ; f/ K* D" H' v$ a' J& G
  249.                 }
    + y1 n. u' y0 U
  250. 0 K8 g, x3 k2 l2 A% ~
  251.                 if(status!=STM32FLASH_BUSY)                        //非忙' i6 @9 \/ Y2 b; W7 S8 \
  252.                 {        
    : `3 F" `* i$ j( V: q9 A
  253.                         FLASH->CR&=~(1<<0);                                //清除PG位
    9 L( s6 t/ _3 A* l/ z4 a, w4 q
  254.                 }
    1 \# S+ |# Z7 C' m/ ]& h. N
  255.         }
    * u, C3 Y0 G2 b4 V  s
  256.   a* x' o9 X6 ]/ o  K/ Z! K
  257.         if(status != STM32FLASH_OK)
    , g0 D) T+ {4 \7 o
  258.         {
    1 S1 _6 K: x; |8 Y3 `$ o
  259.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);6 B/ o6 `. ^) K/ p
  260.         }
    8 u/ N, U3 m7 i: {
  261.         ! @( j. @" q2 m
  262.         return status;- a6 c4 D! z3 C1 [3 Q0 v
  263. } 5 c6 O: e3 s* Q7 p

  264. 8 N. a4 |8 W6 f  J. B
  265. * Y) O  y9 v! H7 Q4 v6 f9 F. G
  266. /*************************************************************************************************************************( O5 w& s% [8 Q/ Y  I3 s
  267. * 函数                        :        u32 STM32FLASH_ReadWord(u32 faddr)
    7 C8 \! Z( w. Q: F# X: p- N( p! S
  268. * 功能                        :        读取指定地址的一个字(32位数据) 3 U$ g. d7 u& a
  269. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);: ?: v2 P1 C0 n, F5 F& b, Z, F& o
  270. * 返回                        :        数据7 L( x9 n2 N& Z/ i8 {3 O% ]
  271. * 依赖                        :        底层
    * f. n/ i/ p3 w" T# m( g+ c
  272. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>- o+ N. b! a5 C3 N' b0 v5 b
  273. * 时间                        :        2018-01-03, }0 J' U9 d$ z' J: s: F9 ^$ L" }
  274. * 最后修改时间         :         2018-01-03
    5 L7 U- h. ^( X) o# L- n7 f; r
  275. * 说明                        :         警告:地址必须是4的整数倍4 O+ K, ~- m) ?. m- K
  276. *************************************************************************************************************************/: Y) n2 H. T* D$ R2 b
  277. __inline u32 STM32FLASH_ReadWord(u32 faddr)/ ~: y0 }4 f% ~+ Z& ]( B, P
  278. {
    7 P5 Y% |, H. C
  279.         return *(vu32*)faddr; $ _# f7 {5 f' Q! M& G
  280. }! v4 i- ~, X) Q6 C

  281. ; h0 Z8 l. Y, q3 }# k! k2 }
  282. + g" _! ]( V$ z( R0 h0 E
  283. /*************************************************************************************************************************
    0 m( V' N0 R1 C' l5 C8 l% _, U
  284. * 函数                        :        u8 STM32FLASH_GetFlashSector(u32 faddr)
    : a( [4 s; F6 @- x5 q" s, d
  285. * 功能                        :        获取某个地址所在的扇区
    # H' _# j, P+ i) U  `+ C
  286. * 参数                        :        faddr:指定地址
    9 _( E# f+ w# a: X" ^- S
  287. * 返回                        :        删除编号,0-6,如果超出了也会限制到6% l) O! _- h5 a5 O- ]9 P/ U
  288. * 依赖                        :        底层
    * j) ?& J0 b5 n! i2 [$ i
  289. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    : q: X; l* i0 P, k. o% [" g
  290. * 时间                        :        2018-01-03: U- h, E- S8 S4 K# [+ }# O' D
  291. * 最后修改时间         :         2018-01-03* u% b8 N5 q0 i4 a5 g
  292. * 说明                        :         地址请不要超出范围$ J; C# j, ], R4 U
  293. *************************************************************************************************************************/( D# u# }/ i' ~3 \7 p1 z6 E
  294. u8 STM32FLASH_GetFlashSector(u32 faddr)  @2 L" c  U, P3 _/ V4 |/ M
  295. {
    * x) K2 v9 q3 W4 g8 d5 i# G
  296.         if(faddr<ADDR_FLASH_SECTOR_1)                return 0;
    : g2 Z# B) n. K& w
  297.         else if(faddr<ADDR_FLASH_SECTOR_2)        return 1;
    # Q* q4 m- }" G+ c; B, D6 s
  298.         else if(faddr<ADDR_FLASH_SECTOR_3)        return 2;
    # Q8 J- o# {/ x
  299.         else if(faddr<ADDR_FLASH_SECTOR_4)        return 3;
    5 }1 g* a5 r2 I
  300.         else if(faddr<ADDR_FLASH_SECTOR_5)        return 4;
    $ D( Q2 W: @2 t7 B+ B) s2 t" Q3 K& p
  301.         else if(faddr<ADDR_FLASH_SECTOR_6)        return 5;
    * q0 K& M( h: S& v% I7 c
  302.         else if(faddr<ADDR_FLASH_SECTOR_7)        return 6;" [. D& j& ]% P$ R9 e! D
  303.         else return 7;        : @$ U* t1 E) J
  304. }) l- b' f* `  X; h3 {3 U
  305. 5 P2 N/ T. J  U4 n0 m7 `

  306. 7 w- V; f% h0 g
  307. /*************************************************************************************************************************
    : V3 i- J+ `, ?. O$ X
  308. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  
    4 a! f0 j* }1 @
  309. * 功能                        :        不检查的写入; F1 A7 q# m0 U; D6 L* F
  310. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数
      d! ]7 O& X- T' S# ]
  311. * 返回                        :        状态6 V( g, _3 k7 m9 w* c
  312. * 依赖                        :        底层
    " x# x- f+ W$ G  h; v, i
  313. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>( b5 T/ Y3 T: b% o8 c$ d6 Q
  314. * 时间                        :        2013-10-200 k. `- Y- F4 y" b. m  B& @
  315. * 最后修改时间         :         2018-01-03
    % c* Q6 q* o* {2 X+ R) \' x, O
  316. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)$ m: H3 D2 Q: G& o! [+ ~6 `6 x
  317. *************************************************************************************************************************/& j2 G: l* Z: y" ?1 J
  318. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   6 y4 D3 W6 p" \2 d  F
  319. {                                          
    8 |: `" e% ]0 s6 H& M( M* U5 b
  320.         STM32FLASH_STATUS status;" Z5 {# s, j* L5 P( j/ p" c' [, M
  321.         
    ( J% o1 n4 W" N6 M8 T6 s( I
  322.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误
    0 \# Y) {0 Z7 e! p* L& p
  323.         STM32FLASH_Unlock();                                                //解锁 $ [2 S. O' z2 z8 l1 w: Y
  324.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    ' m5 F" Y( k* l  v5 J! _3 F
  325.         {
    " A& Y  t* e  f  U, @* {
  326.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    9 N( \1 n  ^; L. B; r: G& J4 U7 t
  327.                 FLASH->SR |= FLASH->SR;, P9 O" ~6 x$ S9 u
  328.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);. \% o* c) t% c" c! _
  329.         }: }1 S3 F$ \4 X1 C1 g6 a+ ?$ \( j/ Y) Q
  330.         status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据7 M* Q5 Y, G0 c! L9 g- V: n
  331.         STM32FLASH_Lock();                                                        //上锁7 Q$ n7 A( N" d: b! W
  332.         return status;2 D4 m$ j) {7 v6 U1 C) _. }
  333. }   t, |( x! ?5 q+ e) p$ e
  334. ; {9 ~) `+ N' q3 [- V

  335. . p6 o6 y" p4 G8 n) e
  336. /*************************************************************************************************************************
    0 Z& J9 \( B" m# s2 M  s$ W
  337. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   
    1 G3 H0 d* ^% _& ^  J( I$ ~  J8 t
  338. * 功能                        :        不检查的写入一个字* j3 n1 Q- j+ S, R1 Y, G) W
  339. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);data:要写入的数据值5 R& M0 Y1 h+ h$ C
  340. * 返回                        :        状态9 T3 i: y8 J* s/ ?: Q4 t4 T
  341. * 依赖                        :        底层" M0 }# g, N" r( m/ o1 F8 ]1 v
  342. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>7 F0 v) B: G  F, y
  343. * 时间                        :        2020-02-08- t, C4 {% e2 [! j1 T/ z" m6 ]' f  ^
  344. * 最后修改时间         :         2020-02-08! {' N5 N  y; Q% Z- I* d. ?
  345. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)
    ( T2 m. i  Z/ g$ U5 P7 |- Z/ F
  346. *************************************************************************************************************************/
    . Z1 y8 f, R1 ^- }
  347. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   
    / `7 L% u- ~, q1 o9 G
  348. {                                          
    & |7 m# b+ p: |9 ~# r# f
  349.         STM32FLASH_STATUS status;
    , V$ m# A! v& _4 s
  350.         3 p$ |9 n8 i: ?1 z/ y) S0 m
  351.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误8 v5 q1 p4 C- \/ P" u1 e: K) k9 J
  352.         STM32FLASH_Unlock();                                                                                                        //解锁 & s4 H8 M& C8 G
  353.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
      V  B4 X/ t, @* W0 Z4 I+ @4 x0 O  h
  354.         {6 D, E8 O( l) [5 }! ~
  355.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    & w# r$ g4 d; p; E# ?% ~3 e9 y
  356.                 FLASH->SR |= FLASH->SR;
    ) U( N* @4 Q9 v3 Z3 m" _
  357.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    1 p6 H0 t% u' j/ s; p  s# P0 r' D
  358.         }
    . @/ x" h! G$ v- M% h4 S, L2 N$ E
  359.         status = STM32FLASH_WritedWord(WriteAddr, data);                                                //写入1个字的数据7 {% M+ e4 z7 f7 g) L
  360.         STM32FLASH_Lock();                                                                                                                //上锁
    # a: K4 u) d( @, K# Q
  361.         return status;
    2 d3 x8 Y- b# [1 w, U1 x
  362. } 7 j. z4 i6 i7 T5 b$ k; G. s

  363. & G$ Y) ?2 ?& r8 ]$ i

  364. & N& s7 l+ ]: x
  365. /*************************************************************************************************************************' x( e: r& E, R5 z! C% R
  366. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        + ]6 q7 a, p4 {9 z3 E6 a
  367. * 功能                        :        从指定地址开始写入指定长度的数据(数据长度字为单位)
    , V. b- L( ~" \) F6 o3 Y9 N
  368. * 参数                        :        WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
    ( W8 K( ^! v0 g& u9 C% j; o
  369. * 返回                        :        0:完成;1:忙;2:错误;3:写保护% Y% F  z* Z8 C; z. b' z' B, M- `
  370. * 依赖                        :        底层
    7 R+ P, W8 w4 c
  371. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>& l  _! Y/ _+ j
  372. * 时间                        :        2013-10-20
    & G8 I# X+ h( R& B* v9 i; m2 ?+ F
  373. * 最后修改时间         :         2016-01-07! l" E2 T# k# S) b# J' S/ H; T
  374. * 说明                        :         警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据# v/ O. V7 s; O
  375.                                         如果需要保存其他的数据,请在应用层进行实现(比如:先读取扇区,修改扇区,擦除扇区,写入扇区,需要大内存支持)+ E  I5 k- |, {* b
  376. *************************************************************************************************************************/ 0 c) x  j( M0 E8 p
  377. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        ' w- L9 `: ?5 G
  378. {, v0 k2 M, A% N
  379.         STM32FLASH_STATUS status;
    . I" H1 N' X2 c: [2 J6 L& Z
  380.         u32 addrx=0;; ?. O. P( A; E- ]
  381.         u32 endaddr=0;        & E) ^7 e7 C  `6 W0 q  j
  382.          
    . D- u1 x# u7 ~- q
  383.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR;        //非法地址1 H1 D5 F: f+ {. ^" {( Z+ r; R7 D
  384.         $ C' U) ^' @# m
  385.          FLASH->ACR&=~(1<<10);                                                                //FLASH擦除期间,必须禁止数据缓存!!!搞了我两晚上才发现这个问题!
    ; x* d6 W! `8 W8 X5 o
  386.         addrx=WriteAddr;                                                                        //写入的起始地址. p0 G! s7 n, V! s5 k
  387.         endaddr=WriteAddr+NumToWrite*4;                                                //写入的结束地址. w1 o, v' @6 m
  388.         
    . Q. b  t1 T. H+ O3 @4 Z
  389.         if(addrx<0X1FFF0000)                                                                //只有主存储区,才需要执行擦除操作!!8 M, F3 a$ d5 T# O
  390.         {" |) ]5 l, ?6 M0 t0 ]" {" S
  391.                 while(addrx<endaddr)                                                        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)) B4 H& _. Z# U9 _7 x1 D1 \
  392.                 {' _- x( z! {/ P
  393.                         if(STM32FLASH_ReadWord(addrx)!=0XFFFFFFFF)        //有非0XFFFFFFFF的地方,要擦除这个扇区
      y' q  ?. V6 i" p8 s8 r/ G% B  f% O
  394.                         {   : y0 u: ]7 b( L" z
  395.                                 status=STM32FLASH_EraseSector(STM32FLASH_GetFlashSector(addrx));# z- \2 ?. F6 n6 w2 d+ Y
  396.                                 if(status != STM32FLASH_OK)break;                //发生错误了
    3 O4 F- U( Z8 h8 o! m
  397.                         }else addrx+=4;
    / `( A: ^4 c' @/ Q, K  }; s
  398.                 } & X* r6 A) N+ r; h: V
  399.         }& u/ E7 C1 \! g$ }! y* p
  400.         if(status==STM32FLASH_OK)9 F1 L* `" ]& x! }5 l/ j
  401.         {: p+ D7 H" P/ A' D( |4 v
  402.                 STM32FLASH_Unlock();                                                        //解锁
    , h0 ]% `+ N6 V1 N2 U
  403.                 if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现6 w% b  p- ?1 P  V5 I* f- R
  404.                 {, [+ U7 z% y% I; l, q% S
  405.                         DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    8 z# @( n5 r* L; ~8 b
  406.                         FLASH->SR |= FLASH->SR;
    2 }. {. G' d$ |  u! x, b
  407.                         DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);% A$ x3 ^: W- r( @9 f4 |
  408.                 }
    8 Z( Y1 P5 @4 f. e
  409.                 status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据& Z% K: ~0 g$ }  I4 T! v& N$ M
  410.                 STM32FLASH_Lock();                                                                //上锁6 B3 u9 Y" n2 T/ ^! Y0 u
  411.         }& N; U, I, h3 `6 O# ?
  412.         FLASH->ACR|=1<<10;                                                                        //FLASH擦除结束,开启数据fetch1 k  \6 v; E! L5 j! q/ b
  413.           _& Y/ x. w: T6 W
  414.         7 j; u7 y+ ~( }! s; G9 _: E
  415.         return status;/ M5 s. T2 \* ]( n
  416. }8 U2 l; j  F- ]/ Q- f5 s

  417. 2 S6 T" l( P7 }

  418. % a0 S1 J- [) M- y6 w* _, N1 \9 u
  419. ) p( i. R2 d( G# S% I% ?

  420. . j6 }0 a0 c1 y; c8 _: ?' @
  421. , q! n) f  a. q9 X8 F+ [
  422. /*************************************************************************************************************************- s6 n/ B3 k1 Q2 N& e
  423. * 函数                        :        u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)
    9 p( ^7 v" p9 V2 z
  424. * 功能                        :        从指定地址开始读出指定长度的数据* A, S0 G3 u- ^6 s- N
  425. * 参数                        :        ReadAddr:起始地址;pBuffer:数据指针;NumToWrite:字(32位)数
    5 |8 c2 L# n) b6 q$ q* g9 Y6 e  J
  426. * 返回                        :        读取的数据长度(字为单位)& B, b' r) i( B. W' n
  427. * 依赖                        :        底层
    , u; q3 X* E% l0 |6 K2 `
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>  f( Z4 W& n4 [* c/ E% U9 c
  429. * 时间                        :        2013-10-20
    " d: q- |. d. t1 O' U
  430. * 最后修改时间         :         2016-01-07
    ! b# W: \3 u2 _! U5 J2 S
  431. * 说明                        :         地址必须为4对齐% P. a$ p  \$ @; }' ?. x; _8 _" L. @
  432. *************************************************************************************************************************/
    9 I  E. k6 }0 I& W
  433. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)           
    $ {7 @1 A" Z1 O5 _, S! [! m) d
  434. {( f" ?2 C+ l0 c
  435.         u16 i;
    - R3 W. w/ w) \! U9 N  E
  436.         u16 cnt = 0;
    ( T- l: e( H5 J& Q
  437.         , X0 F( u3 A* ?$ F6 o) J: o
  438.         if(ReadAddr<STM32_FLASH_BASE||ReadAddr%4)return 0;        //非法地址5 v4 f6 g% q; d$ e0 j' a
  439.         1 z5 f1 s7 M# D# V" C  @
  440.         for(i=0;i<NumToRead;i++)
    1 ~/ a/ B3 `9 [2 T8 @. a$ k' [
  441.         {: J( a+ F9 w" M4 }" s* m& {
  442.                 pBuffer=STM32FLASH_ReadWord(ReadAddr);                //读取4个字节.
    4 U+ _1 T; ^' }8 _
  443.                 cnt++;
    0 p/ h6 c) p" O$ b7 J6 i5 I
  444.                 ReadAddr+=4;                                                                        //偏移4个字节.        9 h9 L8 F2 h5 e/ Y- L( L* h
  445.         }
    3 ~6 U# {' F# S
  446.         return cnt;
    3 B2 g  E9 N0 @
  447. }* Z8 y! P, c& q2 u

  448. - c+ f& }: L# w$ u( ?2 Y# e
  449. ' a$ ^7 D0 r& Y+ {1 P/ C
  450. /*************************************************************************************************************' j* z# P2 K0 p$ [2 l
  451. * 文件名:                        stm32f7_flash.H
    1 f& w0 S5 N# A. k: u1 ~
  452. * 功能:                        STM32F7 内部FLASH编程驱动函数
    4 ~6 Q, w+ ]& R$ G& I& t/ N# m
  453. * 作者:                        <a href="mailto:cp1300@139.com" style="">cp1300@139.com</a>
    " |4 E4 k$ r, S! {1 F2 t9 Z% ]% B" C
  454. * 创建时间:                2013-10-20
    2 \! j3 }# G, Z- i& q
  455. * 最后修改时间:        2020-02-07- |/ n- R; _8 j) ]/ o( [
  456. * 详细:                        用于STM32F7内部flash读写驱动4 q. {+ t! c/ k
  457. *************************************************************************************************************/
    , V/ E+ b( D, X5 O/ J/ m
  458. #ifndef __STM32F7_FLASH_H__
    " q. n) G, C: L5 M% T; o! m
  459. #define __STM32F7_FLASH_H__" B: W+ x7 T% \2 H
  460. #include "system.h"  1 L' i# n( `) C

  461. " y( X5 Z) |; y3 q1 y* D
  462. //FLASH起始地址7 Q2 s& A, E$ K( k
  463. #define STM32_FLASH_BASE                 0x08000000                         //STM32 FLASH的起始地址
    - j0 @0 V- i9 S- y* C
  464. 1 U) t0 u: k0 E& b
  465. //FLASH 扇区的起始地址6 I7 @- o3 U0 B- u2 v
  466. #define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)         //扇区0起始地址, 32 Kbytes  
    ) l5 x- `* {, T9 n0 z$ ~" l
  467. #define ADDR_FLASH_SECTOR_1     ((u32)0x08008000)         //扇区1起始地址, 32 Kbytes  $ j4 D& r% Y  j0 G4 t: H1 T
  468. #define ADDR_FLASH_SECTOR_2     ((u32)0x08010000)         //扇区2起始地址, 32 Kbytes  
    , f; V" P) h" G7 o9 y
  469. #define ADDR_FLASH_SECTOR_3     ((u32)0x08018000)         //扇区3起始地址, 32 Kbytes  " v' [, {$ h1 l
  470. #define ADDR_FLASH_SECTOR_4     ((u32)0x08020000)         //扇区4起始地址, 128 Kbytes  
      l1 R+ N. Y1 M2 F6 u% B$ o: P
  471. #define ADDR_FLASH_SECTOR_5     ((u32)0x08040000)         //扇区5起始地址, 256 Kbytes  
    2 \4 k, W7 c1 h) g/ n6 y. `, m/ C
  472. #define ADDR_FLASH_SECTOR_6     ((u32)0x08080000)         //扇区6起始地址, 256 Kbytes  
    . ]. Z* y- N: `! t9 g4 n
  473. #define ADDR_FLASH_SECTOR_7     ((u32)0x080C0000)         //扇区7起始地址, 256 Kbytes  
    ' S2 x$ t* ?' s/ K3 w# N2 i0 i- h

  474. ( {7 b- y) \, X/ Q3 x

  475.   `" m$ ~" o7 {* W2 ~' D
  476. //FLASH解锁键值  K1 J  e1 E0 L# ^5 y2 J4 ~
  477. #define RDP_KEY                  0x00A5) h& q& v3 S: a% E7 D" z
  478. #define FLASH_KEY1               0X45670123
    - X% B/ v& ~4 `7 M9 q. g8 V9 a; ^
  479. #define FLASH_KEY2               0XCDEF89AB
    / B; G5 t4 Q1 d+ t/ L8 q
  480. #define FLASH_OPT_KEY1           0x08192A3B
    ' k0 b, C# r9 w; u" H+ l6 ?/ O
  481. #define FLASH_OPT_KEY2                         0x4C5D6E7F
    - a1 k% P  \% ^! ~

  482. * q7 j5 |( K. r8 `4 J' d. w- }
  483. //STM32F7 Flash操作状态4 W7 u( K$ D& D- C
  484. typedef enum
      {( m0 K9 J/ g$ C5 Z
  485. {+ Y7 D8 I; J+ q: N; B: h; k0 ?8 ?. D
  486.         STM32FLASH_OK                        =        0,        //操作完成
    ; x% x6 D5 J. u/ b( p( S+ ^) ^/ p
  487.         STM32FLASH_BUSY                        =        1,        //忙
    - f; Y7 ~' `& i) X
  488.         STM32FLASH_WPRERR                =        2,        //写保护错误
    4 w# o8 H7 E6 L& K" U- _2 T8 [- H5 y
  489.         STM32FLASH_PGAERR                =        3,        //编程对齐错误,必须128位对齐# b* \* h& J9 J: P  t
  490.         STM32FLASH_PGPERR                =        4,        //并行位数错误: y* E2 [$ p5 B
  491.         STM32FLASH_PGSERR                =        5,        //擦除顺序错误4 K) D) b5 V/ i& h
  492.         STM32FLASH_OPERR                 =        6,        //操作错误
    % L1 N& d$ `$ d1 i; j( ?: f
  493. }STM32FLASH_STATUS;5 |9 e9 ]: B" ?: O

  494. ! F/ [; t6 u6 ~! C" Y7 S
  495. //常用接口) t( K, d6 D  U& A: z
  496. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr);                                                                  //擦除扇区% \! K# V$ m9 }, X  \( ]  D
  497. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite) ; //不检查的写入多个字的数据+ G1 }/ |" b* n4 d+ M
  498. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data) ;                                //不检查的写入一个字的数据
    0 ?3 I# j) M4 t2 P% v- w
  499. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite);                        //从指定地址开始写入指定长度的数据(数据长度字为单位)
      c! C7 x, g( u7 H: S& o. R5 F
  500. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead);                                                        //从指定地址开始读出指定长度的数据
    - b) l2 f, j( ~, ]$ z; O
  501. # F( M" d# @1 A' u) m
  502. //不常用接口
    1 F1 _1 Z' ]# K% w. _2 A7 ^
  503. void STM32FLASH_Unlock(void);                                                                                                                        //FLASH解锁. i7 K. H) R8 h* s6 w0 O) q
  504. void STM32FLASH_Lock(void);                                                                                                                                  //FLASH上锁& |4 j4 X& D6 H
  505. STM32FLASH_STATUS STM32FLASH_GetStatus(void);                                                                                          //获得状态
    0 H2 ^1 w  F* P+ f, [
  506. 7 A' o% L: M/ y! x2 C* ]
  507.   k4 _* g7 j) l! t. O$ C6 w2 w8 a
  508. #endif        //__STM32F7_FLASH_H__  X. h& V, v' i& O" b

  509. * m, K% p" d; s! _) U
复制代码
/ M, n/ e! Q( A' \( {
收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

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