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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
总体来说与STM32F4操作是一样的,就是扇区大小变化了,测试过程中发现当PG=1之后立即写入数据到flash会造成编程顺序错误,通过增加一个nop的延时即可解决此问题,还可以通过将多个数据连续烧写的方式避免此问题,就是当PG=1之后,把所有数据都烧写完成后再将PG=0,不要频繁的开关。
- ?) l/ J# f9 ^  H  }  S+ d+ g& A, |( W6 ^: @8 S# O$ O) t+ B8 M1 W
  1. /*************************************************************************************************************
    $ P$ t( H; [8 f# D  \
  2. * 文件名:                        stm32f7_flash.c
    3 d- |0 m: g3 S- ?
  3. * 功能:                        STM32F7 内部FLASH编程驱动函数
    : L" B! f+ Y. M5 D6 d
  4. * 作者:                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    * K8 L$ p0 c; J- t
  5. * 创建时间:                2013-10-20% F% o3 S$ V/ G
  6. * 最后修改时间:        2020-02-07
    ! z/ ?) L9 p: Y. O; c
  7. * 详细:                        用于STM32F7内部flash读写驱动
    : ]3 }. L4 j8 K" h5 e' P! p
  8.                                         默认为3.3V供电,并且宽度为32bit;
    ' Z0 Q0 Q( t* e7 Z  k. u
  9.                                         扇区擦除最长时间:32KB扇区500ms;128KB扇区1.1秒;256KB扇区:2秒$ T* I" n7 z' V' t" K, R
  10.                                         修复STM32F7开始写入数据时,PG=1后没有延时导致异常,增加批量写入多个字的数据函数STM32FLASH_WriteMultipledWord()支持。
    - h6 ~. W  Q; u
  11. *************************************************************************************************************/
    2 Q( }! D# E3 A; E/ {
  12. #include "stm32f7_flash.h"- F2 L' R7 o: ]9 V+ g
  13. #include "system.h"
    7 E) E- J) i4 W3 V2 _, j! r
  14. #if(SYS_WDG_EN_) //使能了看门狗* J, @( R7 m1 S8 _" n
  15. #include "wdg.h"- t% M/ l. w# Q8 S- g$ H6 r2 y* h
  16. #endif //SYS_WDG_EN_2 `5 W: p. F$ X( y# S
  17. 2 o7 j7 z: K! N) D

  18. * I: N. p6 P4 N" Y3 X( ?

  19. 6 Y- ]9 `' g2 ^1 j( H9 S, ?9 }1 ~# Z" j

  20. ' B) [1 r  Z. B  X
  21. /*************************************************************************************************************************/ Y. F0 y6 _1 t
  22. * 函数                        :        void STM32FLASH_Unlock(void)
    ) l, N. B9 X% s$ m. h; c, p
  23. * 功能                        :        解锁STM32的FLASH! j' k1 O9 E2 ~9 s2 ?& q
  24. * 参数                        :        无
    ! A5 U$ p2 B8 v& ~9 i9 ~: ^
  25. * 返回                        :        无$ d, `- u% E1 z8 b1 Q& K" A& ?
  26. * 依赖                        :        底层
    9 H9 W0 t  B4 c$ W+ l3 C0 l
  27. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>% |" A. L& l9 i: }4 w
  28. * 时间                        :        2013-10-20
    6 N# R- `2 b( _* Y4 f7 s/ R) s4 o
  29. * 最后修改时间         :         2013-10-20
    6 B: L! @% ]  [' u8 x8 F- I
  30. * 说明                        :         
    * w# b) G) U- m3 }# m& c6 G8 A0 E) L+ R- S
  31. *************************************************************************************************************************/
    5 y9 y' I5 r' y% K. a) Q
  32. void STM32FLASH_Unlock(void)- Q( f1 H8 S0 ]# O# t* j
  33. {
    $ H! y9 O. z9 }7 f4 B! q* g! l* \
  34.         FLASH->KEYR=FLASH_KEY1;        //写入解锁序列.
    ( p! Z; q# f# D4 E, I
  35.         FLASH->KEYR=FLASH_KEY2;4 |4 v5 `2 f  V0 V* y/ G
  36. }- p# Q" ?5 c4 x
  37. * c) j$ `) [7 f
  38.   y2 V) m% F# q

  39. # y% b! h' S2 i+ ]2 E
  40. /*************************************************************************************************************************
    3 [& A; o* E1 ^8 C9 q# ~  n( j
  41. * 函数                        :        void STM32FLASH_Lock(void)
    9 I/ v1 H6 y. ]3 r; O8 E# {& z: `
  42. * 功能                        :        上锁STM32的FLASH, N" j& }  z" w4 s! ]) d
  43. * 参数                        :        无$ O# C1 C. Z- Q4 l
  44. * 返回                        :        无  N- R/ N# ~- W1 W  }3 L- _
  45. * 依赖                        :        底层: x& v; r$ l7 n, }7 y; s7 u" t
  46. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    + Y' U& `: G, W
  47. * 时间                        :        2013-10-209 v1 r1 T" `5 t# W0 Y, o% \
  48. * 最后修改时间         :         2018-01-13
    ' J$ l* e3 S0 i" b% ]1 Y
  49. * 说明                        :         6 ~7 o' w$ `) }! x, E7 u! e
  50. *************************************************************************************************************************/
    0 }7 m! f$ m7 e) ]/ X/ O
  51. void STM32FLASH_Lock(void)
    9 N1 {' b3 B* e" h$ p- t
  52. {
    ' Y  C0 ]: R  k( w7 T
  53.         FLASH->CR|=(u32)1<<31;                        //上锁
    # p" M9 d/ Y/ a
  54. }
    ' t, u, J/ C! X0 _# Z
  55. " V- [' Q* M4 W9 v$ Z
  56. & S  K$ c% ]" R; [

  57. ; O/ [4 Q+ M" o7 y, t% p
  58. ! v( s# l, k+ ?1 c/ ~& u3 {
  59. /*************************************************************************************************************************3 v) ]; {0 A/ a' P. \# l
  60. * 函数                        :        STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    : k' k7 K9 P: [4 v+ e. K) @* E
  61. * 功能                        :        得到FLASH状态
    - j* W% I$ J6 s( k) I2 `! o
  62. * 参数                        :        无
    ; o# ?3 s; Y; T2 a6 _/ ~7 ]
  63. * 返回                        :        STM32FLASH_STATUS& ~# b. _! _) I: A% q7 X6 o
  64. * 依赖                        :        底层6 q0 ^: H1 g. H; s, ?1 S
  65. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    % \7 z' Y9 _- A4 L: |
  66. * 时间                        :        2013-10-20" s# `7 O. J7 a! X! k
  67. * 最后修改时间         :         2018-01-03
    9 j; j' v4 v- Z( P2 v+ c
  68. * 说明                        :         + e# G! Z4 k2 n1 C2 y
  69. *************************************************************************************************************************/- x, w  Y) Z+ z) A3 ~
  70. STM32FLASH_STATUS STM32FLASH_GetStatus(void), m0 \* Y3 d0 J0 Q9 L5 x: V1 `
  71. {        / n. y6 E4 ]4 w
  72.         u32 temp=FLASH->SR;
    ) D( S  u* J4 ^
  73.         4 s3 K/ L. z: G6 e3 Y; ]
  74.         if(temp&(1<<16))return STM32FLASH_BUSY;                        //忙. ]7 W2 s8 S# Z6 v) x
  75.         else if(temp&(1<<4))return STM32FLASH_WPRERR;        //写保护错误
    / `# m3 d7 t* C6 X8 Z( {2 k
  76.         else if(temp&(1<<5))return STM32FLASH_PGAERR;        //编程对齐错误, h0 e+ h% Z! L5 R7 C' C7 H  }
  77.         else if(temp&(1<<6))return STM32FLASH_PGPERR;        //并行位数错误
    ) i1 K  F8 L! S" F, @
  78.         else if(temp&(1<<7))return STM32FLASH_PGSERR;        //擦除顺序错误/ t8 @1 w% z7 u! {
  79.         else if(temp&(1<<1))return STM32FLASH_OPERR;        //操作错误0 |, @0 v1 R3 i( M: I, U1 l) S1 D% P
  80.         return STM32FLASH_OK;                                                        //操作完成
    " a0 f0 z2 S) Q/ H$ D
  81. }
    3 a. Q: k# m' ~! A1 s+ S, ]- A

  82. $ t0 L1 O+ _4 C1 |) q2 L. a

  83. . G6 X1 t. L( l$ a7 h/ l
  84. # f' m0 @3 g/ x8 @, B
  85. /*************************************************************************************************************************: `/ F+ X  y7 `% W' ^" y
  86. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)* Z5 h! w9 x* a3 H' S
  87. * 功能                        :        等待操作完成
    1 v* c5 R  S0 N1 o" J
  88. * 参数                        :        time:要延时的长短,单位us
    ; i9 Z4 U/ R) t# L6 z( Y9 R8 W, j4 \" s
  89. * 返回                        :        STM32FLASH_STATUS
    4 p* W' a2 e$ s' d6 I
  90. * 依赖                        :        底层
    0 L& X3 A) |6 ^; n$ D1 d$ l- L
  91. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>* S/ ^/ [, Y  C3 n' c! X
  92. * 时间                        :        2013-10-20
    % V% h* k5 A+ M
  93. * 最后修改时间         :         2018-01-03) z# {9 @2 V/ {  w: Z
  94. * 说明                        :         2018-03-24:增加清除看门狗功能
    : k1 I6 z. A/ C) l2 m: x2 s2 I
  95. *************************************************************************************************************************/7 m+ X6 ?0 |- j4 i6 L( Y
  96. STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)
    ) j0 a* Q9 Y+ Y) ^! m0 r, Z
  97. {$ i' o: |$ l, V% P( o# F! o
  98.         STM32FLASH_STATUS status;6 i$ ~- S7 s; D3 ~' w  {
  99.         9 q4 `$ j4 I" m6 O, O" m) ^
  100.         if(time < 1) time = 1;
    6 P6 a8 O9 p) M) k; f8 C
  101.         do
    ( [. ^1 N0 g( @3 W  y6 t+ Z
  102.         {
    7 o. M; y6 X- ]8 t6 a
  103.                 status=STM32FLASH_GetStatus();                        //获取状态" e( C9 `' O; J8 j
  104.                 if(status!=STM32FLASH_BUSY)break;                //非忙,无需等待了,直接退出.
    & u9 k) k9 Z9 @
  105.                 Delay_US(1);2 Q( s* {, I( g* o
  106.                 time--;" c: A3 \1 n! o7 g
  107.                
    ( m$ v" l( T/ _+ z
  108. #if(SYS_WDG_EN_) //使能了看门狗
    : u/ K4 A% {1 k1 }6 Q& [) E
  109.                 IWDG_Feed();
    - a+ [( Q5 ~9 ~7 O  O! C/ _$ N; W
  110. #endif //SYS_WDG_EN_        
    , A0 j( P+ J2 T. |
  111.                
    , `: P  D( V6 z, o+ S
  112.          }while(time);2 I# W7 m/ c8 H
  113. $ J$ Z& w5 q9 K6 d& {  M
  114.          return status;
    $ I6 ?6 G+ s' D. j
  115. }
    6 m1 r3 H4 s: O" h3 c$ ]( a

  116. & p  E/ u4 s6 A; p
  117. 2 X; \% P: p. J9 v# L: \3 B
  118. 5 S) g# {. ^! `  V* }. ]7 ]7 E
  119. /*************************************************************************************************************************
    6 v( L9 H$ o/ g" A, p4 [! U" O4 M
  120. * 函数                        :        STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)2 H( Y0 z( _! {3 r) `
  121. * 功能                        :        扇区擦除
    # d5 \' r! X$ {
  122. * 参数                        :        sectoraddr:扇区地址,0-11
    5 H9 |* C4 x; l+ j# z+ H$ \. e
  123. * 返回                        :        STM32FLASH_STATUS
    $ q. ?  h2 }( m! n* S  \
  124. * 依赖                        :        底层. Z4 ~2 ^/ Q; f7 R+ `5 f- Q
  125. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    0 f' Y& ^' _0 S" ^: S
  126. * 时间                        :        2018-01-03  ^. |6 T; E6 \2 K
  127. * 最后修改时间         :         2018-01-03( j2 q- m% k' J2 Q  G2 c/ K, y6 O# S
  128. * 说明                        :         扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区" M8 ~0 o! _  D" m3 A
  129.                                         128KB扇区擦除足最大2秒
    + A' |  J2 s+ _( G
  130.                                         2018-01-16:修复扇区擦除时没有解锁问题
    , h5 U/ I( x+ j+ V% a; z
  131. *************************************************************************************************************************/
    ! G1 W! T( k0 B
  132. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)
    , s! u6 d$ k' U$ H5 r8 g
  133. {/ ^# o4 N% ^/ l9 G3 {' ^/ {
  134.         STM32FLASH_STATUS status;
    - ^6 ?  D" {8 G
  135.         - P4 m1 `9 Q/ Q. j% z- _# B
  136.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    + M8 \5 g: w, }0 A! O5 T/ j
  137.         {) M* s6 F: }; A
  138.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    % B9 ^5 L# D4 Y/ Z) O) e; u) P) c
  139.                 FLASH->SR |= FLASH->SR;
    4 L1 [3 w7 P, A+ I- S5 n
  140.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);9 R" i9 ?# E: W, F& B* |
  141.         }
    & G3 |3 X5 p1 N; ~( }
  142.         
    7 ?4 I$ d% f$ k# N
  143.         status=STM32FLASH_WaitDone(2100000);        //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过
    , b, `8 t" W6 T2 n4 L
  144.         8 V0 l9 _0 T  G- U3 k4 R3 S! y8 C
  145.         STM32FLASH_Unlock();                                        //解锁 ; B$ \6 b) m- @; P
  146.         if(status==STM32FLASH_OK)                                //没有错误1 r/ Q/ Q( p$ }. c( i
  147.         {
    $ m3 K/ ?3 Q7 `
  148.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    " J7 }* {$ G2 A- t
  149.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!* [& X& V* J' _$ h/ T% j
  150.                 FLASH->CR&=~(0XF<<3);                                //清除原来的设置+ U$ }- G+ @! _/ Y8 J- n
  151.                 FLASH->CR|=(sectoraddr&0x7)<<3;                //设置要擦除的扇区 , ^* K# h* d) n7 N1 ^9 `6 q# ]
  152.                 FLASH->CR|=1<<1;                                        //扇区擦除 " \. t: ^! K4 w+ B5 g, A
  153.                 FLASH->CR|=1<<16;                                        //开始擦除, F3 |+ [0 z1 h1 a
  154.                 status=STM32FLASH_WaitDone(2300000);//等待操作结束,最大2s  - U0 ]7 W- g& c
  155.                 if(status!=STM32FLASH_BUSY)                        //非忙
    $ _- {; k9 R9 f. K8 b! _9 N% t
  156.                 {! p" \( _  d6 ~0 Z, H& O( N, S  d$ P* V
  157.                         FLASH->CR&=~(1<<1);                                //清除扇区擦除标志.
    . z5 \- S  B& c5 v. Z
  158.                 }3 |4 _9 r) f' u9 b
  159.         }
    % P, A5 }- a5 o. j+ _; k' @' f0 Q7 Q, q. u
  160.         //DEBUG("扇区擦除状态:%d\r\n", status);! U7 J2 j( C/ p1 F5 d5 f
  161.         //DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n", FLASH->SR, FLASH->CR);
    ! P0 `  S" X( C/ g* ]; C! T
  162.         
    / D6 b; P, l% Q# h% {2 r
  163.         STM32FLASH_Lock();                                                //上锁3 u3 U2 J' }+ w9 j
  164.         if(status != STM32FLASH_OK)
    4 H: a7 \8 I% ?! J
  165.         {- n, |6 N) g! [* A" S
  166.                 DEBUG("擦除扇区%d失败(错误:%d) FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",sectoraddr, status, FLASH->SR, FLASH->CR);
    1 N  W! e5 y: ]; V
  167.         }7 a. W% P& U2 e
  168. 8 v( ~! f: T5 A- E1 W2 M
  169.         return status;                                                        //返回状态$ ~) h' `. P  \# O0 R  ]
  170. }3 e5 }4 w9 }8 D0 G

  171. ! Z( B7 i9 x$ S' x. o4 {7 o) C

  172. , ^! j! I; m! r$ {9 s

  173. 1 m/ g# o' Y$ ~0 P

  174. 2 }' Q# T$ E( A+ Z0 y
  175. /*************************************************************************************************************************% u8 i' P( ?1 q$ H7 K+ I
  176. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)
    + l- o9 h- T$ N' j; ]# D/ }6 b
  177. * 功能                        :        在FLASH指定地址写入一个字的数据(32bit写入)2 X" C2 j) x  Z* ^3 h
  178. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据2 }9 i! ~$ y/ k0 |
  179. * 返回                        :        STM32FLASH_STATUS
    3 M' T! L" n! W! Z
  180. * 依赖                        :        底层
    3 i4 u6 f1 L" s2 F- K! e
  181. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    0 f2 \' S  U. R9 {
  182. * 时间                        :        2018-01-03  K$ _6 O  u$ _2 g, q, E. Z
  183. * 最后修改时间         :         2018-01-038 k& L% c% y9 Z+ [3 a
  184. * 说明                        :         警告,地址必须为4的倍数8 _4 q/ J& j! R
  185.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    % [3 _+ ~- n' G+ ]- @
  186.                                         不会判断是否能写入
    , n( m# F( Y, |
  187. *************************************************************************************************************************/2 @. m$ \3 f, a5 [) i
  188. STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)
    # ?% v; {* Z" B) G
  189. {* _% b/ ^. e% |
  190.         STM32FLASH_STATUS status;- `. n% Q9 U' Y  W) J
  191.         ) U$ z1 z% w/ ~" ]
  192.         status=STM32FLASH_WaitDone(200);                 //判断状态
    5 z/ O( p9 l7 Z1 j  H* B/ @2 @/ i
  193.         if(status==STM32FLASH_OK)                                //没有错误8 }. G& Y6 A( V( k
  194.         {1 N  @5 k& k9 X2 c# q- d8 O
  195.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置5 Q. Z& s$ Z: Q( G; @3 E- o8 r" O
  196.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!- c9 P+ @. o9 O3 v
  197.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误
    : O  G* W% n) p0 M* H, j; b8 A) R
  198.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        ! H7 T7 g5 c3 b+ }! K
  199.                 *(vu32*)faddr=data;                                        //写入数据' E3 P8 A: k; i  k! I- }
  200.                 status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.
    1 d: S2 g1 Y6 H' C
  201.                 if(status!=STM32FLASH_BUSY)                        //非忙
    9 r" i! [7 l1 ]6 S# s3 y& ]/ M
  202.                 {        * q: K; L+ R! m! A" a( l
  203.                         FLASH->CR&=~(1<<0);                                //清除PG位
    ( N; D, I) O) H$ w* i3 @8 @
  204.                 }
    ! y) `  S/ a, k$ v% i
  205.         }   U+ C& q1 E3 N* T

  206. 9 m- a" s3 j6 b6 [4 b% G
  207.         if(status != STM32FLASH_OK)
    % Y' [: [" S) Z/ v. `
  208.         {% R3 K: c/ p/ b7 _% v# q) H
  209.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
    ) s. h" E4 ~7 t/ O
  210.         }9 T4 Q6 y: p) I+ B8 Q, r
  211.         ' ~) u/ F& w6 o1 C7 J3 L) G! Q5 a
  212.         return status;
    - g, e' i9 F9 F
  213. } ! D1 z5 c7 }# ^" x+ i. n! ?' ~2 @- J
  214. 2 C0 K/ j: ~% |8 A: {* g
  215. 9 m) U- z( ~3 V  n  D! C: y2 v
  216. /*************************************************************************************************************************7 e, D+ T/ I+ n1 I
  217. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)7 g' Q4 q, K0 |' o7 @9 V, L
  218. * 功能                        :        在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)
    4 _5 k, [; s- R
  219. * 参数                        :        faddr:指定地址(此地址必须为4的倍数);data:要写入的数据% Y% o6 ?0 |7 N" `1 Z" W3 e9 o
  220. * 返回                        :        STM32FLASH_STATUS
    9 @: z1 a6 R4 l" D9 b
  221. * 依赖                        :        底层
    : p3 j& N, u  [7 x! n
  222. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>1 u/ y# x) D+ u6 W
  223. * 时间                        :        2020-02-08$ [. G+ z( d$ {/ f" v* \# T6 X1 I# b) c
  224. * 最后修改时间         :         2020-02-08
    4 l5 {  J7 j0 x7 i5 Y3 F+ w* I: U
  225. * 说明                        :         警告,地址必须为4的倍数
    " Z9 p7 |! p  y; {5 {
  226.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    0 W& [) q6 `. ]$ O
  227.                                         不会判断是否能写入
    $ t9 a6 q9 _/ T
  228. *************************************************************************************************************************/- ~4 S( I$ q5 o) y
  229. STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount); X& @5 a; i3 X) _1 L' @
  230. {
    4 G+ V) @( o' H1 O7 m
  231.         STM32FLASH_STATUS status;) q. w6 T' O8 b/ X  C. x

  232. " U0 b" _4 [0 K( i( t1 Y
  233.         status=STM32FLASH_WaitDone(200);                 //判断状态
    ! u9 ^& k- E9 Z/ f
  234.         if(status==STM32FLASH_OK)                                //没有错误; C8 h# V+ N; w1 r  g2 P* l) S
  235.         {
    1 s& s2 G4 I) `# \8 o
  236.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置8 q, w% [3 h4 \( U% n( ~
  237.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    ( K- A3 i+ S6 }
  238.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误
    / m( [4 W% S( O( ~
  239.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    & Z8 H* |6 }  ^) f  \$ W% Z1 g
  240.                 while(dWordCount --)
    % F; q5 k6 C8 K
  241.                 {
    ) n; G1 M: h" G& l0 s2 T
  242.                         *(vu32*)faddr=*data++;                                //写入数据6 k* r* X; R5 }& O  D: _
  243.                         faddr +=4;                                                        //地址自增+4
    6 Y* H+ n. O! d  U8 i( x2 g
  244.                         status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.4 E7 R8 b" Q( I
  245.                         if(status!=STM32FLASH_OK)                        //有错误; d! x! ~3 j' G& j
  246.                         {
    - d* s% G$ x6 g: S/ b: c
  247.                                 break;
    ) N/ Y4 b- q6 N# Y; {+ t- H
  248.                         }
    ! B: `2 s) x' T7 A# f9 W
  249.                 }" z  R# s  K' s3 g: H7 f3 \
  250. . D" }. h6 {+ _) g+ w
  251.                 if(status!=STM32FLASH_BUSY)                        //非忙9 [+ Z3 T; C( H( P% Y/ h1 W% l* B
  252.                 {        ' J: p' z$ ^* T5 Y, q
  253.                         FLASH->CR&=~(1<<0);                                //清除PG位0 f2 j9 S" f. h
  254.                 }
    / Y4 w2 s' C+ B3 k7 i
  255.         } * K( [( }% Z8 v# l
  256. + I) w2 t4 u# q  @. D( d
  257.         if(status != STM32FLASH_OK)7 f  L6 F" r! Z2 o- z( E4 o
  258.         {
    & P# a* C  p% ]
  259.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);, b+ ^0 K: q; i0 O
  260.         }% L: y/ P, U$ M4 F
  261.         
    $ Q9 `, ~0 H3 g( r$ v' }2 {) @& K
  262.         return status;# b  W* J) ?. f& d: ^5 K/ }
  263. }
    - h: [, m& @% V! }% a) H0 j
  264. . H1 s) m$ @; o9 @+ W5 T$ w
  265. ( q) K) {6 [5 n& P' u
  266. /************************************************************************************************************************** }/ a; ~0 t( l6 h: _2 O% p
  267. * 函数                        :        u32 STM32FLASH_ReadWord(u32 faddr)
    6 U9 ?# `0 i8 i+ M, o
  268. * 功能                        :        读取指定地址的一个字(32位数据)
    4 z2 |& h( Y. @# H8 \5 e3 y
  269. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);0 k$ ^: |7 \4 v. e$ X/ N! O' P
  270. * 返回                        :        数据/ \" G' O* o$ @
  271. * 依赖                        :        底层
    " V8 N1 E# h; l3 J/ O7 e
  272. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    " G8 A5 T0 \! P! L
  273. * 时间                        :        2018-01-031 _' t+ M& i& K0 w  l( R
  274. * 最后修改时间         :         2018-01-03% x5 L1 p% N+ S6 i# h6 S
  275. * 说明                        :         警告:地址必须是4的整数倍+ K7 C9 p6 J# R3 l6 T3 @% u. n3 y6 l
  276. *************************************************************************************************************************/$ }3 j! E- m. B5 d( |" C3 m! c* f, q+ z
  277. __inline u32 STM32FLASH_ReadWord(u32 faddr)  `9 L- M" V4 B$ r( G
  278. {2 z# N3 ^! j+ V8 }! a; \( m
  279.         return *(vu32*)faddr;
    ' k6 d& r, z" k" B
  280. }' B2 p8 A9 z: t0 w2 ]
  281. $ l4 U& }" M5 g

  282. # K9 u/ p! b2 Z3 V. q
  283. /*************************************************************************************************************************# @+ W& L* b+ D& s  z
  284. * 函数                        :        u8 STM32FLASH_GetFlashSector(u32 faddr)
    ; B) Q! h5 t" S, s
  285. * 功能                        :        获取某个地址所在的扇区. X6 x8 @0 B2 C5 u8 c# ]; a
  286. * 参数                        :        faddr:指定地址2 w+ \6 t% o3 x# v! e" S8 o" u. `3 U
  287. * 返回                        :        删除编号,0-6,如果超出了也会限制到6% P1 v. y3 O: ?) _0 z
  288. * 依赖                        :        底层
    0 E, N: h% K- j# ~6 _4 o' s
  289. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    2 J1 c1 D+ A: B! D) Y, v
  290. * 时间                        :        2018-01-03# _. ], U( k' ~# f, \! R
  291. * 最后修改时间         :         2018-01-03
    " q( U$ z- S4 ]
  292. * 说明                        :         地址请不要超出范围; g) e5 |: j& q
  293. *************************************************************************************************************************/
    0 M$ @$ r3 K4 ~+ e- d5 d
  294. u8 STM32FLASH_GetFlashSector(u32 faddr)+ B, P. ?; m- X3 _/ j4 Z9 {) j
  295. {
    , i" ?1 g1 l! F+ ~4 a7 R+ I& i2 H
  296.         if(faddr<ADDR_FLASH_SECTOR_1)                return 0;
    9 g2 v$ ]$ E8 U
  297.         else if(faddr<ADDR_FLASH_SECTOR_2)        return 1;
    8 o( \$ t* U3 l' G; y3 D# B$ E
  298.         else if(faddr<ADDR_FLASH_SECTOR_3)        return 2;( e) r- X' b) M  ^3 E) q0 c9 r  `6 D
  299.         else if(faddr<ADDR_FLASH_SECTOR_4)        return 3;
    0 `% ~* H6 G' m
  300.         else if(faddr<ADDR_FLASH_SECTOR_5)        return 4;6 H  O, J; G5 s6 }( [/ x7 e" B
  301.         else if(faddr<ADDR_FLASH_SECTOR_6)        return 5;* u8 W" q1 ]8 i$ v+ W6 V
  302.         else if(faddr<ADDR_FLASH_SECTOR_7)        return 6;& _; \0 e% Z  C
  303.         else return 7;        6 _! j/ J+ T" i+ [: ^4 e
  304. }, U: z2 K9 U/ D$ j) k! d2 ]

  305. 9 m4 \! g5 k+ w8 J# c7 c
  306. ! ~* F# X* G& n6 W" q
  307. /*************************************************************************************************************************
    . h3 k( }9 q1 F5 ]1 d! s" B
  308. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  
    9 ~/ L3 P- x* \
  309. * 功能                        :        不检查的写入
    % I0 k$ j  b) m/ ?1 m
  310. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数
    , Z. D5 v$ o1 Q4 w% s) `& E% r( V
  311. * 返回                        :        状态' C8 e" [& Z$ v2 O6 l3 T4 {
  312. * 依赖                        :        底层$ V. b1 N' C, L. B- ^0 m
  313. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>0 f  Q+ z% X4 H4 ]' I0 F' i: @
  314. * 时间                        :        2013-10-20
    % u: y5 i0 K4 ^: E
  315. * 最后修改时间         :         2018-01-03
    ( d9 \3 V- v) R6 a  [5 m
  316. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)
    " M6 K! W/ A* I+ t# H) g
  317. *************************************************************************************************************************/  N4 v; P6 @0 B5 m! v7 s7 i# `; I$ z
  318. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   
    ; J4 b3 G  b. T' Z  s
  319. {                                          
    : x* n1 L4 {! F# J8 W
  320.         STM32FLASH_STATUS status;
      U4 }5 f( t3 \0 u/ o$ t& W; M
  321.         
    * _; {* q* l4 w' r2 R, c
  322.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误' u4 [9 l5 }* b- z, C
  323.         STM32FLASH_Unlock();                                                //解锁
    3 D5 n# m# C: v+ O3 H! W# p7 L
  324.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现6 E$ G" N- j3 A/ C; n' z
  325.         {
    1 Z% d& e7 T2 @* @6 T4 q( e* _
  326.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    + w" k- K, H( M9 Q
  327.                 FLASH->SR |= FLASH->SR;0 T: p$ g1 H" r/ ?; N/ D, P
  328.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);% U0 P- V, H0 `( y* O" c5 ~  ?4 H
  329.         }
    # r4 h0 ?& {4 N! U5 }
  330.         status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据
      @9 w+ R3 d4 H2 D- Z7 X
  331.         STM32FLASH_Lock();                                                        //上锁  _4 x2 q8 j% ?: ^  K& k
  332.         return status;
    ' o" v9 {+ r2 `6 ^6 i! J# S* ^
  333. }
    5 t1 w/ V# v) p3 q4 `
  334. 3 c& ^# g3 P. k. b2 y4 u1 g, R

  335. 8 v' s% O6 ~5 \! O
  336. /*************************************************************************************************************************: e" d1 {% j. ^: k) W' A
  337. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   
    # d0 a3 j1 n, [9 `% K
  338. * 功能                        :        不检查的写入一个字! D7 D' c" {8 s
  339. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);data:要写入的数据值* }* M7 H0 n+ X/ l, r
  340. * 返回                        :        状态
    , w" E$ E2 |6 o! f2 m  \
  341. * 依赖                        :        底层$ A4 g2 m/ @+ s- X
  342. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    / i% D$ f+ ]# ?2 ~& l) ]
  343. * 时间                        :        2020-02-08
    2 T) i0 H4 y. A. e
  344. * 最后修改时间         :         2020-02-08% Y. I/ M9 ]5 u$ N. M& m
  345. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入): C0 _# {; R) C. f: ?
  346. *************************************************************************************************************************/
    . A; p; [+ A! ^% ^; C; \
  347. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   
    # D5 K% y; A" Y: a/ @6 j1 r% G! K
  348. {                                             a# `; p; K, [
  349.         STM32FLASH_STATUS status;
    + L! v" z' `6 t0 C
  350.         
    ( a" h; z% P4 C; z
  351.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误
    & B: J# z4 {: Z! G/ i# D( a
  352.         STM32FLASH_Unlock();                                                                                                        //解锁 1 o' ]9 @! h' B5 R  u6 D
  353.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    1 Z' ^$ B! f$ v6 [$ e
  354.         {
    % m6 O7 _0 t6 K+ X
  355.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    * ?  O8 n+ x5 ~9 E% V2 f
  356.                 FLASH->SR |= FLASH->SR;. y7 U1 j* t( [2 f7 h
  357.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    , D1 `! Q) F+ X* W; s
  358.         }
    1 B1 g: `% i( K, U
  359.         status = STM32FLASH_WritedWord(WriteAddr, data);                                                //写入1个字的数据* x8 d4 G+ y3 C
  360.         STM32FLASH_Lock();                                                                                                                //上锁
      w' T% A0 h3 G! [
  361.         return status;- j2 N2 F0 r' {& W* _5 I  p  b4 a
  362. }
    7 s  H; i; v: }

  363. 5 F' x8 ~6 h9 e9 p1 ?# j3 h4 }
  364. $ {$ ]' T* \$ I8 k
  365. /*************************************************************************************************************************; ]8 [. g9 D9 }5 c/ A, C
  366. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        
    : `% Z& e# E2 Z" P1 Z6 c
  367. * 功能                        :        从指定地址开始写入指定长度的数据(数据长度字为单位)0 V# K( t0 D8 k, _: A/ S
  368. * 参数                        :        WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
    - i% R. J7 d' S9 p) v' C* e/ u
  369. * 返回                        :        0:完成;1:忙;2:错误;3:写保护  @4 s0 a! o$ W% P: Z8 `
  370. * 依赖                        :        底层7 X2 i$ R2 c& U
  371. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>  h5 Y1 @1 n* W1 u9 y
  372. * 时间                        :        2013-10-20
    : s! Y% U3 N: X0 s6 }! D
  373. * 最后修改时间         :         2016-01-07! M+ |5 I( g# r, S4 P  I
  374. * 说明                        :         警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据
    0 w% d; c3 X! U, M+ U1 f. j
  375.                                         如果需要保存其他的数据,请在应用层进行实现(比如:先读取扇区,修改扇区,擦除扇区,写入扇区,需要大内存支持)
    ( c" b$ m& v* k$ E+ c* l
  376. *************************************************************************************************************************/ 8 v9 @7 ]) _) K
  377. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        0 ~# _4 x" O- ^/ s& `
  378. {
    . |+ Z- \1 C+ r5 H3 @
  379.         STM32FLASH_STATUS status;
    ' g7 Q0 C9 x/ _" M, u
  380.         u32 addrx=0;
    0 \6 v# K  q1 g9 \4 H
  381.         u32 endaddr=0;        
    ! I% |, K, {( g. q; j/ ^- ?
  382.          
    ( y" l* {( K0 F4 l. ~9 w0 T
  383.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR;        //非法地址  f0 _* y( o# n# _
  384.         
    - s6 g. _' P' c  [# H
  385.          FLASH->ACR&=~(1<<10);                                                                //FLASH擦除期间,必须禁止数据缓存!!!搞了我两晚上才发现这个问题!: x0 U2 e; f* P
  386.         addrx=WriteAddr;                                                                        //写入的起始地址! Q7 k) k. u4 f
  387.         endaddr=WriteAddr+NumToWrite*4;                                                //写入的结束地址8 s! a- d! ~. A. u& Q' Q* o( I* M6 b
  388.         ( d9 G& o8 E# I$ o, f
  389.         if(addrx<0X1FFF0000)                                                                //只有主存储区,才需要执行擦除操作!!
    $ F( F( e9 x5 o9 P# J
  390.         {
    ( u: B0 }9 q9 t7 p) `
  391.                 while(addrx<endaddr)                                                        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
    7 M/ G+ f7 _/ S. ^, k$ E
  392.                 {6 C3 Q: l, m* B+ I, a- J
  393.                         if(STM32FLASH_ReadWord(addrx)!=0XFFFFFFFF)        //有非0XFFFFFFFF的地方,要擦除这个扇区
    * T# {" X. G" }+ s8 t
  394.                         {   
    ) B1 c7 U1 h2 h
  395.                                 status=STM32FLASH_EraseSector(STM32FLASH_GetFlashSector(addrx));+ k5 |/ K6 \/ y' W3 P
  396.                                 if(status != STM32FLASH_OK)break;                //发生错误了
    0 s! V" O& _- F' N/ @6 Z
  397.                         }else addrx+=4;
    + O4 u. z- b5 q; n- j1 s8 H
  398.                 } 4 v, [4 i) i0 p4 |9 q9 u
  399.         }. |' G' }5 @7 H
  400.         if(status==STM32FLASH_OK)* P7 ]$ S9 H% i/ g( g3 K
  401.         {
    $ j" {, b1 q" G
  402.                 STM32FLASH_Unlock();                                                        //解锁 % d; x- L+ t$ R6 r
  403.                 if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    - K- `/ M; p  w" P/ e7 B# r
  404.                 {
    - d$ `2 m6 Q/ @6 q$ T* X
  405.                         DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);0 R% }5 y- j6 W: |" [. |/ m3 z: Z
  406.                         FLASH->SR |= FLASH->SR;6 q4 ]; @* B4 A# K( P$ r5 O2 y0 B# e
  407.                         DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    ; c% H! L* Q, A" _$ g: ?0 J
  408.                 }
    2 ~" l! T0 v& _0 F& ~% P( w
  409.                 status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据7 t" K% e8 Y' ]8 k
  410.                 STM32FLASH_Lock();                                                                //上锁
    , b+ v/ U$ \% L/ J
  411.         }
    " A  D; _; K4 z7 V) q2 z
  412.         FLASH->ACR|=1<<10;                                                                        //FLASH擦除结束,开启数据fetch' r) g5 f3 h% f  G3 f
  413.         
    : Z8 ^0 E  c5 P0 D: I  b& `, h
  414.         
    7 ]2 i" N; i; P1 w0 A5 O
  415.         return status;, ]" _) F: E* z; E0 ]5 p) p0 I5 E& `
  416. }
    , }) K1 c: g5 ^3 V
  417. # _6 M4 s# S: m; o
  418. ; ]) T0 m, i4 M5 V- D; K1 o+ z
  419. * ~% {4 X. O) s- M( F4 k2 |
  420. 6 W) T4 X  P, V8 s# ?

  421. ( y, g% c" l! A; y0 d
  422. /*************************************************************************************************************************
    . V: C  o  `* U1 B" J
  423. * 函数                        :        u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead) 5 [$ i! M, g# J# u
  424. * 功能                        :        从指定地址开始读出指定长度的数据$ v: x: f8 T0 _8 s( X
  425. * 参数                        :        ReadAddr:起始地址;pBuffer:数据指针;NumToWrite:字(32位)数
    2 V7 l+ f! V& k$ p( b2 I
  426. * 返回                        :        读取的数据长度(字为单位)
    - }, Q: H( g1 W
  427. * 依赖                        :        底层
    7 D; L9 `7 |# {
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    8 G5 q" J1 K2 y
  429. * 时间                        :        2013-10-20
    , X' i+ c# C. A8 p% b1 ^: d
  430. * 最后修改时间         :         2016-01-07
    % K( y, M# T- k$ j4 l* y# W
  431. * 说明                        :         地址必须为4对齐
    " G# r( N* m2 G* M
  432. *************************************************************************************************************************/
    ; y8 U% N' B" F
  433. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)           
    ! B' q1 e- h' B9 z
  434. {
    . o1 i5 B  j1 N* P- z# A5 ?
  435.         u16 i;
    . l* I  R2 v. F
  436.         u16 cnt = 0;
    ) N- B/ `- h) F4 T; }2 y" x
  437.         
    2 C7 \* F# J" x
  438.         if(ReadAddr<STM32_FLASH_BASE||ReadAddr%4)return 0;        //非法地址" C4 I: p* K0 c) v9 [7 R6 d
  439.         
    8 @% t% h; q1 z  E
  440.         for(i=0;i<NumToRead;i++); O) h% {# q6 y  O
  441.         {
    ' n/ q6 x; u1 S; C" j  D
  442.                 pBuffer=STM32FLASH_ReadWord(ReadAddr);                //读取4个字节.: x2 v1 D4 ~& I( Y
  443.                 cnt++;
    ( W' g3 N2 r( w
  444.                 ReadAddr+=4;                                                                        //偏移4个字节.        5 |) d' `4 {# \1 ?" H
  445.         }" f) V4 B3 v- P* I' z9 C9 D
  446.         return cnt;- O" S+ ~# ^0 B8 y; n  b* Q4 e
  447. }+ G; @5 L1 _  C
  448. 7 t* k# B- w4 L% y& k" r  S$ z

  449. 7 p9 l! d0 f  h3 t; T
  450. /************************************************************************************************************** W( o1 F1 }. ~5 j; D% U5 [: J
  451. * 文件名:                        stm32f7_flash.H
    4 i$ f- q0 g$ b5 ~4 {0 {3 |
  452. * 功能:                        STM32F7 内部FLASH编程驱动函数2 T* C- E& R6 g$ ~( J  B) \# L( K- P$ X
  453. * 作者:                        <a href="mailto:cp1300@139.com" style="">cp1300@139.com</a>1 P3 R* _5 t$ G
  454. * 创建时间:                2013-10-20
    % t! ?: k2 z& z+ F8 G
  455. * 最后修改时间:        2020-02-07
    4 \: M( E  e4 i2 w) C% i
  456. * 详细:                        用于STM32F7内部flash读写驱动
    3 t5 O2 ?6 l5 \9 J8 \
  457. *************************************************************************************************************/
    1 _+ {# w& D9 s& v
  458. #ifndef __STM32F7_FLASH_H__
    & S/ x" Y0 l6 X6 b2 ?: C6 O1 ^
  459. #define __STM32F7_FLASH_H__2 ]- }) {; f" t2 F7 T- e4 Q
  460. #include "system.h"  
    0 c2 u  X' Y1 _

  461. 9 K6 \, h2 P/ B' m" k; F9 u5 N
  462. //FLASH起始地址, r0 G6 U7 l2 J  _, F$ ]* e  ]. P
  463. #define STM32_FLASH_BASE                 0x08000000                         //STM32 FLASH的起始地址0 g5 ^) e' ]$ X3 n, Z4 Q! T) {
  464. ) ?9 K3 G2 S5 E8 {4 y" ~/ q
  465. //FLASH 扇区的起始地址2 r7 }% \) \* H8 |6 w: V0 U
  466. #define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)         //扇区0起始地址, 32 Kbytes  
    0 ]( S( I1 C2 r8 ~$ w
  467. #define ADDR_FLASH_SECTOR_1     ((u32)0x08008000)         //扇区1起始地址, 32 Kbytes  " _0 Q4 E8 k! p1 l
  468. #define ADDR_FLASH_SECTOR_2     ((u32)0x08010000)         //扇区2起始地址, 32 Kbytes  $ P/ _6 a. M1 I: H: O2 d- Z- u3 |
  469. #define ADDR_FLASH_SECTOR_3     ((u32)0x08018000)         //扇区3起始地址, 32 Kbytes  0 G0 F  u, W9 u. b' y. F; Z0 Q* F
  470. #define ADDR_FLASH_SECTOR_4     ((u32)0x08020000)         //扇区4起始地址, 128 Kbytes  
    ! {! b! R+ V( ]( G
  471. #define ADDR_FLASH_SECTOR_5     ((u32)0x08040000)         //扇区5起始地址, 256 Kbytes  
    ) R5 ~  D# U+ R- G/ ^
  472. #define ADDR_FLASH_SECTOR_6     ((u32)0x08080000)         //扇区6起始地址, 256 Kbytes  
    + w" X. X7 V- ^3 q
  473. #define ADDR_FLASH_SECTOR_7     ((u32)0x080C0000)         //扇区7起始地址, 256 Kbytes  
    ! X. v6 v% o, I* ^, G* @
  474. ; w9 J9 e' [; @  ]. J% \- p

  475. + Y' r" h$ g+ q1 N1 ~2 h9 x
  476. //FLASH解锁键值
    3 ]; A1 [& @. ?2 g; h( Z  I. c
  477. #define RDP_KEY                  0x00A5
    3 W( k' b& D) u9 R$ _% W
  478. #define FLASH_KEY1               0X45670123% ^/ j5 d' t; M: G9 X# ?2 ]& D1 s
  479. #define FLASH_KEY2               0XCDEF89AB
    ' ]9 k. c2 w2 G& A9 ]9 J
  480. #define FLASH_OPT_KEY1           0x08192A3B
      w9 C/ [' `8 o" h" O
  481. #define FLASH_OPT_KEY2                         0x4C5D6E7F
    7 o6 V: y) _7 u
  482. 6 }" q7 U/ a5 B. b1 K! J9 K
  483. //STM32F7 Flash操作状态
    : c9 n$ r" G$ I5 Z
  484. typedef enum
    6 ^4 p/ o: U0 j" c
  485. {
    % Q. k% n4 c3 X. u8 T8 k: d
  486.         STM32FLASH_OK                        =        0,        //操作完成
    ( @( N2 [- P/ X3 E" k% [
  487.         STM32FLASH_BUSY                        =        1,        //忙2 l) a) Q4 @" Q* e5 v
  488.         STM32FLASH_WPRERR                =        2,        //写保护错误9 M, n1 |8 F$ s6 [
  489.         STM32FLASH_PGAERR                =        3,        //编程对齐错误,必须128位对齐; q, w* R+ t# M' b! Z) _
  490.         STM32FLASH_PGPERR                =        4,        //并行位数错误
    & [: j% ^# n5 H' K  [7 T9 e
  491.         STM32FLASH_PGSERR                =        5,        //擦除顺序错误8 f% n8 X6 r0 \, s4 \
  492.         STM32FLASH_OPERR                 =        6,        //操作错误
    # H# {) S! y+ q0 T- @# p
  493. }STM32FLASH_STATUS;/ Q/ E: R6 G) P) y6 j% _
  494. 7 |& T, Y6 k2 _; i
  495. //常用接口
    ' L( r& U3 E0 G7 N% K
  496. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr);                                                                  //擦除扇区1 x& b$ ~5 P1 Y
  497. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite) ; //不检查的写入多个字的数据
    8 t0 w0 N3 ^+ o; ]0 ]
  498. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data) ;                                //不检查的写入一个字的数据
    $ k+ G4 J7 O8 t) g! d$ {) Q6 ?4 ~
  499. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite);                        //从指定地址开始写入指定长度的数据(数据长度字为单位)
    $ q2 A! Y  X2 [. M( G5 c
  500. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead);                                                        //从指定地址开始读出指定长度的数据3 i# i( g5 Z3 S2 k$ ]
  501. ; T, P, r4 ^6 C# }% ~& r
  502. //不常用接口0 c/ \3 r  I. ?6 j6 @' D
  503. void STM32FLASH_Unlock(void);                                                                                                                        //FLASH解锁
    # J) Z' V; u% f* b4 X) y
  504. void STM32FLASH_Lock(void);                                                                                                                                  //FLASH上锁
    1 p# ?4 }+ I2 h& X8 B2 f
  505. STM32FLASH_STATUS STM32FLASH_GetStatus(void);                                                                                          //获得状态. |; M% L, p2 Q5 `& H# j4 d

  506. 5 l/ x1 b% ]5 ]1 A& [" i

  507. ) u# a/ l0 v0 K; W1 F
  508. #endif        //__STM32F7_FLASH_H__$ c7 h# Y; _4 s0 Q8 l

  509. ) F1 w( j# t4 H' [1 ~) P3 M
复制代码
' y, ]  f: D; {  S$ O) @; ^
赞 收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版