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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
总体来说与STM32F4操作是一样的,就是扇区大小变化了,测试过程中发现当PG=1之后立即写入数据到flash会造成编程顺序错误,通过增加一个nop的延时即可解决此问题,还可以通过将多个数据连续烧写的方式避免此问题,就是当PG=1之后,把所有数据都烧写完成后再将PG=0,不要频繁的开关。
7 n( D" v& ^% K+ u7 G6 ~
2 o7 Y% |% X4 b5 F
  1. /*************************************************************************************************************- |% @3 ?: A  ~; m
  2. * 文件名:                        stm32f7_flash.c& D% ?& A) G/ @3 g, B
  3. * 功能:                        STM32F7 内部FLASH编程驱动函数% W& @  n4 h7 ]
  4. * 作者:                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    % ?8 T& p/ L7 R; z
  5. * 创建时间:                2013-10-205 T; o7 J* h6 [) m! t6 b
  6. * 最后修改时间:        2020-02-07
    4 b' g1 U/ m) i
  7. * 详细:                        用于STM32F7内部flash读写驱动- _3 s9 Y& ]& _* K; {4 C. O$ M3 M
  8.                                         默认为3.3V供电,并且宽度为32bit;" S- |( M! a  `3 \0 T1 w
  9.                                         扇区擦除最长时间:32KB扇区500ms;128KB扇区1.1秒;256KB扇区:2秒, `, |3 F  M/ p) _, K) r( X7 Z
  10.                                         修复STM32F7开始写入数据时,PG=1后没有延时导致异常,增加批量写入多个字的数据函数STM32FLASH_WriteMultipledWord()支持。
    % L: f. _+ @/ A" O/ k- t
  11. *************************************************************************************************************/& F1 v3 s! C: |/ c: S8 E
  12. #include "stm32f7_flash.h"3 o1 ~5 f% |4 Z( V9 S, b" a
  13. #include "system.h"
    # V8 ]9 _! \3 \7 D" ]& \" J3 Z4 L# W
  14. #if(SYS_WDG_EN_) //使能了看门狗7 {  G; U* |/ i5 E
  15. #include "wdg.h"( v7 V& d9 O) C* Y
  16. #endif //SYS_WDG_EN_
    0 ?9 w: q# i, ]4 g3 y

  17. % x! D- Q8 \3 R8 m/ \# O' o
  18. 2 g5 L2 W: h( O" a3 A, d: o

  19. 8 R* c5 T6 K6 a/ j
  20. ; p  U% v; f3 X3 g
  21. /*************************************************************************************************************************" J1 D. a( d/ S
  22. * 函数                        :        void STM32FLASH_Unlock(void)- k# Z4 g" U6 S) a8 y
  23. * 功能                        :        解锁STM32的FLASH5 \+ s0 w5 c* {4 S8 a9 R
  24. * 参数                        :        无0 F* F* f( B: U. ?/ N5 o. c% W
  25. * 返回                        :        无
    , Q. G( E: g/ h5 T
  26. * 依赖                        :        底层
    1 z$ |- Z+ f$ ]2 {6 G$ ~& L* v
  27. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    8 k* Y  U- A: i! m* z6 W% l9 v) h
  28. * 时间                        :        2013-10-20
    . W2 v0 P0 R% e4 D  g1 B( C  o$ c
  29. * 最后修改时间         :         2013-10-205 _' [9 r+ N( ?/ _/ P# |# ~7 S. W
  30. * 说明                        :         ) X) b: i2 V% y9 O# T0 l
  31. *************************************************************************************************************************/
    " s4 G8 \& D, i0 c
  32. void STM32FLASH_Unlock(void)2 c! ^) f  ^. D5 Z
  33. {; R1 Q1 M- [: c9 B4 z
  34.         FLASH->KEYR=FLASH_KEY1;        //写入解锁序列.
    8 P. e7 z- [  v+ P$ m' ~  i
  35.         FLASH->KEYR=FLASH_KEY2;: @$ T" V4 ~/ O( u* n8 w# m9 g' N
  36. }0 Q: w5 ~" G& v. o, M

  37. ( f# Y- ]  i2 J( L! {$ m$ j$ }8 P

  38. # c, F* b9 P  m

  39. . |/ O9 a' H# X8 M- S
  40. /*************************************************************************************************************************
    ) F9 ?; `% p  k: l; l
  41. * 函数                        :        void STM32FLASH_Lock(void)
    ; c. M7 \0 N) V
  42. * 功能                        :        上锁STM32的FLASH
    / a7 G0 v7 f, j: k' W5 r
  43. * 参数                        :        无
    , j  q0 K4 x" G- A# I- O. U0 e
  44. * 返回                        :        无
    - z1 Y) C! q  g6 ~# r3 K
  45. * 依赖                        :        底层/ ]. C1 k7 Q( D9 z+ X# p, {
  46. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    . ?2 c' p# C& p& Y' q
  47. * 时间                        :        2013-10-20
    ' N# s, ]5 ], X' i8 ^* l' Y
  48. * 最后修改时间         :         2018-01-13
    1 d# @  G6 O- N/ `& n# b7 U$ J
  49. * 说明                        :         . {6 F9 T6 n* d; y6 |
  50. *************************************************************************************************************************/
    ; U& ~7 T& F2 ^) A
  51. void STM32FLASH_Lock(void)  A  t5 i! d$ Y3 X+ D
  52. {
    # @% B: @* G6 Y, r/ ^- T  {/ w
  53.         FLASH->CR|=(u32)1<<31;                        //上锁: G  k* F  f. W3 E  `0 |- e
  54. }2 e! I* S9 N1 }" A& _
  55.   k4 w& |3 K: f" j! R
  56. 1 g! X: t) C+ |" Z, a9 ?# ^8 P

  57. ' h2 ^+ U5 s- |: M& X9 I" Q

  58. . o7 c  n; ]2 ^+ r5 E& H9 G
  59. /*************************************************************************************************************************: H! u/ Z+ G  K
  60. * 函数                        :        STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    & E3 J4 J  k- |
  61. * 功能                        :        得到FLASH状态
    ( x6 Z$ b8 e: N$ C4 w0 k2 I
  62. * 参数                        :        无  G8 `. Y4 s  f6 |
  63. * 返回                        :        STM32FLASH_STATUS' I& n" b% n- \# `
  64. * 依赖                        :        底层
    ' ?8 B" _! M: H; v: d# W: O
  65. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>4 g7 l' c! ?# W" W3 v
  66. * 时间                        :        2013-10-20
    # n8 m2 b5 f) x: q# J' g2 G1 f
  67. * 最后修改时间         :         2018-01-033 F2 L" {0 k2 c9 p3 J1 ~; @; o& t" N
  68. * 说明                        :         ( @6 S7 v/ x5 x4 l& N& w
  69. *************************************************************************************************************************/
    6 J- X8 A0 M: ~, W0 H6 G
  70. STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    : v* ~4 O4 i, Q" T* Y( J) [0 A, V9 E
  71. {        
    . E4 I6 c1 s6 D7 J: c6 t
  72.         u32 temp=FLASH->SR;
    ; ]  ^  F9 w9 o
  73.         
    - n  B, e8 Z3 s9 H
  74.         if(temp&(1<<16))return STM32FLASH_BUSY;                        //忙
    ( _9 z+ S3 e  z1 W
  75.         else if(temp&(1<<4))return STM32FLASH_WPRERR;        //写保护错误
    5 d; H5 }9 t) Y: V" Q) m) K: {. P& i9 I
  76.         else if(temp&(1<<5))return STM32FLASH_PGAERR;        //编程对齐错误, I; T+ S& }, r/ I+ K2 H' F
  77.         else if(temp&(1<<6))return STM32FLASH_PGPERR;        //并行位数错误
    6 _7 m) m) d. p6 [
  78.         else if(temp&(1<<7))return STM32FLASH_PGSERR;        //擦除顺序错误
    # e% h0 D! {; v1 k, L& M
  79.         else if(temp&(1<<1))return STM32FLASH_OPERR;        //操作错误
    ; b' H. D; b# E) U! P1 o5 t4 {
  80.         return STM32FLASH_OK;                                                        //操作完成
    $ I+ e, r! E! M4 r
  81. }
    % j6 b0 f+ B* V2 E

  82. ; L2 p+ K5 [# r
  83. 4 i) q2 u$ l8 A* J
  84. 2 h3 q1 z# T4 T9 ]1 u& `
  85. /*************************************************************************************************************************
    ' E* @+ |* Q, R9 Z7 `
  86. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)
    & A% a0 U2 t6 Y; g! |: B
  87. * 功能                        :        等待操作完成1 w/ N; O9 v1 w
  88. * 参数                        :        time:要延时的长短,单位us
      Z. F  y& F) w: j% [" \# ^2 U
  89. * 返回                        :        STM32FLASH_STATUS
    ; o* u; ?6 A! P# c
  90. * 依赖                        :        底层& ?9 k7 T  \" u% H) `6 b
  91. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>6 i, e: t+ j- [! Z
  92. * 时间                        :        2013-10-208 C! H6 O  u+ g0 l) h
  93. * 最后修改时间         :         2018-01-031 ]) K9 b$ G$ N! t# c; G$ R/ d
  94. * 说明                        :         2018-03-24:增加清除看门狗功能
    6 s4 F; V* ]. P6 }, Y9 o  O6 z, d
  95. *************************************************************************************************************************/
    0 T7 C! H0 j$ |; X" N
  96. STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)+ k$ l+ `) ?# d& T  l5 q
  97. {/ J8 x6 X- {7 Z4 A) i5 Z5 w, C5 O
  98.         STM32FLASH_STATUS status;
    - k' R* x1 `' e& |& V' L$ U3 x! c
  99.         6 b6 p/ J7 l# b' l
  100.         if(time < 1) time = 1;
    , P& ~% z5 f  ]
  101.         do
    8 T+ d' b" w, O% O( f. |
  102.         {
    : i1 i  q$ x9 d2 g  r" O( C
  103.                 status=STM32FLASH_GetStatus();                        //获取状态& ^  c7 Z* H$ F) r/ b
  104.                 if(status!=STM32FLASH_BUSY)break;                //非忙,无需等待了,直接退出.
    ; T5 f6 w2 G& E$ T8 g  L- F( ]# F  S8 D
  105.                 Delay_US(1);
    " I, M% o7 {; o0 o: x! i6 ]5 m
  106.                 time--;: N0 P7 F; V- Q1 U9 p# Z7 y4 N# ^
  107.                 + |/ j1 G) a# x( u5 f# Z9 d" s6 w% u
  108. #if(SYS_WDG_EN_) //使能了看门狗3 u( I! q( B% p* S7 D7 I# A! ~
  109.                 IWDG_Feed();
    ! `4 g1 O7 ]! [: o
  110. #endif //SYS_WDG_EN_        
    6 Q+ j1 E' y1 [' K; M8 w
  111.                 7 J2 d0 l. b, x3 |- Q8 U
  112.          }while(time);
    , @. ^7 H1 V7 ^( [
  113. . ~! U  f* ~9 g" }" A
  114.          return status;
    0 D; N" W! k# ~# B% o% i
  115. }
    6 ?$ w: l/ Q# p; {/ W7 ~" e

  116. 5 t# y& J& b) l- ^7 P

  117. & y* _; @$ [3 r/ G) ?& O

  118. - g' j) w* X' V6 Z; z( d
  119. /*************************************************************************************************************************/ c0 I- J2 u3 A5 }8 E0 F- ?6 p
  120. * 函数                        :        STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)
    ) c! Q: h6 O5 R0 K' N
  121. * 功能                        :        扇区擦除
    ) B8 R. ]" h. {( u$ e' R, }
  122. * 参数                        :        sectoraddr:扇区地址,0-11- c& K4 U  K1 X+ B2 g
  123. * 返回                        :        STM32FLASH_STATUS6 _# k% v9 N1 a. I1 F1 S, c% G1 I
  124. * 依赖                        :        底层# j' H1 `$ U8 v
  125. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    1 i- b7 Q- B0 }0 k4 Z
  126. * 时间                        :        2018-01-036 a3 g8 |+ B+ ?( v3 }1 t/ [; R
  127. * 最后修改时间         :         2018-01-031 M: u& O: j) k
  128. * 说明                        :         扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区0 O) b; N1 g; @- r4 Y) `( \
  129.                                         128KB扇区擦除足最大2秒4 l5 Y* |# Z# e1 a
  130.                                         2018-01-16:修复扇区擦除时没有解锁问题# q% K9 F) f8 l9 ]' J' v4 x
  131. *************************************************************************************************************************/$ ?8 h# v5 H1 z3 ]6 y2 c* W6 C
  132. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)
    2 i1 S  }7 r8 x! G% ]- f# h0 S- q
  133. {4 @/ ]& w/ ~- I& j4 w& g
  134.         STM32FLASH_STATUS status;; Q' k* [% X. [- U1 D
  135.         
    , }3 N! {( r. A
  136.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    5 T% M/ h) F3 W& T' b+ C1 [# i
  137.         {
    ( \0 Z9 ~# _5 n
  138.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    4 W7 ]- @5 N) X  z/ ]. A% p  w
  139.                 FLASH->SR |= FLASH->SR;# \) W  Q. R2 G
  140.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    0 C5 S! g1 C  M: T+ R
  141.         }: j; B% I1 P$ e
  142.         ( T3 t$ P( |0 h# l
  143.         status=STM32FLASH_WaitDone(2100000);        //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过
    ' V' U9 o; K9 G6 v) ~
  144.         " u% z5 p. A% N4 \
  145.         STM32FLASH_Unlock();                                        //解锁
    ; J9 R2 y! t2 a+ O9 F
  146.         if(status==STM32FLASH_OK)                                //没有错误6 A6 M4 [4 G+ V2 C& h: {/ Q
  147.         {
    3 [1 E$ D  n5 w+ j! ~# L
  148.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置- X2 ^) F5 ^1 \6 |" h  T. u  M
  149.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    : I# e1 M$ ~& M- q" m0 Y. ~* k6 q4 ~& N" `! b
  150.                 FLASH->CR&=~(0XF<<3);                                //清除原来的设置& J1 ^" e& Q" r  T
  151.                 FLASH->CR|=(sectoraddr&0x7)<<3;                //设置要擦除的扇区 % ^- s; Q3 `' H  j6 ^
  152.                 FLASH->CR|=1<<1;                                        //扇区擦除 # `0 ?3 a4 A( f/ q+ Q; `- V1 ?
  153.                 FLASH->CR|=1<<16;                                        //开始擦除8 R( r! @. p2 d
  154.                 status=STM32FLASH_WaitDone(2300000);//等待操作结束,最大2s  5 z% w% L8 O: C$ G. C2 n4 |8 J( u
  155.                 if(status!=STM32FLASH_BUSY)                        //非忙
    * o: R! }3 n& t0 p& g5 Y, C
  156.                 {/ Y$ i. L' o3 P# B
  157.                         FLASH->CR&=~(1<<1);                                //清除扇区擦除标志.
    & ~' |" |, `+ g8 x  k
  158.                 }
    ) b) o1 t8 `6 [& K  r
  159.         }6 r- J- U6 F+ _9 B$ `
  160.         //DEBUG("扇区擦除状态:%d\r\n", status);
    6 @$ k8 L: J  w4 x+ G
  161.         //DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n", FLASH->SR, FLASH->CR);# Y/ m4 ]5 h* e  t3 Q
  162.         * h( B5 |  u7 [+ G: Q; |5 o1 U$ N
  163.         STM32FLASH_Lock();                                                //上锁; R/ U. Q/ H3 ?! J% N/ T# ~9 j
  164.         if(status != STM32FLASH_OK)
    & _9 X# O" `) h) I8 K" v
  165.         {1 r: v& ~! W$ ~1 X
  166.                 DEBUG("擦除扇区%d失败(错误:%d) FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",sectoraddr, status, FLASH->SR, FLASH->CR);4 g3 m/ P/ X  M2 v
  167.         }+ n4 F& f/ l$ {
  168. * Q* l1 A: G: w& A* F% }* N' p8 U
  169.         return status;                                                        //返回状态
    % i# l" x# `+ ?% f2 B3 V
  170. }
    ! N+ w3 t& n$ q! D! A
  171. . f( C, c- J4 ]6 `0 d* J& W! d* h

  172. / s1 ~9 e" Q4 {0 \

  173. " L+ }2 f3 G% Q  \' S1 ~% x

  174. 9 F2 n- _$ J$ F7 p# X+ K1 E# B
  175. /*************************************************************************************************************************8 D* P' ~% ?6 t
  176. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)
    2 F& F, e* N6 M( h* A4 I
  177. * 功能                        :        在FLASH指定地址写入一个字的数据(32bit写入)9 V! q% L$ c" }( u5 v, L  y6 i: {
  178. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据' H) z! |. ?  |/ y9 w* ~
  179. * 返回                        :        STM32FLASH_STATUS: \7 [' q  f) @& i
  180. * 依赖                        :        底层" |5 ?# K% O3 r+ X. M
  181. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>5 P# J5 l- E1 M/ w+ h- l" W
  182. * 时间                        :        2018-01-03( W' Q5 I( z7 }/ k
  183. * 最后修改时间         :         2018-01-030 y0 V5 ^+ |. o/ h4 u
  184. * 说明                        :         警告,地址必须为4的倍数( Q0 d8 j; }+ z( h$ p: \; R
  185.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁. e# E2 P$ A1 _5 Z& W9 O7 ]
  186.                                         不会判断是否能写入
    8 M' q% k# {$ v! B
  187. *************************************************************************************************************************/2 U4 }" s% |  h
  188. STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)
    ! F6 w/ x- I( S
  189. {
      |! _) g8 [$ _0 U8 x
  190.         STM32FLASH_STATUS status;
      ?9 W. |8 \/ v% A
  191.         " ~9 C. J' Z/ l, x* Q) C( r  v+ d
  192.         status=STM32FLASH_WaitDone(200);                 //判断状态! M" V+ D1 y; r& y& R5 W5 j. o+ o" s
  193.         if(status==STM32FLASH_OK)                                //没有错误
    / K  z" L5 Y9 m: i
  194.         {
    9 N+ T. W' k% L: U# m
  195.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置$ l8 H" \0 M; ^6 f  p) _& c4 {& l/ s
  196.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    * E* C4 Q6 m4 X$ E0 i7 U2 Q5 b
  197.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误
    1 J" o& ?3 e5 W: g
  198.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    * \+ D% g' Y, Y: u. e
  199.                 *(vu32*)faddr=data;                                        //写入数据
    6 }" r$ \: H$ V) r7 Y% k) R* [1 m
  200.                 status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.
    & k+ R# |. |' w" W
  201.                 if(status!=STM32FLASH_BUSY)                        //非忙4 X8 m( c' `2 w+ U. v6 u- X
  202.                 {        
    - \6 `9 o7 a# n' n
  203.                         FLASH->CR&=~(1<<0);                                //清除PG位
    . C# s' I) c* ]5 ], \: u
  204.                 }
    : T1 Z* _9 {' t% Q
  205.         }
    8 m* B! D* A* `4 \; J8 T
  206. 0 q1 j0 W+ A, v
  207.         if(status != STM32FLASH_OK)! {5 T6 p- h# f+ w
  208.         {
    7 a# O! o) \2 p: p; M! U
  209.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
    ' t3 O) h9 Y3 h, H) K. I
  210.         }# B" e: u; Q+ X6 r6 a
  211.         0 }3 z: Q& m# U. X
  212.         return status;) {) W  ~, k" I, m+ g- f" q" X
  213. }
    4 z7 n( |  d. u4 C! Z
  214. 8 F. m2 _; x9 {. t

  215. " C5 v7 [4 W% P2 \
  216. /*************************************************************************************************************************
    9 \1 }% c& l1 J$ ~# m. H2 i; t+ n
  217. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)$ R# D3 f0 W/ o
  218. * 功能                        :        在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)6 ?* J6 f' M& d
  219. * 参数                        :        faddr:指定地址(此地址必须为4的倍数);data:要写入的数据
    8 J7 J2 H6 I: L; ^+ E
  220. * 返回                        :        STM32FLASH_STATUS9 J3 X( I+ y$ o3 E5 j& w# q
  221. * 依赖                        :        底层
    6 M- @. x5 U, r; {7 B. r
  222. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    0 T+ O# \8 e7 g! M# U
  223. * 时间                        :        2020-02-08
    ! V  N# K- L2 O" J
  224. * 最后修改时间         :         2020-02-08" N6 p6 H, ?. h1 s7 T; y% ^
  225. * 说明                        :         警告,地址必须为4的倍数
    9 Y( c" P: T+ L0 @( H- D; ?
  226.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    - k8 Y/ ]* k( P3 P0 L
  227.                                         不会判断是否能写入  o  u" M/ P, P: Z
  228. *************************************************************************************************************************/1 I! H+ b" m4 W: \+ U1 L" ]
  229. STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)0 l& c, `1 I5 c' e0 @
  230. {
    ; @/ y: N7 y! B1 w8 U: k( C
  231.         STM32FLASH_STATUS status;
    5 i, G9 z& _7 C+ `2 I* y8 t3 N

  232. * V  y# y5 S8 U! f1 L8 I' }
  233.         status=STM32FLASH_WaitDone(200);                 //判断状态! V. \. A& S: U' ?" ?+ D9 ^
  234.         if(status==STM32FLASH_OK)                                //没有错误
    & X) Y. l+ d' E2 y: W
  235.         {
    , b+ `) {$ Z7 i3 A6 c
  236.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    : ?" J3 `- Y5 Y2 N
  237.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    ( h, x; t: _5 x0 b' {1 @2 W" n
  238.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误- ~( y. m0 g2 O. Y( g
  239.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        6 U' {" P8 O/ c0 G! |: D
  240.                 while(dWordCount --)0 n8 |$ `- `* d
  241.                 {: c4 D  n- K, w- T6 w% w: r" v
  242.                         *(vu32*)faddr=*data++;                                //写入数据
    . H2 `9 D6 K' h. m% t
  243.                         faddr +=4;                                                        //地址自增+4
    4 k& s( D! I: @
  244.                         status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.
    ' m' ~8 w6 R; ~- g. ^7 B% y
  245.                         if(status!=STM32FLASH_OK)                        //有错误! j; S" o$ V0 T) Z- Q8 ~8 Q
  246.                         {
    3 T2 ~( N, I0 y. I
  247.                                 break;
    ( C. Z- G, i  J% Q) ?* Q4 _
  248.                         }
    9 c4 y; ^: `9 V5 V
  249.                 }
      X" F* H- L. V6 J

  250. $ E- M5 e9 Y+ m1 j. _# X& T. `( C
  251.                 if(status!=STM32FLASH_BUSY)                        //非忙
    0 A, |  T7 g: l4 M6 A' ]
  252.                 {        
    : w' ^! Y, M- F! _% }
  253.                         FLASH->CR&=~(1<<0);                                //清除PG位
    9 V* ?1 R) A  T# n
  254.                 }
    % y  f7 {! ]2 t( M
  255.         }
    9 v8 r8 ]+ r" k  ?# ]+ q" z9 c
  256. # _/ |; j& Z4 F! n
  257.         if(status != STM32FLASH_OK)
    6 b9 ^; h9 C; H; R
  258.         {
    7 Y2 u7 i4 w( i) d. H
  259.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
    - a4 v% u0 L" Y: {
  260.         }
    ( B; T9 R: U1 x! t* ~+ i$ |$ {
  261.         
    4 |. @4 H# b/ K7 E- m4 u3 Z
  262.         return status;3 ]' l  d, S7 ^4 v7 B7 Q2 O. S
  263. } ( F' @8 M' W/ ^9 L9 g
  264. ; y; i, `- }2 S* s* d$ F. _
  265. ( w% [' W$ O0 e1 _6 E* V
  266. /*************************************************************************************************************************3 \* E9 B& g$ X( p7 x8 ^
  267. * 函数                        :        u32 STM32FLASH_ReadWord(u32 faddr)
    4 f/ M" R5 ~; J8 o7 V' G9 [
  268. * 功能                        :        读取指定地址的一个字(32位数据)
    % ~7 N6 R: o- H
  269. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);; v* A, b: l( _  D1 ~
  270. * 返回                        :        数据. m! Q1 n* K- c, E0 y
  271. * 依赖                        :        底层$ x6 g. S, y3 E
  272. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>9 v" v+ }5 a8 s9 ]4 E
  273. * 时间                        :        2018-01-031 Q/ v* h- G4 N& w7 s
  274. * 最后修改时间         :         2018-01-03% o2 R& a' T6 R$ l' V( j2 @
  275. * 说明                        :         警告:地址必须是4的整数倍
      y$ f- ]4 m) T2 x* p; U1 `
  276. *************************************************************************************************************************/: O' b5 \, x3 i# @% ^* |
  277. __inline u32 STM32FLASH_ReadWord(u32 faddr)
    ; s+ Y0 F9 m. r' J! p1 d  Y" ~
  278. {6 \% k3 O( L& x5 e7 b/ ~
  279.         return *(vu32*)faddr;
    & x5 e" v! B0 s! U9 f  V
  280. }3 e" L0 F0 n9 M( v/ x+ _+ Y6 K

  281. ) g1 E- C; q1 p- U

  282. 7 x) k/ F. V6 `0 y
  283. /*************************************************************************************************************************6 \2 ?6 t7 x/ \9 ^. M1 f
  284. * 函数                        :        u8 STM32FLASH_GetFlashSector(u32 faddr)
    + e3 J( _' U9 [. w
  285. * 功能                        :        获取某个地址所在的扇区
    ) I$ ~( b! _9 ~( q4 N3 k
  286. * 参数                        :        faddr:指定地址, w+ c" J$ w  @6 L% {
  287. * 返回                        :        删除编号,0-6,如果超出了也会限制到63 y9 z9 n* E; g8 x% C
  288. * 依赖                        :        底层# T( n7 `5 _. |0 l
  289. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>' |1 W0 T" s2 G
  290. * 时间                        :        2018-01-03
    $ `: W0 O7 }+ D: Z- C: z
  291. * 最后修改时间         :         2018-01-032 @7 d% u* u2 {# y0 `( a2 \
  292. * 说明                        :         地址请不要超出范围
    ( k8 y8 @9 Z. G+ d% ]+ T
  293. *************************************************************************************************************************/
    7 {( \7 K: z/ _, ?
  294. u8 STM32FLASH_GetFlashSector(u32 faddr)2 r. h( `, B. b
  295. {8 i; T! B6 Q0 \( f) o" R4 G3 h
  296.         if(faddr<ADDR_FLASH_SECTOR_1)                return 0;2 d* O+ N. b& H+ i2 E6 j0 Z, o9 U
  297.         else if(faddr<ADDR_FLASH_SECTOR_2)        return 1;8 v4 B7 ^0 |% Y9 C" P# ^
  298.         else if(faddr<ADDR_FLASH_SECTOR_3)        return 2;
    & d9 E1 w2 X& m& s" L. G" A* e
  299.         else if(faddr<ADDR_FLASH_SECTOR_4)        return 3;
    $ u" \: B) X/ ?) F, |. A9 m( a4 l
  300.         else if(faddr<ADDR_FLASH_SECTOR_5)        return 4;
    & D) i7 Q. d: ~- G5 c3 g
  301.         else if(faddr<ADDR_FLASH_SECTOR_6)        return 5;- w& }/ z& J) M4 {! }. @
  302.         else if(faddr<ADDR_FLASH_SECTOR_7)        return 6;2 r0 x  J1 M: U# H
  303.         else return 7;        * z# N) t6 K3 P- ?; i1 S
  304. }
    7 @- N( `# V) I3 `( o8 S

  305. & P* k* i! L, V, |2 G. Q( B+ ?

  306. ; F- v- Z! o+ o2 S# `3 s
  307. /************************************************************************************************************************** v: F- S/ {4 m, ~4 f6 x
  308. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  " u- A- z" W  Z3 P# f8 ]# m& F. o- F
  309. * 功能                        :        不检查的写入% T0 D+ y- a! ~* o, K, ~
  310. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数 $ N; n/ L1 T. a; O0 s1 r5 j
  311. * 返回                        :        状态
      c0 a- V& Y* U4 {
  312. * 依赖                        :        底层' ]: I8 u: s. z
  313. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ( F; m) G1 U' u7 @0 O, y
  314. * 时间                        :        2013-10-20
    1 y2 F/ I" o3 d! M% N/ E
  315. * 最后修改时间         :         2018-01-03
    8 M0 o, D1 K1 x, f, \& j
  316. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)
    ' X2 j5 S" ~7 ^2 t- Y
  317. *************************************************************************************************************************/  e6 M* S% W) A; R7 j' o' F4 N
  318. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   
    9 E# s% h7 ?4 w
  319. {                                           & Y& r9 p- k* U2 @0 `
  320.         STM32FLASH_STATUS status;
    ; Y/ f5 o" H6 ?# d9 _
  321.         , `# w. _8 F8 ^* j4 z: g8 F" ]
  322.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误, J8 B' S3 d) x) J/ e
  323.         STM32FLASH_Unlock();                                                //解锁
    $ R8 Z# q( w6 F) c  K# }
  324.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现# [: k! `# d% m' Y
  325.         {- k( n5 M, D7 N6 A2 p& T# D
  326.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);) n/ {' g& Z; M2 l
  327.                 FLASH->SR |= FLASH->SR;# G3 T: m( o9 x# r* n- N- _+ A
  328.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);$ h8 x- x, W4 j  n
  329.         }3 a3 v8 Y. F2 ~1 M* f% q
  330.         status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据1 k: Z7 [% y5 Q8 Q( I1 V
  331.         STM32FLASH_Lock();                                                        //上锁
    4 Y6 L6 L5 }: _: T! O4 f
  332.         return status;
    , C: h8 |7 h% {9 f" P
  333. }
    # u/ y; u9 o1 U9 N+ n+ ~$ @7 R
  334. ; |2 G* Y) l. T5 A- ~6 \

  335. 8 c2 A6 J& K2 y, L, {" p+ r( b5 p
  336. /*************************************************************************************************************************
    6 k4 |' P& W* G0 t7 b; r
  337. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   5 _4 Z) r9 z$ {* f, J: C  F( y
  338. * 功能                        :        不检查的写入一个字, D3 [* s; i: K5 f. t
  339. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);data:要写入的数据值9 z2 ]* O& K2 n1 b6 T- h
  340. * 返回                        :        状态) w# a, z5 l6 G4 Z, z
  341. * 依赖                        :        底层
    3 Y, G  o2 |2 e: L) N  @( \6 a3 U
  342. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    6 v+ C0 _  y' B! d) e
  343. * 时间                        :        2020-02-08
    ; v! G; ]+ Z8 g/ m8 a" O
  344. * 最后修改时间         :         2020-02-081 x+ A& V. g. d8 c
  345. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)% y1 M4 p' t- o! D" c, j& a
  346. *************************************************************************************************************************/; b% c, C# G$ A. h/ S3 C
  347. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   . q9 K1 n- t3 S
  348. {                                          
    ( t. E  q7 L8 m# x1 B
  349.         STM32FLASH_STATUS status;
    7 A. r' F: Z9 ?3 A4 \
  350.         + E/ n. u' A7 H% P: \6 q
  351.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误% ]0 `+ d& A, [; p# t8 b* q5 X
  352.         STM32FLASH_Unlock();                                                                                                        //解锁
    , Z7 t3 M4 K; t& V) |. j% V, P
  353.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现" ]3 |: Q& f- W$ v5 s9 H+ l3 ?
  354.         {
    $ A) s! a( F; U# W7 [1 w0 f
  355.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);5 {) X5 w7 K  c- t
  356.                 FLASH->SR |= FLASH->SR;
    " f) ^3 l6 }% D6 z. \* J1 c+ y
  357.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);8 |0 M* z6 ?/ [: D
  358.         }
    " u: ~9 X/ H$ c
  359.         status = STM32FLASH_WritedWord(WriteAddr, data);                                                //写入1个字的数据5 ^  M( y. r" u; o# }# b6 S
  360.         STM32FLASH_Lock();                                                                                                                //上锁8 o# t9 D6 _: g2 P$ A
  361.         return status;% b9 \  o7 L' s' @! M
  362. }
    ( T( v5 `2 _9 W  x( O
  363. 6 a8 j7 H( N. _% R" b2 @2 y
  364. # F# ^& B* Q) I1 x% i0 i$ r; k4 M
  365. /*************************************************************************************************************************
    ' P( P+ o. @( h1 B: O' P/ E
  366. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        9 c* f, u" Y/ c/ A: k- B
  367. * 功能                        :        从指定地址开始写入指定长度的数据(数据长度字为单位)
    " v) ]; R7 o) z% j) f. ?0 X3 B% d: I
  368. * 参数                        :        WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.)- V. E, h7 R  C
  369. * 返回                        :        0:完成;1:忙;2:错误;3:写保护) |8 L2 k2 J; [+ H# \
  370. * 依赖                        :        底层+ k& P7 B+ F8 e5 w5 b7 F6 x
  371. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a># O5 ^. e. {8 b  l/ v' v) U- j
  372. * 时间                        :        2013-10-20
    # ^+ ^& f* E' \9 f! L5 z6 |
  373. * 最后修改时间         :         2016-01-07
    " F- w2 |1 z6 O. i2 M9 n
  374. * 说明                        :         警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据
      _0 C6 E" R9 }/ l+ l# C! N
  375.                                         如果需要保存其他的数据,请在应用层进行实现(比如:先读取扇区,修改扇区,擦除扇区,写入扇区,需要大内存支持)
    0 n. M+ I8 d9 ~& R. I, P
  376. *************************************************************************************************************************/ ! O. l+ `# ~) [9 W
  377. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        
    ) K! D4 c. L+ q6 {
  378. {9 {  ^) p& M  U; v% B
  379.         STM32FLASH_STATUS status;
    & a( S( @; e  b9 f/ ^( f
  380.         u32 addrx=0;5 I1 T8 K! u" o  v) z9 ~4 d8 u% f# A
  381.         u32 endaddr=0;        6 o7 H9 p0 F/ R. ~6 z* _" o
  382.          
    + `( n! O" W3 `0 x" Q
  383.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR;        //非法地址- a! b" f/ f6 _" p4 o: a
  384.         : t& O. R9 Y1 G; D" e, S9 a( w" Z
  385.          FLASH->ACR&=~(1<<10);                                                                //FLASH擦除期间,必须禁止数据缓存!!!搞了我两晚上才发现这个问题!6 D! v- O4 A& b
  386.         addrx=WriteAddr;                                                                        //写入的起始地址
    9 x- b% ?- c5 `
  387.         endaddr=WriteAddr+NumToWrite*4;                                                //写入的结束地址
    9 P1 Z+ J# o: N3 V, T
  388.         1 t" w$ w" Z2 N9 C$ p
  389.         if(addrx<0X1FFF0000)                                                                //只有主存储区,才需要执行擦除操作!!: r. L( U; Q7 X
  390.         {1 i: p) n1 k! p6 l
  391.                 while(addrx<endaddr)                                                        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)( v1 I2 U( ~+ V" J2 R/ ^1 J
  392.                 {
    ( C. F% ^- U& ?  j# Y  T. N
  393.                         if(STM32FLASH_ReadWord(addrx)!=0XFFFFFFFF)        //有非0XFFFFFFFF的地方,要擦除这个扇区$ L- h% w& n- p; g) J" d
  394.                         {   
    ( a5 U$ k$ Z, F- k) @; R# g8 s
  395.                                 status=STM32FLASH_EraseSector(STM32FLASH_GetFlashSector(addrx));" [' h$ @0 _  i1 H( x
  396.                                 if(status != STM32FLASH_OK)break;                //发生错误了
    % Z% f  c. [( P2 C3 K6 ?; ?
  397.                         }else addrx+=4;
    - L) S6 W( w: ~4 c1 o
  398.                 }
    5 w* C3 V, ?, s- e
  399.         }
    * H/ ]4 K: s' V2 G- G* X3 n
  400.         if(status==STM32FLASH_OK)& z; k1 ?! X6 Y: ?- Z  Q6 N
  401.         {
    6 E% s) k3 }, H8 }1 a0 T* [
  402.                 STM32FLASH_Unlock();                                                        //解锁
    , c( M, K, j+ Y3 }
  403.                 if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现+ W- _. R7 r1 s" |: ?
  404.                 {
    / Q: `2 T9 i, S- f7 F
  405.                         DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);# `, b2 [2 ~  `0 J5 p1 B
  406.                         FLASH->SR |= FLASH->SR;
    6 U* }1 B/ x) m! f% f$ B1 U
  407.                         DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    7 b6 _. P2 b: w6 P" r+ ?
  408.                 }  a! W6 n7 s! h3 [& H0 I" m; y
  409.                 status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据
    2 B  y9 d! [0 f7 ^0 n
  410.                 STM32FLASH_Lock();                                                                //上锁
    6 R3 |6 e2 K! b2 f
  411.         }5 A8 ^+ f  o( f( y, I4 h
  412.         FLASH->ACR|=1<<10;                                                                        //FLASH擦除结束,开启数据fetch- U+ Z# s# D% p& V7 m
  413.         
    6 a! G+ e' ~+ z- q) Q1 x/ i7 ~( F
  414.         2 Q$ J! j/ o1 g% g- ?
  415.         return status;7 [5 w+ L. l: G8 u$ J
  416. }
    9 B3 q) p3 C9 s7 i( N
  417. / }$ U8 V) M( m+ l* R) F

  418. , F; V% l# @6 {9 t- y8 Y7 F

  419. 2 N8 R  i' S  i/ x" v- \3 I

  420. - N9 u" }4 r/ \/ {$ c
  421. # n3 k6 W3 u6 L0 O2 j& j
  422. /*************************************************************************************************************************. z& H' H3 [! R4 Q, ~* p. X' C
  423. * 函数                        :        u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead) 7 t9 Q% y, K+ m. g2 I7 H
  424. * 功能                        :        从指定地址开始读出指定长度的数据
    : L9 M% k6 m8 h: s
  425. * 参数                        :        ReadAddr:起始地址;pBuffer:数据指针;NumToWrite:字(32位)数
    # T5 Z0 d7 `* u% x$ O" F5 y
  426. * 返回                        :        读取的数据长度(字为单位)' o  Z8 Z! ~! X; m; j# b
  427. * 依赖                        :        底层7 `1 _$ Z: l5 x& j
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    " k% k: ^& l& B: |6 E
  429. * 时间                        :        2013-10-20
    4 O, J0 S8 d- A/ Y2 ?1 W
  430. * 最后修改时间         :         2016-01-07! x% O1 a( e( @2 E
  431. * 说明                        :         地址必须为4对齐
    , O; m) N* d- `0 b) T/ t8 g. z
  432. *************************************************************************************************************************/
    7 ?3 [. ^3 C  `  B9 ]) u
  433. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)           9 p' R. @' v4 \7 {$ ~9 U
  434. {! x! U  b) v( P  p( x
  435.         u16 i;
    ) ?. Z* d( [3 t! @& F& g- v! I
  436.         u16 cnt = 0;
    * \. m) k# n2 P
  437.         
    4 i, W( Q. F' _
  438.         if(ReadAddr<STM32_FLASH_BASE||ReadAddr%4)return 0;        //非法地址/ S/ D) n2 h) d& i" W$ b
  439.         
    % v& j( Q* h. \5 C
  440.         for(i=0;i<NumToRead;i++)
    2 X. y2 R9 O+ f8 A
  441.         {
    1 H& s6 c6 E( z0 Q8 v; m' X
  442.                 pBuffer=STM32FLASH_ReadWord(ReadAddr);                //读取4个字节./ g4 e% c3 g$ Y: P& C/ Z
  443.                 cnt++;
    7 D2 I- y* I2 Y0 _. |5 V
  444.                 ReadAddr+=4;                                                                        //偏移4个字节.        % ?: L" m; q( l/ J% d# s5 k
  445.         }
    ! L# L" V. e# T( `- v
  446.         return cnt;1 I/ G/ i& c! o3 G$ |( j; y
  447. }
    3 s+ g6 h& A4 x

  448. 2 [4 ]3 P) |& N7 C7 b! X7 y

  449. 6 Q% W+ Q0 l2 O# u0 ?7 _$ T
  450. /*************************************************************************************************************
    ' p& y; [8 w* T$ P9 ?1 F$ U
  451. * 文件名:                        stm32f7_flash.H
    " I4 L; j0 Y4 Z( i9 \8 N6 ]0 V
  452. * 功能:                        STM32F7 内部FLASH编程驱动函数
    % D! J9 f; T7 m; }3 P, i
  453. * 作者:                        <a href="mailto:cp1300@139.com" style="">cp1300@139.com</a>) J1 h  _  w5 X) Y8 Z8 W. N# P2 u
  454. * 创建时间:                2013-10-20
    / T. r+ G' P& w0 G; C, N( V
  455. * 最后修改时间:        2020-02-076 d  j, n/ N% |0 O. U3 V! Y
  456. * 详细:                        用于STM32F7内部flash读写驱动) S6 c: \; ^, E
  457. *************************************************************************************************************/
    ! B, t5 x! Y  U1 p. N% A. T
  458. #ifndef __STM32F7_FLASH_H__# g6 d: f5 E( o; z$ S" L
  459. #define __STM32F7_FLASH_H__/ c3 l4 W3 w3 K& `3 m% i0 A
  460. #include "system.h"  8 X/ k- \( I9 r% |; J
  461. * ~$ T! }+ l! J
  462. //FLASH起始地址( N2 M* A- l: y; `% K# ~+ s
  463. #define STM32_FLASH_BASE                 0x08000000                         //STM32 FLASH的起始地址& s/ {) U# R1 g: _" r3 H( Z8 Y

  464. + I6 `* {! H! r1 V; }; T+ c! R" j* f
  465. //FLASH 扇区的起始地址
    : f6 [; P' {# _' h+ o
  466. #define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)         //扇区0起始地址, 32 Kbytes  
    3 @3 e, A# g$ t& q- g3 \: Z6 E( y) O
  467. #define ADDR_FLASH_SECTOR_1     ((u32)0x08008000)         //扇区1起始地址, 32 Kbytes  
    ) I) c& r$ i6 A3 ?1 g) l# [# A: Y
  468. #define ADDR_FLASH_SECTOR_2     ((u32)0x08010000)         //扇区2起始地址, 32 Kbytes  
    8 p) ]) |& E; _3 t; B3 E
  469. #define ADDR_FLASH_SECTOR_3     ((u32)0x08018000)         //扇区3起始地址, 32 Kbytes  
    5 I% T! c7 L- R# J. S' z
  470. #define ADDR_FLASH_SECTOR_4     ((u32)0x08020000)         //扇区4起始地址, 128 Kbytes  
    ) U6 B7 ]" n5 d" I( ?# x
  471. #define ADDR_FLASH_SECTOR_5     ((u32)0x08040000)         //扇区5起始地址, 256 Kbytes  
    : G6 j' e& X9 l" _& ?; U  T2 X
  472. #define ADDR_FLASH_SECTOR_6     ((u32)0x08080000)         //扇区6起始地址, 256 Kbytes  
    ( ]: b7 X" y% ^' G4 R
  473. #define ADDR_FLASH_SECTOR_7     ((u32)0x080C0000)         //扇区7起始地址, 256 Kbytes  
    ! b2 K' Q" c' Q- _) K: Z
  474. 1 B: R# o% a9 I0 z( C% H

  475. " i4 U  s+ R# H$ k
  476. //FLASH解锁键值
    ) R: F7 g2 E6 k1 A
  477. #define RDP_KEY                  0x00A5+ l- Z$ E" ]' L: O6 `
  478. #define FLASH_KEY1               0X45670123  }6 y/ o, Q* L# g( P. d) ]' {
  479. #define FLASH_KEY2               0XCDEF89AB& r7 E3 A$ i7 n8 A- T. W
  480. #define FLASH_OPT_KEY1           0x08192A3B
    ; E) X: g  q7 v" W* O3 A
  481. #define FLASH_OPT_KEY2                         0x4C5D6E7F3 W4 a8 B& P  ?2 \0 B+ z4 G: d8 X
  482. # L0 X# D/ c- H
  483. //STM32F7 Flash操作状态
    ! U& B: [/ G, C2 ?0 U5 P
  484. typedef enum, t( ~5 w. S$ B! _- H
  485. {
    & [+ \4 |  o7 X( |! \1 Z  h
  486.         STM32FLASH_OK                        =        0,        //操作完成5 N) ~0 C6 [' `2 V: s/ @
  487.         STM32FLASH_BUSY                        =        1,        //忙' M( a! N) m. A7 ^6 o  N$ S
  488.         STM32FLASH_WPRERR                =        2,        //写保护错误1 ^, P% Q4 K% a- C% u- g
  489.         STM32FLASH_PGAERR                =        3,        //编程对齐错误,必须128位对齐
    ) p4 T6 F; l, C; K' e4 L
  490.         STM32FLASH_PGPERR                =        4,        //并行位数错误; k% G5 w% I( S6 l7 S9 _
  491.         STM32FLASH_PGSERR                =        5,        //擦除顺序错误
      [% x! i7 t; m& z% h# U  q
  492.         STM32FLASH_OPERR                 =        6,        //操作错误+ ~0 j& V' ^6 w% T0 m% u# e
  493. }STM32FLASH_STATUS;1 I& m2 ?0 t$ j2 V0 g
  494. " c7 C3 r2 ^& v' m! _3 h7 @% `1 X" r
  495. //常用接口. S* |$ a$ T' N; F' {! G3 H
  496. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr);                                                                  //擦除扇区
    ; g! H3 }6 m3 Y  P2 F
  497. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite) ; //不检查的写入多个字的数据5 Q. G; t, C1 o$ g3 f' U. X9 N* L
  498. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data) ;                                //不检查的写入一个字的数据4 t6 \; f! Z0 W# w9 A
  499. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite);                        //从指定地址开始写入指定长度的数据(数据长度字为单位)
      ^# }" [1 q- R+ a& h! R
  500. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead);                                                        //从指定地址开始读出指定长度的数据
    7 u: _3 c* N/ y1 d3 i, W

  501. 5 i! [  r' y" _- e$ g
  502. //不常用接口) e; h% p1 X$ V' I; I
  503. void STM32FLASH_Unlock(void);                                                                                                                        //FLASH解锁# N( S. @! p3 U+ D! K
  504. void STM32FLASH_Lock(void);                                                                                                                                  //FLASH上锁, j: `  x& w4 x9 H
  505. STM32FLASH_STATUS STM32FLASH_GetStatus(void);                                                                                          //获得状态* H. o0 L  O: F1 F
  506. % t8 }7 h5 d. H( E  s4 h) H
  507.   C! |$ ^& ^& p( h) f' o
  508. #endif        //__STM32F7_FLASH_H__3 u# _. z9 t, D: v

  509. 4 e: c+ f2 S8 ^" n7 U8 N2 w. }
复制代码

) \5 ?3 r0 l- |5 D5 F9 Z
收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

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