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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
总体来说与STM32F4操作是一样的,就是扇区大小变化了,测试过程中发现当PG=1之后立即写入数据到flash会造成编程顺序错误,通过增加一个nop的延时即可解决此问题,还可以通过将多个数据连续烧写的方式避免此问题,就是当PG=1之后,把所有数据都烧写完成后再将PG=0,不要频繁的开关。
# b% s( q5 [( ~0 x
2 C: q, A' I0 J6 y6 N5 S* T
  1. /*************************************************************************************************************- b; ^* |9 R: c3 X; b4 [
  2. * 文件名:                        stm32f7_flash.c
      w" I4 B: f, x
  3. * 功能:                        STM32F7 内部FLASH编程驱动函数3 Z7 O- t/ j" a  U" {# ?
  4. * 作者:                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    5 J6 z  G" B  j$ o
  5. * 创建时间:                2013-10-20
    . u) j( V  X$ ]
  6. * 最后修改时间:        2020-02-079 o9 g$ c7 H$ ]. s
  7. * 详细:                        用于STM32F7内部flash读写驱动/ I2 x2 p6 H- e( Z
  8.                                         默认为3.3V供电,并且宽度为32bit;6 x5 U! Y: k. R% ]& C& b& Z1 E
  9.                                         扇区擦除最长时间:32KB扇区500ms;128KB扇区1.1秒;256KB扇区:2秒, V0 A' {2 C2 i8 N' d
  10.                                         修复STM32F7开始写入数据时,PG=1后没有延时导致异常,增加批量写入多个字的数据函数STM32FLASH_WriteMultipledWord()支持。
    , Y; R4 T5 B6 }9 q
  11. *************************************************************************************************************/
    , P. ?5 k# A" Y+ l
  12. #include "stm32f7_flash.h"
    # M2 W, G/ x& q& `& Z' P
  13. #include "system.h"
    ; {8 G0 A- y2 f; o6 I" Y" Y7 j
  14. #if(SYS_WDG_EN_) //使能了看门狗: D) U) h3 G* w1 |6 C
  15. #include "wdg.h") v! J5 [. D* |6 ]2 D
  16. #endif //SYS_WDG_EN_8 W- @% A& N, B* L$ h1 v
  17. ' E5 F8 l# T- V

  18. - s8 O; W' C0 r/ N( M, s7 q

  19. 0 O2 L4 O$ f; W& v4 \

  20. & ~: ?1 z: z$ p/ ]2 |; ]4 f  V! k
  21. /*************************************************************************************************************************
    ' }  D* V/ g9 g4 f$ `5 a' U" X3 I5 b- K
  22. * 函数                        :        void STM32FLASH_Unlock(void)- K8 v7 B& J5 d- _. c
  23. * 功能                        :        解锁STM32的FLASH
    ) g$ v4 r" g8 c" C, T5 }( B- A, `
  24. * 参数                        :        无# F6 d/ z/ `! H7 J
  25. * 返回                        :        无! f0 ~0 J8 e# u, C( \$ r# h
  26. * 依赖                        :        底层
    ' C) P, x* q2 ~7 x& n' ^
  27. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    : }7 u. n  C' C: g
  28. * 时间                        :        2013-10-20
    + A) {1 `8 h. m+ Y
  29. * 最后修改时间         :         2013-10-20
    " g3 P7 m0 k, S/ Y. d
  30. * 说明                        :         
    5 ^( [: {* h+ H& S1 n
  31. *************************************************************************************************************************/9 K7 @9 ?$ N& J+ ?5 H
  32. void STM32FLASH_Unlock(void)
    8 h, y5 M5 I! \# @5 {( N* W* v
  33. {& Y0 }! }3 G8 q2 V' T; u( t
  34.         FLASH->KEYR=FLASH_KEY1;        //写入解锁序列.& f. i; g  Q! ^3 x) @
  35.         FLASH->KEYR=FLASH_KEY2;
      F6 {3 B0 f; ]
  36. }
    2 I9 n% s8 J# r3 _# r
  37. * w8 ]8 t+ Q. y- t) m6 O

  38. 6 r" Y; V1 i+ [0 F

  39. $ w2 y3 b, Q% y9 [1 P
  40. /*************************************************************************************************************************
    3 M- O5 `6 E" ~# e2 B2 H. I# W& j
  41. * 函数                        :        void STM32FLASH_Lock(void)$ e3 x1 _6 @& s
  42. * 功能                        :        上锁STM32的FLASH
    1 z4 y6 s: i! C5 y- c( c8 R
  43. * 参数                        :        无: `" T3 X+ u% ?6 z8 b9 O$ Y, `% a
  44. * 返回                        :        无
    6 j8 e3 J+ Z; h3 A% x$ j$ A
  45. * 依赖                        :        底层: a) P. x6 p3 U) q' U, S2 t" G4 I' a. s
  46. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    % z( a9 ^4 G& h, {0 ^2 {
  47. * 时间                        :        2013-10-20
    ; y0 [* I+ s. |- |# v9 Z! l! v
  48. * 最后修改时间         :         2018-01-13
    # F* R' P+ ?5 y& I; t' n/ w
  49. * 说明                        :         + p9 r3 \. H+ x9 q7 E
  50. *************************************************************************************************************************/7 b+ ^& a2 ~! z! t6 e1 ~$ _
  51. void STM32FLASH_Lock(void)' s! I/ t; ]* g4 g
  52. {
    / _5 w" a5 R) V+ q+ h( P) [2 a6 A
  53.         FLASH->CR|=(u32)1<<31;                        //上锁1 a3 D) K' X" N+ C6 w9 r
  54. }( k3 U/ R! [3 ^& V

  55. " z- H' z$ M5 _' Q' e" {
  56. & h- }( g# `- Z0 F- }- o) }0 K
  57. 7 p# b5 i6 z2 x( M' X

  58. ' ~# Y8 Y/ g9 v7 {% M
  59. /*************************************************************************************************************************
    $ \! E, o. g- d: R
  60. * 函数                        :        STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    5 K+ @6 x% E6 z# k9 W( c
  61. * 功能                        :        得到FLASH状态0 C. \; R. V7 x
  62. * 参数                        :        无
    + r. P6 a( X7 c; |: j
  63. * 返回                        :        STM32FLASH_STATUS: u4 a8 o* }8 P  n$ r4 u4 H2 C4 w
  64. * 依赖                        :        底层
    ! }# a$ R8 X4 H- c; I7 a: `5 Y
  65. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    3 h, ^" c- J8 h- m% ]$ _6 Z6 e
  66. * 时间                        :        2013-10-20
    % X. Y, J+ k) X4 _0 ~
  67. * 最后修改时间         :         2018-01-033 S) w6 e" m) A$ c! d
  68. * 说明                        :         
    1 y' b6 w. _5 U: d
  69. *************************************************************************************************************************/. J# ]# x3 }& q* K% w
  70. STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    9 Z" @/ j! c% c  T7 o7 A
  71. {        9 _4 h3 I2 A7 Z3 ]" m5 @4 F% Y2 d
  72.         u32 temp=FLASH->SR; ) s3 Y, B4 ?" g
  73.         ' j3 Y: Y7 l) B8 u% P, x0 r* B
  74.         if(temp&(1<<16))return STM32FLASH_BUSY;                        //忙
      a9 c$ \- V- [3 ^# u8 G
  75.         else if(temp&(1<<4))return STM32FLASH_WPRERR;        //写保护错误
    4 u* c' w( s7 C# g9 g& B" h5 z3 T
  76.         else if(temp&(1<<5))return STM32FLASH_PGAERR;        //编程对齐错误
    ( {2 S2 ~- l0 T- e& H
  77.         else if(temp&(1<<6))return STM32FLASH_PGPERR;        //并行位数错误# ~4 \- d" t! G: B* e- a% s; T
  78.         else if(temp&(1<<7))return STM32FLASH_PGSERR;        //擦除顺序错误
    / K! b/ H# q6 ?, i$ G5 t3 g0 p
  79.         else if(temp&(1<<1))return STM32FLASH_OPERR;        //操作错误- U# b+ Q# M  _9 g0 U
  80.         return STM32FLASH_OK;                                                        //操作完成4 d4 m7 f7 E: X" }& b- x$ P6 k0 A
  81. }
    8 B/ F" T/ H  S6 K, m! k8 @
  82. / d* P9 ^* s8 d- f

  83. 8 O1 C* O6 e9 s5 Y

  84. 4 s( e6 C4 T0 B% L0 ]0 T! n
  85. /*************************************************************************************************************************$ ]/ K+ H/ ]5 r9 T$ N7 H9 t
  86. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)
    ! T% x5 a+ l. }* ]: m+ @
  87. * 功能                        :        等待操作完成# T9 L9 p' D1 O/ D( X
  88. * 参数                        :        time:要延时的长短,单位us9 |6 R3 |7 d( b7 X' h9 x
  89. * 返回                        :        STM32FLASH_STATUS- l- K' f5 `" c  u8 q2 _
  90. * 依赖                        :        底层
    8 A. t9 D( B4 i9 D8 v
  91. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>; t) k) S6 @2 v/ v/ S$ G  A
  92. * 时间                        :        2013-10-20
    5 y; v" I1 u; O1 h; I
  93. * 最后修改时间         :         2018-01-03
    5 x4 B1 s; z4 ?2 g$ [
  94. * 说明                        :         2018-03-24:增加清除看门狗功能* W2 n" ^2 g* C2 Z6 q- a( v
  95. *************************************************************************************************************************/
    . d- f2 G! A2 O3 E2 \
  96. STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)
    " X7 J# b6 Q" U# [" f
  97. {$ m/ W  a* z  H9 Z
  98.         STM32FLASH_STATUS status;; A- h. g4 X) e/ w4 P
  99.         
    9 M: u$ r9 t% a, P) b
  100.         if(time < 1) time = 1;, x. r+ K% h' X
  101.         do. J3 t7 R7 ]) e7 d
  102.         {
    + ?0 V1 ]/ `; Z7 n. h
  103.                 status=STM32FLASH_GetStatus();                        //获取状态
    . N9 [) Q, b: \7 V" n9 B  s$ A. `
  104.                 if(status!=STM32FLASH_BUSY)break;                //非忙,无需等待了,直接退出.9 `3 p- i1 P  z1 p# n: C
  105.                 Delay_US(1);
    6 `0 ~9 F8 t# q6 z
  106.                 time--;; i7 e$ k! M2 b5 \
  107.                
    ) c; \0 m9 `) Q5 N
  108. #if(SYS_WDG_EN_) //使能了看门狗
    2 N1 B* F0 A0 m, Y! c
  109.                 IWDG_Feed();
    ( s4 x4 t* }1 g
  110. #endif //SYS_WDG_EN_        
    9 \9 y, X& }+ n, ^- O( S
  111.                
    ' d- w1 \. T; C1 b, G9 _
  112.          }while(time);
    $ ?' m$ f3 M3 r3 H! c

  113. 1 v4 N. {8 m' H- |/ Q2 ]
  114.          return status;
    7 P/ t4 w( M: B/ u7 I2 g
  115. }
    9 |* M6 X6 {# n# v! ]
  116. 4 L) ]; [" B8 I6 m% B3 x' G
  117. ) T$ G9 R3 E) S- k1 n) E& I

  118. % d& w$ D( o, U
  119. /*************************************************************************************************************************
    ; p# H, f# F' Z) Q$ O2 C2 P$ d
  120. * 函数                        :        STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)
    # m. a& \4 L7 i9 o6 ?- t7 Y3 h
  121. * 功能                        :        扇区擦除
    7 G3 o2 V$ I+ C  Y# _3 I
  122. * 参数                        :        sectoraddr:扇区地址,0-11
      u+ y# S/ }4 e( N. g
  123. * 返回                        :        STM32FLASH_STATUS3 L0 b  A+ u2 c
  124. * 依赖                        :        底层3 ]3 @$ z2 X3 {+ t9 N" V2 ]1 J" V+ i
  125. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    1 k* H% y3 C3 d: P! U8 ^1 E
  126. * 时间                        :        2018-01-03/ H9 n# h2 |4 h6 ?! W! F2 w( M! L
  127. * 最后修改时间         :         2018-01-03. F- d+ v9 N& V( l/ \
  128. * 说明                        :         扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区
    / V/ K" j" _2 S3 P6 R
  129.                                         128KB扇区擦除足最大2秒
    3 J. l7 ]* }4 X) y7 k
  130.                                         2018-01-16:修复扇区擦除时没有解锁问题3 z# o7 y3 f/ g4 Z
  131. *************************************************************************************************************************/
    0 R* a8 I4 Y- Z& I4 W" W
  132. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)- Y/ K1 I# Z4 x4 E' X
  133. {" g& n% d# ^9 v6 D; s: t
  134.         STM32FLASH_STATUS status;
    7 N+ S7 x  X$ {$ e# O
  135.         
    7 W3 \& R1 G) H3 A: ~. {2 J# a
  136.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现' }# B% R, _+ B* @& ?
  137.         {
    7 C9 m: s/ A; {! v- \- s4 t* A
  138.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    + Y$ r7 X# I6 P9 s
  139.                 FLASH->SR |= FLASH->SR;
    , p/ H. ]* O+ Q) W
  140.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);6 |3 L4 q$ G' H6 Y' g/ A3 I
  141.         }
    ! _* E& n; i( j# ]- U( \
  142.         
    , `) Q( ?, [$ o* H2 o! |1 D
  143.         status=STM32FLASH_WaitDone(2100000);        //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过) x' H( g. p$ ~% B1 s
  144.         
    - k; t! {% q3 ^/ r: T
  145.         STM32FLASH_Unlock();                                        //解锁
    ( a" Y* U! C- y  x
  146.         if(status==STM32FLASH_OK)                                //没有错误
    2 v- k5 C) m* b- [7 q: q: z
  147.         { . y1 J2 d, j8 b8 y' w+ `; i, N9 u
  148.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置/ O4 ?5 l8 l9 I) Q9 }
  149.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!0 k) l! Z8 b; S3 a1 @
  150.                 FLASH->CR&=~(0XF<<3);                                //清除原来的设置6 Q) H2 s: D! V
  151.                 FLASH->CR|=(sectoraddr&0x7)<<3;                //设置要擦除的扇区 7 k7 ^8 a: p8 v# {# |3 P# l; d9 y
  152.                 FLASH->CR|=1<<1;                                        //扇区擦除
    4 p  L) Q* @9 r
  153.                 FLASH->CR|=1<<16;                                        //开始擦除
    $ w: F+ F3 [0 }7 p6 p/ S# G0 t
  154.                 status=STM32FLASH_WaitDone(2300000);//等待操作结束,最大2s  
    & \0 q6 h. C" S6 u6 [  o
  155.                 if(status!=STM32FLASH_BUSY)                        //非忙  x( k* Q  _. U1 Z& Z7 C1 X
  156.                 {
    , c6 L/ J/ U$ W* n" p9 t5 q
  157.                         FLASH->CR&=~(1<<1);                                //清除扇区擦除标志.: ~1 ^. ^, v; Z! I
  158.                 }' J9 C$ C  F, ]; m
  159.         }$ ~4 [8 n& S& X
  160.         //DEBUG("扇区擦除状态:%d\r\n", status);4 w& ]) U+ D4 V2 I$ T7 {
  161.         //DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n", FLASH->SR, FLASH->CR);
    4 j* `% Q$ S5 o' I% r3 |( ^3 H
  162.         
    & X3 G5 X  a0 F6 D  s% |
  163.         STM32FLASH_Lock();                                                //上锁
    $ Q5 J7 n+ z+ `. H' D- b$ `  u
  164.         if(status != STM32FLASH_OK); O* s. d) K7 ^' N
  165.         {
    1 W5 O' ^" s0 {
  166.                 DEBUG("擦除扇区%d失败(错误:%d) FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",sectoraddr, status, FLASH->SR, FLASH->CR);
    3 R9 c9 H9 ]3 j; j( X" q1 z& C
  167.         }3 r+ I3 y% k' p5 F5 K
  168. * f' P! F2 o: r& b- v3 h
  169.         return status;                                                        //返回状态5 L# t  H/ j2 G* k* J' K6 _+ |5 J/ B
  170. }1 G& c$ a& ]: Z4 C* K; m
  171. 9 g: _: m6 t; h, J* ?3 ^
  172. , y* M2 m1 e& K5 q% ]
  173. ( ~) k$ q: Z+ I2 `0 G
  174. 0 s: s5 l* {6 E5 f0 p5 N
  175. /*************************************************************************************************************************5 \5 v" Z% U5 w0 e" d! j4 V$ L
  176. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)4 L; g/ N' D- Q! I% h3 g9 ~0 m
  177. * 功能                        :        在FLASH指定地址写入一个字的数据(32bit写入)0 Y- B* d; {0 v8 d* v7 n
  178. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据
    4 s, q5 P1 c% R  b) v* v, i. |
  179. * 返回                        :        STM32FLASH_STATUS
    5 Y4 U. m7 l1 ?0 P. Z8 f
  180. * 依赖                        :        底层
    . G6 X, }0 U0 }0 {9 I
  181. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    % f! ]' B) K- C4 H  Z( g5 Q# y
  182. * 时间                        :        2018-01-03  |4 a) K# G. p0 {" M$ D
  183. * 最后修改时间         :         2018-01-03
    $ @8 E! p8 W. D
  184. * 说明                        :         警告,地址必须为4的倍数- c" E) j' U/ G% [+ {+ I
  185.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁: }4 t* A7 Z" V' }; G. ^) }7 h7 q
  186.                                         不会判断是否能写入/ v3 d1 v2 }( L/ h) X
  187. *************************************************************************************************************************/
    . t. U1 s7 q" ~6 h2 @/ w& z* {# i
  188. STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)- K* R) N, M2 t6 o$ }' I$ c
  189. {
    ' p4 D' u! Z% E) K
  190.         STM32FLASH_STATUS status;
    - v4 J, r, ]% f( T" \6 Q
  191.         " n2 i( C( ]  C, w% s9 ^* L( B' H
  192.         status=STM32FLASH_WaitDone(200);                 //判断状态/ ]  e5 Q- V: U' E1 d6 A) R
  193.         if(status==STM32FLASH_OK)                                //没有错误+ K$ V( r' c5 h+ C/ k" J
  194.         {$ b  L+ G3 I+ j! w7 f# n1 A# T
  195.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    $ D9 J: k* C+ L0 @0 Z. T6 o) |; i
  196.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    9 s0 O  ~: Z+ ]8 B& _# s3 u8 F7 @
  197.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误2 R, m& Y4 B) u3 I* f. d' S
  198.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        , U0 A$ m! S0 @1 y0 b: r
  199.                 *(vu32*)faddr=data;                                        //写入数据: u. U7 I, z+ q) m4 r0 L
  200.                 status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.
    0 g2 L* ?$ `1 w' Y7 ?
  201.                 if(status!=STM32FLASH_BUSY)                        //非忙; ~* n* z3 x3 a* V, b& o' A
  202.                 {        / m. @! S% }( ~3 M( s
  203.                         FLASH->CR&=~(1<<0);                                //清除PG位) e: R0 M9 L" F, o- ?/ |! O
  204.                 }
    7 C" n8 Y) c1 z" c1 [5 b/ ^
  205.         } $ D. I1 r; l2 \  A% G1 y2 a0 U
  206. : C, {" }) Y8 ?' H/ P
  207.         if(status != STM32FLASH_OK)
    3 j% M2 G; a3 W& N9 G0 C5 C; q
  208.         {
    8 S1 U% Q9 ^7 Q! J
  209.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);. y9 s% G- h1 K3 E) d/ p! ]
  210.         }
    - C( P' Q. J+ P' n* S/ _" U
  211.           ]& n  w9 V& t9 r3 G! @
  212.         return status;
    + p- f  V* U, [7 v# n0 b3 Z
  213. }
    ; f1 i% B4 k8 j) w4 C, \
  214. , x8 d/ T7 h% v: G: w9 D& a/ w, W
  215.   r8 G: H& X" h, E
  216. /*************************************************************************************************************************
    2 Z" _8 B" j3 N6 m8 `  L( s2 b
  217. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)5 ^" G! ?0 o) ]# r2 S
  218. * 功能                        :        在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)) d9 ]; j3 L5 a+ ^8 }4 a% H/ C
  219. * 参数                        :        faddr:指定地址(此地址必须为4的倍数);data:要写入的数据
    3 d  e4 l, `* C3 @* X9 n' S, Q
  220. * 返回                        :        STM32FLASH_STATUS
    7 _+ k& I* O) u+ o6 r1 I
  221. * 依赖                        :        底层
    , h/ D( f. e# m. |( I* i
  222. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    , y9 w, a+ o' F& X2 s, a
  223. * 时间                        :        2020-02-084 ?- ?: D7 F" f7 e" V* ?# a- d8 `
  224. * 最后修改时间         :         2020-02-08
    4 N0 c* I& ]! H* q
  225. * 说明                        :         警告,地址必须为4的倍数; ?1 J  W2 d0 n, A) d! }9 {3 R
  226.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    & h2 v: g3 K* T( ]; q
  227.                                         不会判断是否能写入
    * y' S3 R  i$ F& o* v
  228. *************************************************************************************************************************/
    9 p1 u  n5 ^  L$ Y* X4 v! o% y& p
  229. STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)
    ! V# |9 N+ j* I. m
  230. {! g1 M$ b. G0 D; r$ Z0 }' l! ?( `
  231.         STM32FLASH_STATUS status;
    0 A0 r9 w2 q( _* @, I% ]

  232. : u/ _+ i# W/ E2 z4 O
  233.         status=STM32FLASH_WaitDone(200);                 //判断状态+ D! v: S* e  j- F, X
  234.         if(status==STM32FLASH_OK)                                //没有错误% n# Q# a+ Y# p* [
  235.         {8 F" W5 H1 ^9 L0 d' U1 E
  236.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    & o, B  S- m1 p, z1 y+ q0 s
  237.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!9 H6 m9 M1 v, K* P& s# ]
  238.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误0 L) U$ G* n9 s' h- G) P
  239.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        - V) p* z/ o! X- X. c
  240.                 while(dWordCount --)& P3 \  R, ]* P$ E4 ~3 j
  241.                 {. z# g* _3 u# u6 l3 @  W$ n
  242.                         *(vu32*)faddr=*data++;                                //写入数据+ _4 ~( ?' Q" r1 y* T- D
  243.                         faddr +=4;                                                        //地址自增+42 c1 ^: R5 ~" f* P& R
  244.                         status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.
    ! H; H0 C3 w* J, |
  245.                         if(status!=STM32FLASH_OK)                        //有错误+ u  a, b7 B* k( C
  246.                         {
    # C( L1 p  U6 `: l+ W- O0 j; L
  247.                                 break;4 W' E- z( B/ C8 E
  248.                         }2 N  R' w) v; o  K1 p
  249.                 }2 Y( s% ]8 U4 M% q

  250. & S% E6 `7 t# Y) x
  251.                 if(status!=STM32FLASH_BUSY)                        //非忙4 A3 ], l; g; N- N
  252.                 {        
    / I2 {! t! i+ y: n  g/ {
  253.                         FLASH->CR&=~(1<<0);                                //清除PG位. m  w3 q( |7 Y# Y1 I3 g
  254.                 }
    6 I$ Z# e7 V3 C+ _! ]" f  }) J
  255.         } ! ]9 \* O# r1 n, V1 J# H2 h4 x
  256. & V. s- ~  X: g
  257.         if(status != STM32FLASH_OK)* v8 m9 p$ {4 _8 x
  258.         {- \- y9 q* r7 G7 e3 U
  259.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
    7 P% N) v0 s# c6 ]. q1 x3 E& c
  260.         }
    ; C% Z7 N: x2 |& X0 p" ~; D. s
  261.         
    ; ]" o. X/ \8 y' B- q
  262.         return status;
    + m. j7 o3 Q% X1 Q; z3 [! B2 _
  263. } + Z, C6 V% I8 M& i: T

  264. 6 M$ M( z) g% ^8 \) r. Q/ d

  265. " J+ _6 f6 p" ?
  266. /*************************************************************************************************************************
    2 _, R, G% W  p6 ~
  267. * 函数                        :        u32 STM32FLASH_ReadWord(u32 faddr)
    ( U* L" F- m: `7 [; @
  268. * 功能                        :        读取指定地址的一个字(32位数据)
    # C+ F- [3 @/ ?7 S4 N0 K0 Z
  269. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);+ q0 {7 j% h1 ]- f7 C* A
  270. * 返回                        :        数据
    & P) g+ e- b9 T6 n2 ^
  271. * 依赖                        :        底层
    3 e: W- M5 k& y( W# f
  272. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    6 I- T" @0 ^7 S2 Q) ]
  273. * 时间                        :        2018-01-032 t  x" l; P6 _* Y' a  n7 t1 M
  274. * 最后修改时间         :         2018-01-03, S0 D+ z8 J( |( ~
  275. * 说明                        :         警告:地址必须是4的整数倍; a8 J( i" \/ o: Z# m
  276. *************************************************************************************************************************/8 t% g6 O& P8 h7 G- \; X
  277. __inline u32 STM32FLASH_ReadWord(u32 faddr)7 D( @2 ~' D. R
  278. {: t+ v! Q* g. l! U6 o
  279.         return *(vu32*)faddr;
    - }1 y# e5 S- x
  280. }0 w- ^/ `0 B6 E7 E6 S" c
  281. & B; Y+ X+ r5 S: D

  282. ; x7 y6 |& q3 J, f
  283. /*************************************************************************************************************************. {6 M; L8 v, c- x7 c
  284. * 函数                        :        u8 STM32FLASH_GetFlashSector(u32 faddr)
    8 J/ u, w& F) M1 `
  285. * 功能                        :        获取某个地址所在的扇区
    1 f! A$ Y3 V$ `( a
  286. * 参数                        :        faddr:指定地址
    8 e  }+ W, w5 O( z7 @
  287. * 返回                        :        删除编号,0-6,如果超出了也会限制到6
    4 u% _( C! f0 l
  288. * 依赖                        :        底层( G4 k1 Q- i: Z8 z) a0 w/ D' H
  289. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    % C* |( \$ |+ z2 ?2 L! g( _
  290. * 时间                        :        2018-01-03
    8 M' `6 U' F5 G6 R; b- V
  291. * 最后修改时间         :         2018-01-03
    / A; I' `6 B+ D- s! k6 d' _$ W4 c
  292. * 说明                        :         地址请不要超出范围9 ^4 Y) V" C- y/ |. S
  293. *************************************************************************************************************************/
    ; w' v3 n9 I* w  a
  294. u8 STM32FLASH_GetFlashSector(u32 faddr)
    7 O2 @/ `! g3 p8 D8 z
  295. {
    " @, _# P& B7 Q: g; E( l$ {- R
  296.         if(faddr<ADDR_FLASH_SECTOR_1)                return 0;
    . ?1 M8 J3 V. m; F  s1 V$ d: H" Y
  297.         else if(faddr<ADDR_FLASH_SECTOR_2)        return 1;
    4 M' R7 D' b9 |$ y
  298.         else if(faddr<ADDR_FLASH_SECTOR_3)        return 2;
    . o" Z/ A2 c1 a; K, U' V0 F, _2 I+ O
  299.         else if(faddr<ADDR_FLASH_SECTOR_4)        return 3;
    , O; w4 b+ g/ l( o
  300.         else if(faddr<ADDR_FLASH_SECTOR_5)        return 4;
    ! x% h/ K: G* O" y2 R! y
  301.         else if(faddr<ADDR_FLASH_SECTOR_6)        return 5;
    / ~" x  B9 {  I  S8 I
  302.         else if(faddr<ADDR_FLASH_SECTOR_7)        return 6;
    / Q0 {% w7 i# f) h
  303.         else return 7;        
    2 a2 h3 E3 D% ^' J  H6 Z' z$ B
  304. }
    4 b6 b; ?' g, b5 w1 ?
  305. . ]9 n% Z- p4 T- a2 _
  306. 5 c' u7 \2 }% o1 w) t- ]
  307. /*************************************************************************************************************************/ u9 G5 z8 `* j3 u) k0 l" {
  308. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  
    3 K- F! m9 t/ a& m' e
  309. * 功能                        :        不检查的写入* N2 n1 h8 S" k2 z  K
  310. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数 : v$ K2 l2 N8 ~$ N
  311. * 返回                        :        状态0 Q% _9 ]  f1 v5 U4 ]
  312. * 依赖                        :        底层
    & @% }$ F  T2 w' h- T/ D
  313. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>/ n! H2 H  Q0 ]: G* V7 n; r
  314. * 时间                        :        2013-10-20
    2 d7 `( V: v0 g! k* g* v, x
  315. * 最后修改时间         :         2018-01-03
    ! S1 M8 ~/ G% M' H4 H
  316. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)# h" Q6 ~' G/ C; y
  317. *************************************************************************************************************************/
    ! h, r7 }% Z2 l  I! F6 M
  318. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   1 y2 x2 X$ N% o  A  M# r4 N
  319. {                                           % Y) {6 @3 z, K5 g$ i. v- d1 x9 \$ h
  320.         STM32FLASH_STATUS status;
      Y) i4 F/ N- x8 a! r+ x7 m" _
  321.         
    , X. i8 t2 Z, C, l' k) \
  322.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误/ ?8 V( Y* B3 U# O
  323.         STM32FLASH_Unlock();                                                //解锁 ( ~0 b" C( v5 |3 |4 x
  324.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
      g# d% o* B4 A  D# y' x
  325.         {
    0 i, L& R( h. j
  326.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    ) u2 e& e; D2 q3 \  f
  327.                 FLASH->SR |= FLASH->SR;- L7 [" H1 ^. ?. V' V% N
  328.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    3 [9 c% o* Q* Y( r6 g! H
  329.         }
      T/ j2 ^  Y5 A4 {
  330.         status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据. Y( \- C. ?3 K9 n2 e- u% l
  331.         STM32FLASH_Lock();                                                        //上锁
    4 _2 F3 b2 d. V4 i
  332.         return status;
    ' O4 }+ k4 Z& K, W- r8 F
  333. }
    . A/ s, s2 |+ p/ [. w2 h

  334. 4 R) X% S3 i- M9 k5 \4 r5 Y
  335. ; u2 ?! y( \' ~% }% T4 q; V& u
  336. /*************************************************************************************************************************
    6 U6 n+ Y! h# J4 s
  337. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   
    . ~. g0 f: o' o
  338. * 功能                        :        不检查的写入一个字. \; c# C! h9 {  }3 S% j. A- x
  339. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);data:要写入的数据值( b- ?; K- I" V9 L* n- S- b
  340. * 返回                        :        状态' v# R6 ]8 ]; r  H0 F
  341. * 依赖                        :        底层
      |7 t5 ^9 {0 i$ ^
  342. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    2 O& t5 u. V6 T3 t+ B/ O
  343. * 时间                        :        2020-02-080 T: K  Q% z* L: q
  344. * 最后修改时间         :         2020-02-08
    & E8 y8 u( F8 E* w* v& r
  345. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)& i% l& s6 B( Y4 r8 S
  346. *************************************************************************************************************************/
    * x# I# s+ _, @. B
  347. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   
    , ]2 @! t' T& F/ L' s* a( t7 a
  348. {                                          
    ' s8 M: x* O5 ]( d  _& T- T
  349.         STM32FLASH_STATUS status;" g! n& H6 @9 U1 J3 @- Z+ k- m
  350.         + j' K  @- b( T0 |# t# |8 |
  351.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误$ @4 ^" Q- N# p% N1 H
  352.         STM32FLASH_Unlock();                                                                                                        //解锁
    # \( O* w; n$ Y* h1 q# P/ ]; j
  353.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    7 O9 s6 A& t' k# n$ d# p2 r" q
  354.         {9 h2 h7 P) a9 n; R
  355.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);- P, F& s, D# y7 a
  356.                 FLASH->SR |= FLASH->SR;
    + H( M6 v6 @7 J
  357.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    6 L+ B9 Y; @1 \0 Z: K
  358.         }
    : V; j- \: e) W. N
  359.         status = STM32FLASH_WritedWord(WriteAddr, data);                                                //写入1个字的数据
    , G# X, ~" h7 e
  360.         STM32FLASH_Lock();                                                                                                                //上锁: c; b! \+ X9 [% w, b9 @7 \* @
  361.         return status;9 b' A$ S% e7 q; N* [" l
  362. }
    3 p' D% O7 ~' E- n: L$ r/ e

  363. . ?4 w6 H- P7 ^

  364. . f7 I. g2 x3 K) V' v4 m
  365. /*************************************************************************************************************************4 Z2 W, _; _5 P6 G- Z' m* D
  366. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        7 ]1 i' ]$ O' E8 C# R/ Z* ]! [
  367. * 功能                        :        从指定地址开始写入指定长度的数据(数据长度字为单位)
    4 t$ J/ r$ z2 `/ X
  368. * 参数                        :        WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.)! F, a+ `& E( S5 A8 r& R
  369. * 返回                        :        0:完成;1:忙;2:错误;3:写保护
    ' z. H9 `; y0 C, M7 m
  370. * 依赖                        :        底层
    2 S& H* N: ~1 d
  371. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    - _, X/ F) H( d; v6 B+ ]
  372. * 时间                        :        2013-10-207 X! @+ P* }6 }8 n6 S- c5 i
  373. * 最后修改时间         :         2016-01-07
    0 }. a$ y+ \9 ^! ?' M
  374. * 说明                        :         警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据
    * o1 V& `* J, Q- s. E5 i. i" C' Q
  375.                                         如果需要保存其他的数据,请在应用层进行实现(比如:先读取扇区,修改扇区,擦除扇区,写入扇区,需要大内存支持)
    5 Y4 ?& ?0 S  F# k! ?
  376. *************************************************************************************************************************/
    - |! l1 h  {2 `1 ^
  377. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        
    0 o9 w4 s0 m' Y+ n+ L0 F. N
  378. {" \$ F/ d1 I+ z7 c  y+ W8 h
  379.         STM32FLASH_STATUS status;
    8 J: ^/ |$ J- ^
  380.         u32 addrx=0;& O- F0 [9 O# e7 Z& K
  381.         u32 endaddr=0;        
    , A6 s% Y# H5 f4 h+ [) \% V
  382.          
    8 N* n; b% L6 D" q
  383.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR;        //非法地址
    1 G% r7 Q' V1 I  W) E9 h! y( C( c
  384.         
    ! }+ }6 G: ~- w  t0 F5 `
  385.          FLASH->ACR&=~(1<<10);                                                                //FLASH擦除期间,必须禁止数据缓存!!!搞了我两晚上才发现这个问题!  W! y/ y* S" }6 ~( U
  386.         addrx=WriteAddr;                                                                        //写入的起始地址
    3 C( {/ ]8 _5 F- I
  387.         endaddr=WriteAddr+NumToWrite*4;                                                //写入的结束地址  s" X  ]7 K6 _+ W% {
  388.         
    , ]4 v9 n3 W) u4 |
  389.         if(addrx<0X1FFF0000)                                                                //只有主存储区,才需要执行擦除操作!!$ A3 r) a* r$ D9 X0 U
  390.         {
    ' |7 f, q3 I8 X+ n8 c0 ]; S7 ~
  391.                 while(addrx<endaddr)                                                        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
    ) L+ q; Y1 \$ |) G3 ?
  392.                 {
    # B' M# c4 w9 X! l) q" Y  f
  393.                         if(STM32FLASH_ReadWord(addrx)!=0XFFFFFFFF)        //有非0XFFFFFFFF的地方,要擦除这个扇区
    ( X+ i* |( [- p% K3 b% I
  394.                         {   : W1 c/ h" P! [  W
  395.                                 status=STM32FLASH_EraseSector(STM32FLASH_GetFlashSector(addrx));+ m& X$ \8 R( P% v9 B& q: }
  396.                                 if(status != STM32FLASH_OK)break;                //发生错误了
    ( R" D# z" L+ o4 V$ V3 _; U6 r  C
  397.                         }else addrx+=4;
    : A6 N/ Y! s- S3 X
  398.                 }
    ! t% j, }. A& `" d( u3 o" ~) B6 b
  399.         }
    . b2 B& B. _( }! s, V1 ~2 {
  400.         if(status==STM32FLASH_OK)- y% c1 @* ~4 T9 S
  401.         {! A% n# ^8 f" D- F  A3 d
  402.                 STM32FLASH_Unlock();                                                        //解锁
    . H3 B/ B6 E6 {
  403.                 if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现+ b# o/ h. P) D, T! v/ I
  404.                 {9 w8 y7 M# M) Q" c
  405.                         DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    + }) Z' O( _! x( K( i: D, l
  406.                         FLASH->SR |= FLASH->SR;: A2 ^) `/ W3 H  @* {. X
  407.                         DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);5 G) d7 @5 R+ V( @
  408.                 }, l. `) _5 ^8 G, a) L
  409.                 status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据: O- e6 x. U+ W7 A4 h. M
  410.                 STM32FLASH_Lock();                                                                //上锁
    ' ~+ t$ p0 s& P
  411.         }
    ; y2 \9 L( g# ^2 w
  412.         FLASH->ACR|=1<<10;                                                                        //FLASH擦除结束,开启数据fetch
    2 x$ t3 c" a+ x2 H
  413.         4 K: q0 w9 z- G  z; E
  414.         * K' O; p6 p4 z# w
  415.         return status;, d# C* Y# n5 D$ C. X
  416. }/ I" N: p9 X& ?! O- n
  417. 9 P2 O6 [  O/ E1 V+ ~; U

  418. 1 A( m+ b. I2 r7 J9 b' F( A

  419. , m2 [  {" V8 M% s

  420. 3 o% M4 E. l$ ?( i1 x
  421. 4 r7 w2 f8 V+ k2 |8 _2 u
  422. /*************************************************************************************************************************$ a* ~5 f) ?8 d' f9 a  E% T
  423. * 函数                        :        u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead) 5 j1 E& ^8 j, g$ h( G
  424. * 功能                        :        从指定地址开始读出指定长度的数据
    , I! T7 p/ K$ H- f
  425. * 参数                        :        ReadAddr:起始地址;pBuffer:数据指针;NumToWrite:字(32位)数
    & h( f1 @6 z9 @0 e
  426. * 返回                        :        读取的数据长度(字为单位)
    ' _/ g9 v" X+ W+ m6 U4 I
  427. * 依赖                        :        底层3 u  m: F% u# m6 s* M! S8 I# {
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    : ?" g$ C. g8 F: S2 H
  429. * 时间                        :        2013-10-206 @5 f+ M* n8 n1 ?3 J0 k4 y' |2 P# {
  430. * 最后修改时间         :         2016-01-07
    9 }$ J* L, W( I1 a$ r0 t# f
  431. * 说明                        :         地址必须为4对齐9 G' i3 D$ L( O( E. S
  432. *************************************************************************************************************************/) N: N8 r" K# J
  433. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)           
    $ h+ R# b; x. U9 {6 ~* i: d
  434. {# c4 c! P7 ^& X) K5 y; w' Z) Z# B
  435.         u16 i;
    # J* b8 h& s# f  y2 Z6 z: Q
  436.         u16 cnt = 0;3 N1 I; Z8 L* ~! _
  437.         
    $ j+ ^! j: @5 R, T5 S
  438.         if(ReadAddr<STM32_FLASH_BASE||ReadAddr%4)return 0;        //非法地址
    9 f" ]$ @" m1 F* e& w
  439.         , E0 H# R' y$ p2 I+ w: z# I0 {
  440.         for(i=0;i<NumToRead;i++)6 j0 E# u+ \- j* @$ \7 j( A; W6 J
  441.         {
    - d. |! c- E+ i3 |2 o" a3 |0 S
  442.                 pBuffer=STM32FLASH_ReadWord(ReadAddr);                //读取4个字节.% ]/ [7 U: I4 d1 m( m' t! I
  443.                 cnt++;& o, \- L. t+ N9 q, s( o
  444.                 ReadAddr+=4;                                                                        //偏移4个字节.        2 Q8 }* a6 b/ Y% F  `
  445.         }  O  a: q) f/ m5 m# A' R: ]7 m
  446.         return cnt;( ^5 L6 V3 Y& w9 X
  447. }  K" ]+ u) K* r3 Z
  448. ( b* H0 T8 c. W6 P! O. E( w
  449. % g6 ^& e0 r# V" c, ^
  450. /*************************************************************************************************************
    3 w0 f3 ]" c+ i
  451. * 文件名:                        stm32f7_flash.H
    6 v4 {- N$ l( U, j: P" X
  452. * 功能:                        STM32F7 内部FLASH编程驱动函数! `4 w  W' F+ q/ }* `4 v
  453. * 作者:                        <a href="mailto:cp1300@139.com" style="">cp1300@139.com</a>
    . e; d" L' U2 u( ]% Y( [0 t. h
  454. * 创建时间:                2013-10-20
    - M9 o' v- F  t8 a
  455. * 最后修改时间:        2020-02-073 [& A& n# ^' I1 M7 M
  456. * 详细:                        用于STM32F7内部flash读写驱动+ T- k3 x" E2 P# I
  457. *************************************************************************************************************/# c! l5 c& ?# ?  `- d
  458. #ifndef __STM32F7_FLASH_H__2 f7 ?4 |1 f9 ?
  459. #define __STM32F7_FLASH_H__/ k5 P, E6 M& M' k+ p  p# k
  460. #include "system.h"  
    , |: i. ~9 o# {. ]! j4 r

  461. 2 [1 X4 T" V3 F6 n) E0 D  r% E
  462. //FLASH起始地址
    " Z1 M3 z$ C4 c# i  H2 b: m* m- y, }
  463. #define STM32_FLASH_BASE                 0x08000000                         //STM32 FLASH的起始地址/ }% q0 A0 C# n6 o  X

  464. 0 @& R# X+ g" v
  465. //FLASH 扇区的起始地址! q( O; f( ]3 \5 H$ l+ S2 n9 k
  466. #define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)         //扇区0起始地址, 32 Kbytes  
    2 j2 u  ~% T8 J5 f4 V: a
  467. #define ADDR_FLASH_SECTOR_1     ((u32)0x08008000)         //扇区1起始地址, 32 Kbytes  # m/ T7 v, t$ J9 u' o5 r  j
  468. #define ADDR_FLASH_SECTOR_2     ((u32)0x08010000)         //扇区2起始地址, 32 Kbytes  
    2 d* K6 Z' E  z6 F( R3 Q7 J5 U2 U
  469. #define ADDR_FLASH_SECTOR_3     ((u32)0x08018000)         //扇区3起始地址, 32 Kbytes  # L. F) p* \3 f& g
  470. #define ADDR_FLASH_SECTOR_4     ((u32)0x08020000)         //扇区4起始地址, 128 Kbytes  + m) y, s+ ?0 ^; R$ ]! w/ m$ ?* x
  471. #define ADDR_FLASH_SECTOR_5     ((u32)0x08040000)         //扇区5起始地址, 256 Kbytes  6 I8 ?* L& b% g8 x* x
  472. #define ADDR_FLASH_SECTOR_6     ((u32)0x08080000)         //扇区6起始地址, 256 Kbytes  
    7 o- M7 T1 H4 k. m% W4 b( P3 z
  473. #define ADDR_FLASH_SECTOR_7     ((u32)0x080C0000)         //扇区7起始地址, 256 Kbytes  , v7 M1 ~5 d, ]" K# j
  474. $ y$ s- n  G( h1 J. t! a

  475. 7 b; p: y' H6 d, s" `: S, c
  476. //FLASH解锁键值
    / L7 @+ O. @& v. ~6 R% f
  477. #define RDP_KEY                  0x00A5
    " H+ F, i5 Z3 c2 k
  478. #define FLASH_KEY1               0X45670123
    - j! }6 P) ^& M& \1 n& m* t
  479. #define FLASH_KEY2               0XCDEF89AB
    4 C! e2 L6 w# B! B  `! U$ s
  480. #define FLASH_OPT_KEY1           0x08192A3B. j' ^  n) \$ ^" Z/ q4 N" X2 f& J% l
  481. #define FLASH_OPT_KEY2                         0x4C5D6E7F
    0 E* j, C- w. A

  482. 2 V; ~' M, x1 b7 J# j
  483. //STM32F7 Flash操作状态1 S  }! [% L) d* y+ X, E+ X2 ?
  484. typedef enum% z! v/ T: G; A% g) Q" z, n
  485. {# ~  x7 S( L, O* {/ r. c$ Q
  486.         STM32FLASH_OK                        =        0,        //操作完成& i* G1 H3 h+ w4 o
  487.         STM32FLASH_BUSY                        =        1,        //忙
    - `* e( I% w; W# S
  488.         STM32FLASH_WPRERR                =        2,        //写保护错误
    1 C, R8 r: D7 ?8 P2 i0 i: z
  489.         STM32FLASH_PGAERR                =        3,        //编程对齐错误,必须128位对齐4 u0 g" I8 i- p
  490.         STM32FLASH_PGPERR                =        4,        //并行位数错误
    2 |, z* k$ @  ^
  491.         STM32FLASH_PGSERR                =        5,        //擦除顺序错误% n5 B8 @3 z% C! Q! d& r" ?1 }6 h) y
  492.         STM32FLASH_OPERR                 =        6,        //操作错误( o- w# {0 @2 P! K* k( r
  493. }STM32FLASH_STATUS;
    : C& U' ~' Q, g$ Q( n4 z
  494. 4 x5 D+ v% F) F& p8 `, y0 y6 r
  495. //常用接口
    ! F/ C/ f) T% a8 p# p( g
  496. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr);                                                                  //擦除扇区
    . T) i! [* R7 i) ~
  497. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite) ; //不检查的写入多个字的数据
    2 z7 r1 U0 ?: C$ M6 h
  498. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data) ;                                //不检查的写入一个字的数据
    * a$ `  V6 h4 S% X
  499. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite);                        //从指定地址开始写入指定长度的数据(数据长度字为单位)
    / U% t. n, `7 K$ p
  500. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead);                                                        //从指定地址开始读出指定长度的数据
    & f6 N/ ?* N9 j$ J' @

  501. 3 e2 `# ]( J9 B
  502. //不常用接口' o- Q2 o$ v: F. h: C4 X3 z
  503. void STM32FLASH_Unlock(void);                                                                                                                        //FLASH解锁
    # @1 ?7 D5 P# ~9 z
  504. void STM32FLASH_Lock(void);                                                                                                                                  //FLASH上锁
    ; k0 ]* k  {" T6 p$ j
  505. STM32FLASH_STATUS STM32FLASH_GetStatus(void);                                                                                          //获得状态8 t1 Y# E  Z& b7 d, x
  506. : H5 I& @3 c0 h9 x( K
  507. 1 R" l$ n8 g5 O1 o. ~/ \- r3 T2 E
  508. #endif        //__STM32F7_FLASH_H__/ h% T4 h8 p, W' ]; L- X7 K

  509.   j% m; ^: _& i
复制代码
  y0 ^" C' H+ C- K7 J
收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版