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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
总体来说与STM32F4操作是一样的,就是扇区大小变化了,测试过程中发现当PG=1之后立即写入数据到flash会造成编程顺序错误,通过增加一个nop的延时即可解决此问题,还可以通过将多个数据连续烧写的方式避免此问题,就是当PG=1之后,把所有数据都烧写完成后再将PG=0,不要频繁的开关。) `" t7 f1 {3 T

7 \) V1 R3 }4 |: B* K& V2 G
  1. /*************************************************************************************************************
    ) Q2 n4 {4 p8 L+ @7 O" B
  2. * 文件名:                        stm32f7_flash.c
    " |4 k6 n7 H) M+ b  s: B4 k2 m! o
  3. * 功能:                        STM32F7 内部FLASH编程驱动函数  m2 z9 r( M# q# A/ {' i! w
  4. * 作者:                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    - y% R  {# K" [! I$ E/ S
  5. * 创建时间:                2013-10-20% @- h+ O" u  G' ~) s7 C, i. t( ?
  6. * 最后修改时间:        2020-02-07
    9 E5 f1 N3 m, l' z& w  H( Q
  7. * 详细:                        用于STM32F7内部flash读写驱动
    2 b/ z4 L1 x% y8 A8 H* H! L! j1 x! K
  8.                                         默认为3.3V供电,并且宽度为32bit;/ e5 k! e. _$ J. o: H
  9.                                         扇区擦除最长时间:32KB扇区500ms;128KB扇区1.1秒;256KB扇区:2秒/ @# d6 j2 w( P( f' W
  10.                                         修复STM32F7开始写入数据时,PG=1后没有延时导致异常,增加批量写入多个字的数据函数STM32FLASH_WriteMultipledWord()支持。# H& z  M. N) n, D1 P# X# V+ {
  11. *************************************************************************************************************/6 A  n: S; r& @) {
  12. #include "stm32f7_flash.h"
    / E7 k6 ]( U( z' k
  13. #include "system.h": v; s) Y1 l( C& K% ?8 H7 }
  14. #if(SYS_WDG_EN_) //使能了看门狗( H3 q+ i0 L, U. d- k. Z9 {* A
  15. #include "wdg.h"7 R. \" R* W; o; b+ Z
  16. #endif //SYS_WDG_EN_
    9 E+ O8 b' y0 T5 l, N8 K

  17. + k7 o( ]4 x& K# t7 b$ n' t+ {

  18. 1 M4 q( ]6 L. z; Z! P  W# @

  19. & Q. t! G& c/ d) D# b1 U& ^. a$ n
  20. . E' r/ ?% l( q9 y) _  ~  }
  21. /*************************************************************************************************************************
    , s; z" t2 ]9 l
  22. * 函数                        :        void STM32FLASH_Unlock(void)9 Y/ u! z  R- S* q! E4 Z* H
  23. * 功能                        :        解锁STM32的FLASH7 s* o  P7 c6 W3 w
  24. * 参数                        :        无
    ) `% w( Y* M4 L, m4 \: A
  25. * 返回                        :        无
    : U+ S8 W8 u5 D" \( a' Z- s
  26. * 依赖                        :        底层. H: f4 L, u' g2 i
  27. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ; B- j; Z. M9 Z: u' g  C& d
  28. * 时间                        :        2013-10-20) T" d( e/ o* m) f
  29. * 最后修改时间         :         2013-10-20* q8 ]  m: |; L& M2 e: Y' D4 t
  30. * 说明                        :         " j/ g3 H8 J8 B$ B! W) Z  m+ a
  31. *************************************************************************************************************************/" e% u" Y1 l" d8 o% T. y$ N1 V
  32. void STM32FLASH_Unlock(void)1 @. j1 o' e  V3 u
  33. {
    * G2 F. d+ w0 Y5 ?
  34.         FLASH->KEYR=FLASH_KEY1;        //写入解锁序列.% `7 p% X" k, n: X+ l
  35.         FLASH->KEYR=FLASH_KEY2;$ ~; D% L+ X( k6 Z6 F$ Y1 `
  36. }8 N: J' X' U! q9 ?3 X
  37. / M& y4 |! h4 e/ E
  38. 4 Z9 a$ }: W# e9 y, q: U: i

  39. 8 ~# m2 W) \! }
  40. /*************************************************************************************************************************$ M0 k# [2 @8 z. V% b2 R
  41. * 函数                        :        void STM32FLASH_Lock(void)
    , E8 B2 z& j0 d+ d3 @
  42. * 功能                        :        上锁STM32的FLASH3 ]  d- v# v$ D
  43. * 参数                        :        无7 S) q- q0 C$ h' E7 w5 C
  44. * 返回                        :        无1 t4 P- [( C, A( o6 [* b) G
  45. * 依赖                        :        底层
    , N: I2 b! V/ D7 T
  46. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    & }$ W3 z/ l) [, z6 B' L3 q
  47. * 时间                        :        2013-10-20  s' L& y  s$ Y6 Q
  48. * 最后修改时间         :         2018-01-13
    $ B8 p5 h8 j, g# @/ X8 u3 [: K9 A
  49. * 说明                        :         
    % k- ?2 A3 H+ d( a4 l* T
  50. *************************************************************************************************************************/
    . W9 c( B8 Z& l  z+ `) m
  51. void STM32FLASH_Lock(void)
    $ t3 X' N/ Q; ]' _4 [
  52. {; ^7 |1 b9 G  [  T0 x3 _2 q: @
  53.         FLASH->CR|=(u32)1<<31;                        //上锁
    2 x2 F& ^+ K& j  o5 |* V# H) P
  54. }
    1 i% }5 R# i6 @6 Y7 [( K

  55. % w' s( n! i8 O  |: X  S
  56. 2 d" D* }+ \/ _" e9 j

  57. - X5 M- ^" D0 ?) {1 A, Z
  58. 4 Q6 c0 j9 c: N8 H$ U; p7 w# V
  59. /*************************************************************************************************************************, i, o# ]: U1 o4 E
  60. * 函数                        :        STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    0 x4 k: n% T( _* V# C
  61. * 功能                        :        得到FLASH状态
    , y5 k. q5 v+ n
  62. * 参数                        :        无
    1 y% `5 @2 A9 {" [- F7 i1 K
  63. * 返回                        :        STM32FLASH_STATUS: X; a1 N, [4 U" @% v( g& Q4 ^* q
  64. * 依赖                        :        底层$ B' X. e8 }5 E5 }3 V
  65. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>1 o8 W0 i5 E$ s% ?
  66. * 时间                        :        2013-10-202 |$ E2 r6 ^2 M* y% f8 T
  67. * 最后修改时间         :         2018-01-03
    ) F& p" B0 m- \
  68. * 说明                        :         
    9 m* g1 S+ L( F3 r" _; F, n9 F/ I9 r
  69. *************************************************************************************************************************/
    ) V4 n* V$ X0 U2 I, ~' t/ S' m- p
  70. STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    ( @; l  z/ F* U
  71. {        
    / M$ L0 |  X; J% }9 i% x
  72.         u32 temp=FLASH->SR;
    % Y6 Q# ?; l! \: Y4 J
  73.         
    5 q8 z7 Y4 e: Q  O5 Z
  74.         if(temp&(1<<16))return STM32FLASH_BUSY;                        //忙( C: o4 J. z% x$ D* p0 K: v
  75.         else if(temp&(1<<4))return STM32FLASH_WPRERR;        //写保护错误; i8 F, Y) _( t* o' t) ?! _$ e
  76.         else if(temp&(1<<5))return STM32FLASH_PGAERR;        //编程对齐错误+ A& ?# V# F* M$ V
  77.         else if(temp&(1<<6))return STM32FLASH_PGPERR;        //并行位数错误
    ! o0 k! I! X/ O/ o
  78.         else if(temp&(1<<7))return STM32FLASH_PGSERR;        //擦除顺序错误
    , y6 h* j: i# i( @2 d* Q5 n1 b
  79.         else if(temp&(1<<1))return STM32FLASH_OPERR;        //操作错误  \8 ], i2 g( E  N
  80.         return STM32FLASH_OK;                                                        //操作完成
    * v. P3 H* Y  v7 i) y
  81. }( h; ^( ?! j0 Q! u! b2 B% N
  82. / q6 L3 o) d3 j+ F
  83. + g+ F$ q, `$ \. A. n

  84. 1 X) X3 t$ V* A  S
  85. /*************************************************************************************************************************
    # T. Q4 a6 q* {2 d7 ]  q
  86. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)
    ( r& T5 ~. t) v+ ?3 A8 o
  87. * 功能                        :        等待操作完成8 p) Z/ ^2 X/ a! p8 B
  88. * 参数                        :        time:要延时的长短,单位us2 B" [2 \" e2 ?' Q* w4 U
  89. * 返回                        :        STM32FLASH_STATUS4 s$ y# j$ m0 W& ?# K( H, I+ `4 V
  90. * 依赖                        :        底层8 s8 c' ]- X7 Q6 I. D; m* G
  91. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    , C0 [" n: a4 ~! t1 i
  92. * 时间                        :        2013-10-20
      }4 y! B' {0 ^8 x: L6 D- K
  93. * 最后修改时间         :         2018-01-03
    - m4 ^% D6 @5 |* m6 a8 r  a
  94. * 说明                        :         2018-03-24:增加清除看门狗功能
    , K7 w0 v" W. g
  95. *************************************************************************************************************************/8 V+ }/ G% T6 Q( q) z# {5 K" `0 q: h
  96. STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)5 j+ D4 ^5 N% \6 ^' r- ]
  97. {
    $ b' `% k/ _) v+ Z3 ~& V
  98.         STM32FLASH_STATUS status;
    ; F% d5 I1 e& v; _5 H# V' q
  99.         4 G. ~, I9 ~  y
  100.         if(time < 1) time = 1;( k% i0 R/ x" p2 w- P
  101.         do
    % g! z: h- m4 I- ^) Z7 t# N; ?5 Z
  102.         {
    * m% h/ d% v4 P: a9 [3 g4 _/ {+ a
  103.                 status=STM32FLASH_GetStatus();                        //获取状态& q2 o) h" n# U; m3 K: S
  104.                 if(status!=STM32FLASH_BUSY)break;                //非忙,无需等待了,直接退出.
    * L. w/ t) H' p" t
  105.                 Delay_US(1);
    . Q' k& |; ^  X6 N% H
  106.                 time--;
    ) P- g6 q, ]0 _! @* {6 r
  107.                
    4 k0 u6 B  U# l' @( c
  108. #if(SYS_WDG_EN_) //使能了看门狗
    , u+ |$ w) k6 x# r  U  b  y
  109.                 IWDG_Feed();
    8 S2 ~  f+ x# K( }7 X
  110. #endif //SYS_WDG_EN_        
    ; q* ~- V/ d. |' j3 b
  111.                 ! I  O# V( Y0 Q! z1 ~: y2 K* a
  112.          }while(time);4 v; a0 N5 E2 P% L; B% ]/ x
  113. # s  y; M1 w- H& {
  114.          return status;/ H7 V6 _( o# D6 ^  r6 X$ t
  115. }" ~2 M. `$ e2 _( h& x+ Q& f% B) a9 Y
  116. 6 G, e' f% k' v" j* x/ l

  117. - J5 d1 M# z* u0 l

  118. " O# e# M3 B( D6 G+ C
  119. /*************************************************************************************************************************5 z$ A: ~' P; N
  120. * 函数                        :        STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)
    % T% [: l  y$ p# Q4 {. ]0 B
  121. * 功能                        :        扇区擦除
    + V! z  G( c- S  y8 c
  122. * 参数                        :        sectoraddr:扇区地址,0-115 W% P/ {8 F: a# f9 B+ v" ]2 Q
  123. * 返回                        :        STM32FLASH_STATUS$ q" A( k* Y7 |" ~
  124. * 依赖                        :        底层
    2 b) h( w2 _) d; r% }9 k6 p& g
  125. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>8 S; k, K! b- D2 r6 |9 w
  126. * 时间                        :        2018-01-03% r" b, A; }7 U
  127. * 最后修改时间         :         2018-01-038 i' F3 t, A" F0 k$ d
  128. * 说明                        :         扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区
      E# G4 n" n" x4 L( V5 J; {
  129.                                         128KB扇区擦除足最大2秒' T' _8 Q4 M. d$ f' w$ W4 y
  130.                                         2018-01-16:修复扇区擦除时没有解锁问题
    6 A! `* `8 U( f7 A
  131. *************************************************************************************************************************/
    ' ]7 K0 G- D# v2 e# r4 b
  132. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)
    2 f0 r+ o2 r3 @5 W
  133. {
    2 J! Q9 b: n& i1 o
  134.         STM32FLASH_STATUS status;  B9 v2 A, ^. ]  z: U0 p
  135.         
    % u1 b# r# g' g. ?4 C' i* {
  136.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    ( W, U4 {5 w% S  X7 \# ~. Q( a
  137.         {8 W" N6 K# `$ y
  138.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);3 N$ t  T- I  i( Q9 ~( o
  139.                 FLASH->SR |= FLASH->SR;. a5 T- H$ H8 m1 L3 ?
  140.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    3 w0 {* V8 X5 m- E
  141.         }
    ) a: j' _- i* E' \6 ^9 ]
  142.         0 C1 F8 ]6 s2 n& I* \
  143.         status=STM32FLASH_WaitDone(2100000);        //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过
    - L; q8 T3 a  F  [( }& H$ |( t& @
  144.         8 h5 h% p/ Y: `6 ?) h
  145.         STM32FLASH_Unlock();                                        //解锁 $ Z  V* w2 f) R. }$ N# }
  146.         if(status==STM32FLASH_OK)                                //没有错误. ]' ]. V9 V  q  E2 b( T! _
  147.         { * N1 [- l- p' c. A6 Z/ Q  N# l4 Q
  148.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    " {# A& B8 d3 w: b" j. T! Z
  149.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    & W* s& H& {3 a7 F" x6 W
  150.                 FLASH->CR&=~(0XF<<3);                                //清除原来的设置
    * d! G0 S- x% C7 g
  151.                 FLASH->CR|=(sectoraddr&0x7)<<3;                //设置要擦除的扇区 % f7 c* W- c6 Z
  152.                 FLASH->CR|=1<<1;                                        //扇区擦除
    0 d( S. p+ H* N% ~1 g4 H% G! T* U
  153.                 FLASH->CR|=1<<16;                                        //开始擦除
    " t. s# Y% c& Y0 s  e$ ?, s
  154.                 status=STM32FLASH_WaitDone(2300000);//等待操作结束,最大2s  ) O+ @& `/ w( c. p- h6 N
  155.                 if(status!=STM32FLASH_BUSY)                        //非忙- v* v. j- ~% a. |
  156.                 {- V; V( z/ R; ^6 ~' i7 A# @
  157.                         FLASH->CR&=~(1<<1);                                //清除扇区擦除标志." [' f; |# k& _8 N& y# o
  158.                 }
    - I; s* b* [+ R! P7 d& h
  159.         }
    3 M9 j8 O4 U+ p5 E
  160.         //DEBUG("扇区擦除状态:%d\r\n", status);
    8 P: w6 O" n  c2 z, n. f6 y
  161.         //DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n", FLASH->SR, FLASH->CR);
    . G+ f" v9 _6 \8 C
  162.         
    / t) r/ ~0 m' Z- o) a/ C  P
  163.         STM32FLASH_Lock();                                                //上锁" w$ j, C% [) U, U' x6 }( P
  164.         if(status != STM32FLASH_OK), q6 }, w/ g. B" t
  165.         {. p0 t5 O  ~# w7 E6 A4 ^
  166.                 DEBUG("擦除扇区%d失败(错误:%d) FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",sectoraddr, status, FLASH->SR, FLASH->CR);
    . M  U) @0 ?. y0 d2 |" _4 V, A
  167.         }/ g' [# p6 T  l: @" t/ I, F

  168. ; _, i+ _; M5 k1 }) ~2 a
  169.         return status;                                                        //返回状态
    ( x5 V) o& a, L& Q* @
  170. }2 R; O/ E6 u! z: B

  171. 2 T9 p; `5 }+ H0 J
  172. ) g' {% V8 M& Q) Y- S! c/ Z
  173. 3 P6 U2 p) g- e+ T# c  l/ ?
  174. / R# \+ Q+ H( E5 j' G8 y9 J
  175. /*************************************************************************************************************************
    6 n- b/ R$ Z; X7 S
  176. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)6 F# M: M5 [/ A8 h0 ^. l  G
  177. * 功能                        :        在FLASH指定地址写入一个字的数据(32bit写入)8 h0 u6 l! o7 ~# R0 z$ r! R+ Z
  178. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据
    2 A+ R, j1 M) R4 _6 f) _  z
  179. * 返回                        :        STM32FLASH_STATUS. @+ X* C9 |- N
  180. * 依赖                        :        底层+ v% f6 g  U5 n- m# N9 C! @
  181. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    3 h1 k# `' g! t5 K& W% w2 P  f
  182. * 时间                        :        2018-01-034 J1 C, s& `' j8 j
  183. * 最后修改时间         :         2018-01-03& f7 A- X. R1 {9 c
  184. * 说明                        :         警告,地址必须为4的倍数; Y- K/ l% @+ X
  185.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁2 U8 n2 T6 e2 s. o
  186.                                         不会判断是否能写入
    . p' s6 r- J( H2 u) s: w
  187. *************************************************************************************************************************/; @0 u8 m4 f, v5 h( m* e
  188. STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)
    - J" T  S  E6 e2 E4 _0 R7 C# s
  189. {' l( K+ \1 ~& ^& S4 N
  190.         STM32FLASH_STATUS status;
    . @6 `  A0 U1 Q$ U: |
  191.         
    ; W# ]$ P* [# y, t0 l. G
  192.         status=STM32FLASH_WaitDone(200);                 //判断状态
    $ z5 I% H2 O0 Y  X8 G
  193.         if(status==STM32FLASH_OK)                                //没有错误- z! J+ _1 K2 Y# U/ @, ^
  194.         {6 J$ A. c( U8 ?7 K$ x
  195.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置1 V  \8 G5 M5 ?
  196.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    6 M  }; ?' k0 T9 p) M2 ?+ D
  197.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误
    " E3 B) ]; G, P
  198.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    2 D7 Y! d. T  c( A
  199.                 *(vu32*)faddr=data;                                        //写入数据
    ) e! n/ t% j% L4 u
  200.                 status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.# g  `! j- q* P1 c
  201.                 if(status!=STM32FLASH_BUSY)                        //非忙1 }5 v2 Y* x% n5 h/ s8 P6 f
  202.                 {        . b, t8 K) B! n1 u
  203.                         FLASH->CR&=~(1<<0);                                //清除PG位; G  `: l$ W7 [! t/ H& ?" d/ C
  204.                 }& S9 ~8 C2 F6 t
  205.         }
    2 m: d3 m1 K( i5 H

  206. 5 w: X  v4 h5 k+ W$ q
  207.         if(status != STM32FLASH_OK)/ C: w- y' y9 A
  208.         {- o. U% Y0 r9 x$ E8 b
  209.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);& a4 ?( {) _8 W. q8 X( F
  210.         }7 }" x# O' U  u5 A, s( W4 M; L/ ~3 Y
  211.         $ Z' O9 y! k8 e, U1 m
  212.         return status;# n$ l- w+ o9 r: v, i
  213. } & B; ^0 _* a+ n, D& B- i
  214. ) T# {3 ]% K7 W; A3 b! T

  215. 8 [9 }/ B$ Q- t) |4 Z; q' O" f0 I
  216. /*************************************************************************************************************************9 `( q! F/ y( M
  217. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)
    8 v7 ?, G4 o) |, H3 A! U
  218. * 功能                        :        在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)" ~3 f( u- i# e2 |( s5 @
  219. * 参数                        :        faddr:指定地址(此地址必须为4的倍数);data:要写入的数据* u7 O6 O- s& P3 R
  220. * 返回                        :        STM32FLASH_STATUS# v3 t( B9 i# q
  221. * 依赖                        :        底层" `' F# Z3 D5 F! y" g2 Q/ u
  222. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    9 P+ l, d# A0 P. `
  223. * 时间                        :        2020-02-08% ?" l& X9 a- `" F
  224. * 最后修改时间         :         2020-02-084 y/ {2 Z% f0 q+ P; ~
  225. * 说明                        :         警告,地址必须为4的倍数; m/ l3 f' F1 @
  226.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    * p4 C; t) J' ]# |9 L$ l' q" r5 B
  227.                                         不会判断是否能写入
    8 s! g9 J8 l7 I2 z0 K
  228. *************************************************************************************************************************/
    - |* c  G8 Y! V" o" b! Z* p
  229. STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)
    ; i. ]) K6 p6 F7 ^) X# h
  230. {, U, n6 Q& R% H- z) ~" V5 N. Q
  231.         STM32FLASH_STATUS status;
    ; J) a8 g1 L- _: b7 p! C

  232. 9 f7 O9 u  B  q5 q* g8 F
  233.         status=STM32FLASH_WaitDone(200);                 //判断状态
      c* B( e; a7 I
  234.         if(status==STM32FLASH_OK)                                //没有错误
    0 m7 `* z: {! J- G
  235.         {
    8 h7 Z' X5 ~3 \) s  ^: u, Q2 T
  236.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    1 F9 I4 @0 Y5 N4 G1 b
  237.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!6 L6 B3 u8 G- Z1 m, G9 `% h% _4 @
  238.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误4 \# `3 P2 k; @1 [) I
  239.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        ! ~2 x# m) s) q3 Q
  240.                 while(dWordCount --)
      V. |4 C) q8 X+ P' N5 W; F/ y
  241.                 {
    1 H# U- c- j; e! q3 d1 f
  242.                         *(vu32*)faddr=*data++;                                //写入数据  w3 k2 l" g3 ^( p0 A7 }
  243.                         faddr +=4;                                                        //地址自增+4
    $ N! R- P" S: C, x% I% ^' L
  244.                         status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.! B& l1 |3 B8 i# ]3 c
  245.                         if(status!=STM32FLASH_OK)                        //有错误
    ! x6 F! \) e2 {9 _2 o. z5 J
  246.                         {
    9 Q* r5 P* J1 I9 B! N# S9 h, A
  247.                                 break;/ v- q, R: f! ?: c+ u( }- D3 s
  248.                         }
    0 P3 K7 f7 Q/ m. A* t/ e+ I
  249.                 }  O5 ]2 x9 B6 q

  250. 1 d- _* V  k8 N$ r
  251.                 if(status!=STM32FLASH_BUSY)                        //非忙# O, ]1 x, x: W1 u* x; Q* S" l! P3 j
  252.                 {        
    # A% i% d: c3 k. o
  253.                         FLASH->CR&=~(1<<0);                                //清除PG位
    ' n/ S) i( g: f: i, K( ^) v6 k
  254.                 }* k: |  u- _- ?) K0 V$ x
  255.         }
    $ h. d: R  Z# G
  256. ( C- e( ?3 @1 ^" F3 {
  257.         if(status != STM32FLASH_OK): q4 l( T/ R+ m" V! p
  258.         {
    $ }- A7 Q8 F. _6 h' }1 ?( ]' W
  259.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);2 B: N4 h7 f" m6 \% `$ X, R
  260.         }
    8 v$ ^0 T5 Y' A* ]5 I: V+ n0 p+ P1 {7 C
  261.         
    6 |6 }( d9 G; q
  262.         return status;
    # F* d! c5 y3 I4 b$ i
  263. } " T$ w6 o1 s% c# `

  264. % I& c4 ?0 i9 T' d
  265. " l0 u' J3 d3 T) R/ a2 @
  266. /*************************************************************************************************************************
    . [/ B. t2 e# N" u2 m
  267. * 函数                        :        u32 STM32FLASH_ReadWord(u32 faddr), Z1 s0 D- B* f, @
  268. * 功能                        :        读取指定地址的一个字(32位数据)
    * c/ X$ s$ j8 H9 b& ~0 {' ?& @- N# N
  269. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);
    ; F+ U' N  m# u- N; |7 A
  270. * 返回                        :        数据
    1 r& D# B  J2 E9 v% O. t
  271. * 依赖                        :        底层5 w. }2 p0 A9 w0 E
  272. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>+ A! B/ Z) d* t# k: r/ V
  273. * 时间                        :        2018-01-03
    3 [( v4 j- m: G1 Q
  274. * 最后修改时间         :         2018-01-03" c4 L4 W: A, u, v8 k
  275. * 说明                        :         警告:地址必须是4的整数倍  g. @- [- T! t7 X
  276. *************************************************************************************************************************/
    2 |& W) w9 L" H) @: _" Y
  277. __inline u32 STM32FLASH_ReadWord(u32 faddr)
    9 s3 c$ N; s- J! h
  278. {
    7 |# N. R% Y! r3 O
  279.         return *(vu32*)faddr; 4 q% R8 f4 C# N0 r
  280. }) V7 u  m" A: L% o) b
  281. 5 @9 I5 P7 @0 ]1 r2 Z
  282.   Q! x" z4 T$ M2 m: g% D
  283. /*************************************************************************************************************************& `: B2 R2 o+ L4 Z9 k
  284. * 函数                        :        u8 STM32FLASH_GetFlashSector(u32 faddr)8 d3 l4 I* G( x1 \
  285. * 功能                        :        获取某个地址所在的扇区
    . Y2 X# I/ _! q2 g5 N0 M
  286. * 参数                        :        faddr:指定地址) Y: p% F8 M& X7 C( r* L
  287. * 返回                        :        删除编号,0-6,如果超出了也会限制到6( ]" {5 [# ?7 S) P  W" S
  288. * 依赖                        :        底层2 G9 g) W1 L% f9 f! {0 `4 e. o! x
  289. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>6 P5 A& P+ H. }, ?& v3 j
  290. * 时间                        :        2018-01-03
    , @1 ~% r8 y9 }1 t/ `
  291. * 最后修改时间         :         2018-01-03
    : j3 L7 o! u9 d
  292. * 说明                        :         地址请不要超出范围9 V& Y4 {8 m2 b8 h. L. l
  293. *************************************************************************************************************************/
    + T$ |) r* G# ^# K
  294. u8 STM32FLASH_GetFlashSector(u32 faddr)
    ' d# e$ ]  `# H8 L1 f
  295. {% r, ?" I1 d+ K3 U- e
  296.         if(faddr<ADDR_FLASH_SECTOR_1)                return 0;
    + }! n; O3 E& ~+ z+ t; Z6 M
  297.         else if(faddr<ADDR_FLASH_SECTOR_2)        return 1;6 x1 f4 g( t2 K# \8 I6 O! u
  298.         else if(faddr<ADDR_FLASH_SECTOR_3)        return 2;
    $ p, H9 Z" f/ V$ t- ?# q
  299.         else if(faddr<ADDR_FLASH_SECTOR_4)        return 3;
    : F+ Q7 P- Y9 D* }7 f' @6 _7 f# F
  300.         else if(faddr<ADDR_FLASH_SECTOR_5)        return 4;
    , S( n& o" W3 y1 @. c0 q! L, b
  301.         else if(faddr<ADDR_FLASH_SECTOR_6)        return 5;# m" H+ M4 \5 j! f3 i" J2 L
  302.         else if(faddr<ADDR_FLASH_SECTOR_7)        return 6;. w0 K$ X* B9 @% U7 h0 U/ ]7 \
  303.         else return 7;        
    8 e1 ]  Z5 f# b, \* T
  304. }# F+ d- {+ W+ s

  305. $ |$ _- c/ R, Q( V

  306. - b2 w6 o' `8 q7 L" q- x( v$ e
  307. /*************************************************************************************************************************8 S/ N7 Y- E6 i/ @+ C
  308. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  
    & y, B% s; Z" v: z" N6 ]
  309. * 功能                        :        不检查的写入
    $ Q, q7 s$ O5 j0 C& M
  310. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数
    2 i3 W) D7 f9 C- Z! a9 O# y
  311. * 返回                        :        状态
    ! S# K$ y) T" |5 H; \
  312. * 依赖                        :        底层
    * O0 d! q+ y5 H1 U  p
  313. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>' b1 Y7 Q7 \$ v5 l- B6 o$ h
  314. * 时间                        :        2013-10-20) u' k( e/ v8 L% U7 Q: b, \
  315. * 最后修改时间         :         2018-01-036 b6 H8 z( x0 ~7 O; _: |
  316. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)
    4 f2 ?" n. Z) v/ S% z- ?1 `
  317. *************************************************************************************************************************/
    $ z$ ~, r- w& m
  318. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   
    4 X9 g7 n  s2 F8 ?7 t: G1 |$ e
  319. {                                          
    ! l7 ~% J0 o( X8 b
  320.         STM32FLASH_STATUS status;
    / b$ W( y' ~' K& r3 U& p4 P
  321.         
    ! ^4 z9 f+ \' x4 J: f; F' G$ h
  322.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误
    # M/ h. s" Q2 ?% _/ ^" l
  323.         STM32FLASH_Unlock();                                                //解锁
    % `7 D% S/ ?: d, i/ o3 l- M
  324.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现, Z& ~3 m3 c0 E. \6 _
  325.         {: H5 W& O6 ]1 g) g) J1 Z  s8 h
  326.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);4 \+ H  F6 m- O& Z: G( z3 U& @3 a
  327.                 FLASH->SR |= FLASH->SR;  Y& t# E! p/ s6 X
  328.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);$ K( ]$ J" g) L% ~  k# n
  329.         }2 ~! S% V0 y* H6 B' m) I$ q
  330.         status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据0 M; Y9 B' h0 O; b4 l9 X1 }3 S. ]
  331.         STM32FLASH_Lock();                                                        //上锁
    , C6 h% Y8 c6 t' C! S
  332.         return status;* l; _  L0 [  [) f
  333. }
    3 h# w5 Y/ [1 o/ ^9 L* C
  334. 2 v- j3 O$ Q& b2 V% T% ?: W' Q6 c( l
  335. ( {$ `9 f: V3 N3 O2 h' y
  336. /*************************************************************************************************************************
    $ b8 i; j5 P& v
  337. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   # P1 y- `0 l+ n* i6 O+ Y& m
  338. * 功能                        :        不检查的写入一个字
    6 {5 [$ K! O8 I, p* e6 c% Y
  339. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);data:要写入的数据值. K) K6 T  f* _$ k
  340. * 返回                        :        状态
    1 h9 Y8 X3 b$ g+ L7 @( y) ]
  341. * 依赖                        :        底层7 _2 N" J6 i& z$ q7 Y) L/ z3 h
  342. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    # A8 m8 u9 |: k) }9 X# L
  343. * 时间                        :        2020-02-08* O  g% \3 b0 f
  344. * 最后修改时间         :         2020-02-080 ~6 e$ u" T! Q$ G4 ^, k: A+ A( @
  345. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)8 ?& l3 o& w/ D$ M
  346. *************************************************************************************************************************/, U, I3 W, t- }" {$ T# ?
  347. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   
    + v- l- H4 M9 l
  348. {                                          
    . B9 W9 F9 g( T0 Q! t0 Q
  349.         STM32FLASH_STATUS status;% N. W( H$ v3 R- o
  350.         4 c6 m% n4 x( H
  351.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误
    & J: N. V4 O5 M* X2 j; r
  352.         STM32FLASH_Unlock();                                                                                                        //解锁
    ( u2 h5 h2 L3 X* K
  353.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    0 n, J* X6 b3 F+ z1 N! p
  354.         {
    * y7 u! E# v: R) C3 I6 n  ]
  355.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    - j% l- q2 R  I% h5 y& B* @
  356.                 FLASH->SR |= FLASH->SR;
    " f+ _: @# }; |) Y
  357.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);1 o2 Z/ p; ~7 w: ]0 w
  358.         }# M4 T7 k  V8 x7 x6 ^
  359.         status = STM32FLASH_WritedWord(WriteAddr, data);                                                //写入1个字的数据
    " L6 k" L* n  B$ g
  360.         STM32FLASH_Lock();                                                                                                                //上锁
    7 x9 v4 v, \; c. G: j
  361.         return status;
    0 x( N7 y& t4 j" ^9 u6 M) h
  362. } ) x# ]( h( O! u9 h$ Z% j/ p/ O

  363.   ^7 z# g1 o# p! ~8 v1 Q" r

  364. 3 F& G  |: ]% t' V) g  L9 R& g& V+ s
  365. /*************************************************************************************************************************; H8 r+ S' B! C" C# ^
  366. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        ' s6 l3 G. Y- ~9 M8 d+ o
  367. * 功能                        :        从指定地址开始写入指定长度的数据(数据长度字为单位)/ `' r! z) o2 ]# ~1 L; u
  368. * 参数                        :        WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
    % p5 d3 A: K( w
  369. * 返回                        :        0:完成;1:忙;2:错误;3:写保护
    ) D0 R# ]! C6 E" O# v3 Y" y
  370. * 依赖                        :        底层# B9 k0 U' z6 z
  371. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    4 V: ?6 Y7 p" ~+ n: ?3 |
  372. * 时间                        :        2013-10-20
    ( ?  d4 ^1 [! o$ @5 k$ ?
  373. * 最后修改时间         :         2016-01-07
    , G1 w' n' @0 j; w
  374. * 说明                        :         警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据
    + ^5 t& I0 n+ O" e3 @# P4 d$ s- U$ Z
  375.                                         如果需要保存其他的数据,请在应用层进行实现(比如:先读取扇区,修改扇区,擦除扇区,写入扇区,需要大内存支持)
    7 u) Q# Y; U( y9 F- L% o
  376. *************************************************************************************************************************/ * N9 r# j5 W2 ~8 _9 {, z  U* J
  377. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        8 N( s8 \/ X6 U: W' w
  378. {2 G2 S- D$ n, `  o) I- ]# M- W+ m
  379.         STM32FLASH_STATUS status;' P. j" e0 V( t
  380.         u32 addrx=0;
    . Y/ O5 \- t( E; V
  381.         u32 endaddr=0;        % N7 B% R0 E; r
  382.          
    ) B3 g$ f4 V0 u" Z6 m. M
  383.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR;        //非法地址* R  I5 `" C4 i& S' y
  384.         4 |! I# a7 X! J8 E! \
  385.          FLASH->ACR&=~(1<<10);                                                                //FLASH擦除期间,必须禁止数据缓存!!!搞了我两晚上才发现这个问题!1 ?: I( I, O6 K8 e" a$ ~. l' }) A; r
  386.         addrx=WriteAddr;                                                                        //写入的起始地址# _4 Q; J2 s  D1 y: @6 X
  387.         endaddr=WriteAddr+NumToWrite*4;                                                //写入的结束地址
    9 Q: ~. j/ v$ f$ B0 e: ^
  388.         ( s! i, r  A, i3 D
  389.         if(addrx<0X1FFF0000)                                                                //只有主存储区,才需要执行擦除操作!!& \+ N  }% `( W5 T$ r% o! u* H/ O
  390.         {  ~5 Z1 G) r6 Y. `9 X
  391.                 while(addrx<endaddr)                                                        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)* I: V+ a% b* i9 r2 R% y
  392.                 {7 p' Q4 b/ `$ T5 a# J, `
  393.                         if(STM32FLASH_ReadWord(addrx)!=0XFFFFFFFF)        //有非0XFFFFFFFF的地方,要擦除这个扇区+ ^% u) _4 ?9 p8 R; P; }* ~
  394.                         {   
    2 r/ X2 z! T. L! W
  395.                                 status=STM32FLASH_EraseSector(STM32FLASH_GetFlashSector(addrx));
    8 T' [( m5 j1 u7 ~) g; H! \
  396.                                 if(status != STM32FLASH_OK)break;                //发生错误了7 |) c; [+ h( [5 |2 ^, w6 y. z
  397.                         }else addrx+=4;
    " T( H9 X/ Y) A
  398.                 } ) q8 b- ?4 d3 D3 U
  399.         }
    : c( S1 s4 ?" p3 ]7 f2 k% Z/ s
  400.         if(status==STM32FLASH_OK)
    9 Q: b6 {  _' f3 {! C  x( |+ L
  401.         {
    ; s0 K, l- N" y' Q/ L7 c6 h% g9 G1 }
  402.                 STM32FLASH_Unlock();                                                        //解锁
    3 {2 d0 b1 _4 ^: V/ P
  403.                 if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    : o% y/ ]1 F* j- m# |# ]
  404.                 {( K! i2 [0 G6 l9 D0 v5 j
  405.                         DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);7 f! |% a. F8 }8 D( B
  406.                         FLASH->SR |= FLASH->SR;) v9 r# a% h/ e8 o
  407.                         DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);6 h& v0 H/ S' g
  408.                 }. @- t' ]$ `. I1 w! n
  409.                 status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据) k, K  d  T8 x) Y' Z$ t0 j
  410.                 STM32FLASH_Lock();                                                                //上锁
    8 d# H* ?- B7 U$ j/ V5 ^) t
  411.         }! `4 C( i/ C" E4 @0 s
  412.         FLASH->ACR|=1<<10;                                                                        //FLASH擦除结束,开启数据fetch
    " L* D# O( ?' \/ n# B. v6 j
  413.         4 v6 B- @1 q7 r/ @/ O# q% L! d
  414.         
    $ q  v8 @( W( J; [1 w' _* r
  415.         return status;
    ) e9 S4 M' X% \8 V) K8 W
  416. }) {9 V" ]: v% v, i# z% B) v
  417. + q4 I0 p" J% Y* H/ k# r1 q
  418. * Z! t% ^. n+ m7 a% N& \( D
  419. # u  q- C7 N2 a8 S
  420. 4 u& M: C+ F) t: F8 r6 Y

  421. 2 `2 I) B" C+ `# I% z+ k+ j1 b3 d4 \
  422. /*************************************************************************************************************************
    3 }0 h4 O" Q2 P  H3 R7 F
  423. * 函数                        :        u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead) 2 ^- s4 W( W5 o
  424. * 功能                        :        从指定地址开始读出指定长度的数据; f) h8 f( K' u. O$ l* d
  425. * 参数                        :        ReadAddr:起始地址;pBuffer:数据指针;NumToWrite:字(32位)数
    - C. j+ B$ l/ Y: L
  426. * 返回                        :        读取的数据长度(字为单位)) l! J) _5 S/ v! O* u0 d
  427. * 依赖                        :        底层
    9 X. {; W! s: L0 t
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ! }. t3 D; U, M
  429. * 时间                        :        2013-10-20
    % {8 j% W+ c: Z% ^$ [5 r
  430. * 最后修改时间         :         2016-01-07
    : G. O) u, P! \! E* D  I
  431. * 说明                        :         地址必须为4对齐
    3 f/ J$ U0 K. O3 @9 i2 a: P; m
  432. *************************************************************************************************************************/
    / O# i4 \5 g7 d) g+ [8 z% ?
  433. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)           
    4 \  Q$ F. d9 l0 v4 A" q  k; `; X) e
  434. {
      l$ i& b, [8 {4 H* D
  435.         u16 i;
    ) v  N2 u  x/ M2 V4 E. Z% X' `
  436.         u16 cnt = 0;2 U3 z  j1 H; i  e
  437.         9 J, h- \1 y. i4 d# X6 N
  438.         if(ReadAddr<STM32_FLASH_BASE||ReadAddr%4)return 0;        //非法地址
    6 p- U3 V( r" ]! Y2 Z) {3 z/ O
  439.         * {9 h- y/ `5 O1 B9 o5 R8 W
  440.         for(i=0;i<NumToRead;i++)+ X. t' l7 J& }* _/ a: a9 j
  441.         {
    & E, u+ d( ~, F4 P6 Z. x# d
  442.                 pBuffer=STM32FLASH_ReadWord(ReadAddr);                //读取4个字节.
    / N( t- c0 O- Z" U1 D( _+ b
  443.                 cnt++;
    ! \% f. E& B! h- f2 r
  444.                 ReadAddr+=4;                                                                        //偏移4个字节.        3 U9 `/ r* X% M  z" M5 V$ e
  445.         }! d" v; ?& }3 m# y$ A) q$ A& a
  446.         return cnt;
    & ^0 G6 k0 }0 q$ s& q; W
  447. }$ x! A  [6 ]: c( W

  448. # h) i: I) F+ p' f; l3 Y

  449. ! M: H2 X, k1 z8 A5 @
  450. /*************************************************************************************************************6 ^, K' l) ~" I9 M! Z% K
  451. * 文件名:                        stm32f7_flash.H. b: |* X* f, g+ N8 w: L
  452. * 功能:                        STM32F7 内部FLASH编程驱动函数
    0 `. |5 C( z- H0 p% ^$ l. Q% s
  453. * 作者:                        <a href="mailto:cp1300@139.com" style="">cp1300@139.com</a>7 Y4 [2 @1 U9 o! r; K
  454. * 创建时间:                2013-10-20
    ; A+ B3 F: L) m% N5 M% m. Q
  455. * 最后修改时间:        2020-02-07
    ! M; R$ z6 L# p5 c9 D) P; S& B
  456. * 详细:                        用于STM32F7内部flash读写驱动8 R9 K! R- d  e  R# `8 D2 V
  457. *************************************************************************************************************/! \9 Y# J0 [$ C- W1 v+ y2 F  x
  458. #ifndef __STM32F7_FLASH_H__
    5 c5 @2 L! `3 `; z) P$ j4 _8 a  Z
  459. #define __STM32F7_FLASH_H__
    9 s0 O7 T* ^+ D* F. ^# H- U1 l6 B
  460. #include "system.h"  
    ( Z6 `9 l# o, B% L
  461. 3 I! k) Z+ k5 y5 F" j3 F# \
  462. //FLASH起始地址
    / s. r9 Z% X& F. R
  463. #define STM32_FLASH_BASE                 0x08000000                         //STM32 FLASH的起始地址
    & `/ Q1 m, {5 u. m8 O$ b+ l
  464. ' f3 X% q6 T) D+ N& t& c
  465. //FLASH 扇区的起始地址
    9 a1 u8 O' K5 M$ G
  466. #define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)         //扇区0起始地址, 32 Kbytes  
    1 I5 }/ [8 t+ b' Z8 m& d
  467. #define ADDR_FLASH_SECTOR_1     ((u32)0x08008000)         //扇区1起始地址, 32 Kbytes  
    ) U% W- t5 f% _3 Z$ k
  468. #define ADDR_FLASH_SECTOR_2     ((u32)0x08010000)         //扇区2起始地址, 32 Kbytes  8 T$ f, g, x8 s" h6 C2 E1 z; E! d) V! o
  469. #define ADDR_FLASH_SECTOR_3     ((u32)0x08018000)         //扇区3起始地址, 32 Kbytes  
    4 s8 }; ~' x5 ?2 y9 [' E7 ]
  470. #define ADDR_FLASH_SECTOR_4     ((u32)0x08020000)         //扇区4起始地址, 128 Kbytes  6 Q% \! M' _. Y+ k. I
  471. #define ADDR_FLASH_SECTOR_5     ((u32)0x08040000)         //扇区5起始地址, 256 Kbytes  
    * I0 s7 A4 A: Q+ d5 Q, E# a
  472. #define ADDR_FLASH_SECTOR_6     ((u32)0x08080000)         //扇区6起始地址, 256 Kbytes  
    & |  k8 Z* w4 g
  473. #define ADDR_FLASH_SECTOR_7     ((u32)0x080C0000)         //扇区7起始地址, 256 Kbytes  8 [# W5 _) T, `; M! V4 q3 z/ Y
  474. : q9 j8 w" |; J) W

  475. ' u# Y( M# m7 Y% A' K9 [" B. b
  476. //FLASH解锁键值& Y5 @% [/ N# X, G" x; w; H
  477. #define RDP_KEY                  0x00A50 y) A8 G0 W) K: ?  p8 T
  478. #define FLASH_KEY1               0X45670123
    - A0 h; [0 I  M) G3 U/ N8 F; v( H
  479. #define FLASH_KEY2               0XCDEF89AB
    5 A+ Z* N8 M  d
  480. #define FLASH_OPT_KEY1           0x08192A3B
    0 T+ c; K0 u4 y' ~8 b9 V
  481. #define FLASH_OPT_KEY2                         0x4C5D6E7F
    1 K1 [3 G/ K+ k

  482. ; m6 W$ O* P3 W, ~
  483. //STM32F7 Flash操作状态+ Y$ H+ A3 E4 {9 c3 [
  484. typedef enum  c3 B0 N2 y* G7 ?5 Z6 e0 F7 g
  485. {
    8 V. E5 y8 G: X& K
  486.         STM32FLASH_OK                        =        0,        //操作完成
    6 M* n* y; Z: @1 j
  487.         STM32FLASH_BUSY                        =        1,        //忙! o% ^9 I) s2 q& U, H* j& N( C; J
  488.         STM32FLASH_WPRERR                =        2,        //写保护错误) ?$ o; ]( a. s
  489.         STM32FLASH_PGAERR                =        3,        //编程对齐错误,必须128位对齐
    4 d9 ~" a. [, \; h3 }% i
  490.         STM32FLASH_PGPERR                =        4,        //并行位数错误
    ) J# j. a; o$ O# H& d
  491.         STM32FLASH_PGSERR                =        5,        //擦除顺序错误
    ; L, Y5 V8 p4 a
  492.         STM32FLASH_OPERR                 =        6,        //操作错误
    - u& ^% A& H- D; b9 }
  493. }STM32FLASH_STATUS;, h6 @4 x  E' S' C' b; {

  494. 7 E7 E2 e0 o; d
  495. //常用接口6 S7 G0 U4 x# K" A" O$ @8 b# e2 ?9 Y
  496. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr);                                                                  //擦除扇区: s: a, |# _( A1 f' |! I' ?
  497. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite) ; //不检查的写入多个字的数据, e9 l; X* f( ]- n' E% Y- u7 D: R& q
  498. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data) ;                                //不检查的写入一个字的数据2 H5 N: v) M/ H" r. g4 c1 @
  499. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite);                        //从指定地址开始写入指定长度的数据(数据长度字为单位)
    ( Y3 b$ i- Q, y! A+ _8 j. i1 F5 K
  500. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead);                                                        //从指定地址开始读出指定长度的数据
    1 {' p" G8 l5 ^1 P
  501. 2 k* ^9 e! o' _, Z" r$ _
  502. //不常用接口
    & J, A. t, A9 \8 h# ]/ r! H
  503. void STM32FLASH_Unlock(void);                                                                                                                        //FLASH解锁9 s+ _7 a" E2 n' G6 A; H1 o$ f' U
  504. void STM32FLASH_Lock(void);                                                                                                                                  //FLASH上锁
    0 F( f- t/ O0 E& Q
  505. STM32FLASH_STATUS STM32FLASH_GetStatus(void);                                                                                          //获得状态' D! P9 d/ R) Y

  506. ; o- @; b2 ]0 C0 ^: q

  507. & G' Q. O, h$ N( [) i: B5 N8 i  C+ ^
  508. #endif        //__STM32F7_FLASH_H__' J; S* W1 {9 @, G

  509. 8 Z9 `: p6 z3 L0 N1 u7 f
复制代码

8 K, H; c( \0 k6 y
收藏 评论0 发布时间:2021-12-11 12:00

举报

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