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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
总体来说与STM32F4操作是一样的,就是扇区大小变化了,测试过程中发现当PG=1之后立即写入数据到flash会造成编程顺序错误,通过增加一个nop的延时即可解决此问题,还可以通过将多个数据连续烧写的方式避免此问题,就是当PG=1之后,把所有数据都烧写完成后再将PG=0,不要频繁的开关。
0 u$ ^  q0 r  D' E6 w9 P
  h. S$ F4 j& b
  1. /*************************************************************************************************************
    7 R4 O  m& W6 Y. ~) p9 R) q
  2. * 文件名:                        stm32f7_flash.c
    5 b9 a/ N% X$ Q
  3. * 功能:                        STM32F7 内部FLASH编程驱动函数
    8 o! p/ u8 C9 R) d, J& i* X- w
  4. * 作者:                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>- {: }& L8 F/ Z/ ^; k
  5. * 创建时间:                2013-10-20
    3 h1 C6 {; f$ i: |8 h
  6. * 最后修改时间:        2020-02-07
    ; \1 M' g% @) F: b2 n7 b, h9 ?
  7. * 详细:                        用于STM32F7内部flash读写驱动: C- k+ V' D7 z  g6 l
  8.                                         默认为3.3V供电,并且宽度为32bit;4 L. T, g8 w, A$ m7 q
  9.                                         扇区擦除最长时间:32KB扇区500ms;128KB扇区1.1秒;256KB扇区:2秒: p3 J" e0 C  M3 J9 S2 w
  10.                                         修复STM32F7开始写入数据时,PG=1后没有延时导致异常,增加批量写入多个字的数据函数STM32FLASH_WriteMultipledWord()支持。' C8 L+ x7 ]+ s; @$ N5 `1 Z
  11. *************************************************************************************************************/
    ! }/ \# d0 A  d& R: n/ k# p  e
  12. #include "stm32f7_flash.h"
    ; R: T$ d% `% W& V
  13. #include "system.h"
      O0 o9 }* z4 l, H: }5 Y; }
  14. #if(SYS_WDG_EN_) //使能了看门狗0 O3 B! F( p4 T( ?1 S
  15. #include "wdg.h"
    ' k: Q  O) B& W/ a- B% Q
  16. #endif //SYS_WDG_EN_
    ; U% y! U" d8 a0 @

  17. , `( [9 L: k! j; `, }' o- v

  18. - I! k  p0 D0 I
  19. 6 S: W4 r) ]4 e7 X$ M4 e8 E
  20. 2 C% v) D2 r6 x4 G: L3 s
  21. /*************************************************************************************************************************
    6 C' l1 V0 s$ R  g; v
  22. * 函数                        :        void STM32FLASH_Unlock(void)
    # D: v9 _& k. k" h  c1 _4 P) b
  23. * 功能                        :        解锁STM32的FLASH
    4 a  T8 \4 J$ u) D0 C
  24. * 参数                        :        无
    ! _  Y+ P4 H$ s7 t! @2 i7 |0 g
  25. * 返回                        :        无
    3 b7 [; }* G' r) B0 ~5 W, v4 K" x6 w
  26. * 依赖                        :        底层. D2 I7 S9 \# ~: Q
  27. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>* T: ^6 _! O" P/ }  X
  28. * 时间                        :        2013-10-20+ W. `* s) E# _" X0 t/ w) [
  29. * 最后修改时间         :         2013-10-20
    ( u/ u9 C9 }, ~, i: Y4 j9 C8 x+ H
  30. * 说明                        :         ' d* O* o7 `* m, I
  31. *************************************************************************************************************************/+ U2 Q% W$ Y/ v" M0 g6 l  d) m5 c4 I( ?
  32. void STM32FLASH_Unlock(void)5 A9 z2 `3 A; V! o; w# j! |
  33. {! m8 i2 s6 H9 w' ^
  34.         FLASH->KEYR=FLASH_KEY1;        //写入解锁序列.
    * T4 v8 L( [2 P5 W( Q
  35.         FLASH->KEYR=FLASH_KEY2;- Z7 |9 Z6 `" @( a1 J9 U1 {
  36. }
    ; Z7 w; y" V, ?7 b+ |4 ]
  37. ' ]: A# g$ e2 N" E
  38. - `/ N. F; |$ ^

  39. 0 v* b6 J+ c( F9 K" k% i2 c* t
  40. /*************************************************************************************************************************
    % f5 h/ l; L, I' {
  41. * 函数                        :        void STM32FLASH_Lock(void)+ C9 C& j( k( E& f
  42. * 功能                        :        上锁STM32的FLASH
    4 n5 [& p: D4 p2 z
  43. * 参数                        :        无5 \  ^: r9 q* E. X' ?. k- z
  44. * 返回                        :        无! B, g, }9 E% O4 ^8 U! c
  45. * 依赖                        :        底层8 i* q3 E/ n% g' g* d: V: Z4 r
  46. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    , ~; Z0 s; D! ^; ^
  47. * 时间                        :        2013-10-20: R, A4 j$ m: X% J* Q! a
  48. * 最后修改时间         :         2018-01-13
    7 w' C- {1 B7 P" R; S0 o
  49. * 说明                        :         ) V) |5 {- ^5 L7 f$ w
  50. *************************************************************************************************************************/  D5 ]6 [9 @5 X1 Z+ l. P
  51. void STM32FLASH_Lock(void)7 \/ K- o) P/ R
  52. {$ W6 G2 A# Q- G# ^2 _" G$ K
  53.         FLASH->CR|=(u32)1<<31;                        //上锁
    7 ~* n5 w( x/ p5 X
  54. }
    & i7 j  D6 v0 r& O5 `9 m5 \+ W% j

  55. ; b3 T% m  N* x& R4 [4 W
  56. , {# Q  i" v6 R  z+ w

  57. 0 k1 A! v9 D/ J. `4 t2 ^% W+ r
  58. 6 G. E4 I5 G' b9 `& r3 Q# @2 f
  59. /*************************************************************************************************************************& P! W2 E  k4 F9 d
  60. * 函数                        :        STM32FLASH_STATUS STM32FLASH_GetStatus(void): R1 k7 c; T2 y5 c8 T8 S- R" Q
  61. * 功能                        :        得到FLASH状态
    ( d) k; \- D, c- c3 h+ e$ N
  62. * 参数                        :        无
    + }2 h+ I5 C( J4 M
  63. * 返回                        :        STM32FLASH_STATUS7 E4 t+ n" J6 x. {# N
  64. * 依赖                        :        底层
    & t/ ~, z6 I  R( C
  65. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>8 r* |* m) |6 D/ X6 `
  66. * 时间                        :        2013-10-201 Z, B# m0 p! |( {0 B
  67. * 最后修改时间         :         2018-01-034 z- v9 j5 k* i& [1 e
  68. * 说明                        :         0 f/ w" ?: {; S9 H6 [* X- r
  69. *************************************************************************************************************************/0 E1 J% P+ D0 ], ^
  70. STM32FLASH_STATUS STM32FLASH_GetStatus(void)
    & F7 i8 `3 ]. c7 ~/ h" t
  71. {        9 {! S' g' {. O! p6 U
  72.         u32 temp=FLASH->SR;
    3 O8 d, c( G. G- m% P$ I: b
  73.         
    ) w4 L, f0 L& h, W$ o. I4 B
  74.         if(temp&(1<<16))return STM32FLASH_BUSY;                        //忙% J- W( U5 f, `0 h. Q
  75.         else if(temp&(1<<4))return STM32FLASH_WPRERR;        //写保护错误5 \" y" m7 m7 v# h, u
  76.         else if(temp&(1<<5))return STM32FLASH_PGAERR;        //编程对齐错误
    + S. ~8 @; r' v) k
  77.         else if(temp&(1<<6))return STM32FLASH_PGPERR;        //并行位数错误
    , f! P( h2 Y4 V* H
  78.         else if(temp&(1<<7))return STM32FLASH_PGSERR;        //擦除顺序错误
    5 N6 a" x7 E" G# M( o( G
  79.         else if(temp&(1<<1))return STM32FLASH_OPERR;        //操作错误
    : o( I" [: L' t0 e
  80.         return STM32FLASH_OK;                                                        //操作完成# p7 @/ b: p! _2 o
  81. }
    5 [, E% q7 s/ \  D# x) J! Y9 c
  82. - n# n$ S- j( G8 b- z' ?7 a
  83. ) C3 n% l; s5 I0 @
  84. $ r, h% r: ?+ L  u: r- s1 f5 D
  85. /*************************************************************************************************************************2 {' @- U) b! U1 M! G8 \- ~6 d" {
  86. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time)9 j+ u3 C9 ]" Q
  87. * 功能                        :        等待操作完成
    3 T0 B+ N: ~% _: @* r" Z* c/ s6 s
  88. * 参数                        :        time:要延时的长短,单位us
    2 L8 W' j' n) b( k; s# m
  89. * 返回                        :        STM32FLASH_STATUS
    5 b6 D6 @8 E$ H
  90. * 依赖                        :        底层+ D# y) V+ }% d1 W7 G* ^: y
  91. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    , [. Y1 y( E8 M4 z1 _
  92. * 时间                        :        2013-10-20" H3 F. @1 b! L; t! O
  93. * 最后修改时间         :         2018-01-038 c7 j" l* P( ]0 \: Z8 c* I: q
  94. * 说明                        :         2018-03-24:增加清除看门狗功能, [. M4 ~$ W8 G0 T& A! ~2 b
  95. *************************************************************************************************************************/! V1 `( [- q/ H/ e! D0 h
  96. STM32FLASH_STATUS STM32FLASH_WaitDone(u32 time), G( O% {, B8 U$ K
  97. {
    - i4 N5 a' G8 O- H, ^& z, P6 Y
  98.         STM32FLASH_STATUS status;4 n* f  I! D1 y4 V2 }
  99.         : N& }4 L" w1 F* g: b5 b0 ~
  100.         if(time < 1) time = 1;
    / B8 X2 q# i7 \& b
  101.         do
    / g9 _" y" m( }) C
  102.         {- U0 A% b& F4 N8 l9 ?" P
  103.                 status=STM32FLASH_GetStatus();                        //获取状态
    ; U2 S1 u% l1 k' k$ C! U+ `
  104.                 if(status!=STM32FLASH_BUSY)break;                //非忙,无需等待了,直接退出.& b  c  u- h" Z8 ]6 X- }, q$ b
  105.                 Delay_US(1);
    % k4 x7 Q1 v4 J. _
  106.                 time--;3 B& U1 c. `7 a  o5 D! A7 w1 ~
  107.                
      ~) u" e" k0 w/ T( ~) e3 z
  108. #if(SYS_WDG_EN_) //使能了看门狗
    6 b* @8 {5 L+ a
  109.                 IWDG_Feed();8 D4 R& p" L0 ?  {+ V
  110. #endif //SYS_WDG_EN_        
    . O/ k0 d* [- V) p, W& w
  111.                 0 [) f5 Q- F" t0 C5 L
  112.          }while(time);+ D3 M& [% q- \- R5 q

  113. 0 m& A+ ~9 ^) m6 h  x
  114.          return status;' S( G4 h/ `* c6 X4 N9 F9 V: Q
  115. }5 S; b- G1 N. `* p
  116. + Q4 ^0 q9 u4 s( S9 J

  117. $ B2 T6 u3 U, E

  118. 8 U' v$ n" p7 D% X- B
  119. /*************************************************************************************************************************
    & C/ g1 N& ?/ q0 D  i7 [
  120. * 函数                        :        STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr); @- k4 I7 o+ z3 v  h1 X8 n  u  r
  121. * 功能                        :        扇区擦除
    4 r! T6 r0 C8 B1 e
  122. * 参数                        :        sectoraddr:扇区地址,0-11
    ! H' ~/ w3 ?6 L
  123. * 返回                        :        STM32FLASH_STATUS
    * z# W) n- z$ D8 x& E
  124. * 依赖                        :        底层! c6 a3 \3 Q1 }; o
  125. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>, H4 y7 [1 c3 ?
  126. * 时间                        :        2018-01-03
      x4 K) d' e6 Q. m4 \' J
  127. * 最后修改时间         :         2018-01-03; e* E2 l  J$ f
  128. * 说明                        :         扇区大小:0~3:16KB扇区;4:64KB扇区;5~11:128KB扇区% |: c8 H7 ^' [6 z# v
  129.                                         128KB扇区擦除足最大2秒
    / N' E9 r/ l" T, N7 P& w
  130.                                         2018-01-16:修复扇区擦除时没有解锁问题( y( S( _" X8 k* V
  131. *************************************************************************************************************************/
    7 [# d& o* s8 h, v$ D. A4 m, k6 H
  132. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr)* E# |8 c  w# @5 C$ Z. d- f
  133. {$ H2 m3 ^3 R; x
  134.         STM32FLASH_STATUS status;, f4 \0 c$ K: s# h& @
  135.         ) t: l1 X+ |! W! ?" u7 G
  136.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现
    * w7 a8 j, a8 L
  137.         {
    5 l) @& y- V! G! S+ P- w- ?4 r
  138.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    . s  G+ Q& h) w9 _9 u$ ~
  139.                 FLASH->SR |= FLASH->SR;2 e! d6 E( ^  L* Y: Z2 _
  140.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);* N5 ^- z! B1 c3 ?
  141.         }
    3 W, {- r. m; `, p# o
  142.         6 v5 w$ V0 h2 ]# P- Y
  143.         status=STM32FLASH_WaitDone(2100000);        //等待上次操作完成,最大时间2秒,如果已经操作完成了会直接跳过: ^& X! F% D  u! |6 o9 @+ ~
  144.         # W& `) m- W& u" u2 Z  ~
  145.         STM32FLASH_Unlock();                                        //解锁 3 a3 s6 z# s, Q. o* r2 h+ x
  146.         if(status==STM32FLASH_OK)                                //没有错误
    6 y& m- A! S1 k) h
  147.         { / v# q  _0 G+ j9 T
  148.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置2 l& [% z: y  v# R
  149.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    " {6 E# `7 N! P- [5 l
  150.                 FLASH->CR&=~(0XF<<3);                                //清除原来的设置
    + u, x8 s; D7 x$ {5 N8 ]% f
  151.                 FLASH->CR|=(sectoraddr&0x7)<<3;                //设置要擦除的扇区 5 I4 a* R- y8 ]2 t& h0 t
  152.                 FLASH->CR|=1<<1;                                        //扇区擦除 ) C+ A$ [# l, {1 L4 ^
  153.                 FLASH->CR|=1<<16;                                        //开始擦除) C, g: c9 H, q. N* r' Q& s
  154.                 status=STM32FLASH_WaitDone(2300000);//等待操作结束,最大2s  
    + }) q6 A1 Y8 K0 s- G9 q% P
  155.                 if(status!=STM32FLASH_BUSY)                        //非忙9 u5 G$ g1 p& h7 c
  156.                 {* Y$ l3 S+ \) z/ T7 o: H% e
  157.                         FLASH->CR&=~(1<<1);                                //清除扇区擦除标志.2 d  o0 i9 G, L: k) V% c
  158.                 }
    5 `1 I+ R8 T$ v% q3 \
  159.         }
    3 `2 x$ ?' e1 K. i0 K5 H0 X
  160.         //DEBUG("扇区擦除状态:%d\r\n", status);# M* m- \$ Z7 x2 t" z8 R
  161.         //DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n", FLASH->SR, FLASH->CR);, O$ O( e, \4 P# w( [" S
  162.         ( l$ R2 p/ _3 c& ?) {+ }
  163.         STM32FLASH_Lock();                                                //上锁
    7 q2 C# t1 l  ?7 E1 [3 u6 g
  164.         if(status != STM32FLASH_OK)
    ( m. g) b' |; ^' ~
  165.         {
    3 \: h: ~, V7 k" G: b4 \0 Y8 m
  166.                 DEBUG("擦除扇区%d失败(错误:%d) FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",sectoraddr, status, FLASH->SR, FLASH->CR);; r  T7 q/ c* ?4 O4 {$ f1 N6 x% C+ ~
  167.         }
    : q" b0 E  M& P- h6 f6 H0 R- N) j
  168. . c2 ?! j5 H% M% K
  169.         return status;                                                        //返回状态0 [8 z* t3 \5 h, `
  170. }+ u1 x: K6 m( t' R# {

  171. 8 o; t+ E3 B9 d- \
  172. - H# F( O9 F! O( v
  173. - }% {6 V, }. V- @% Y" b
  174. 5 i. C5 Z4 p& C% [& A& D6 k
  175. /*************************************************************************************************************************
    * T  b/ C8 ?1 r! G1 n
  176. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)) V: \0 H8 l: B- K0 g" h9 [
  177. * 功能                        :        在FLASH指定地址写入一个字的数据(32bit写入)6 N  B6 B* y6 I" g0 u3 ?
  178. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);data:要写入的数据
    $ J) F, i6 B# o8 ^8 ?5 X3 `5 Q
  179. * 返回                        :        STM32FLASH_STATUS' L, Z5 f( c# u
  180. * 依赖                        :        底层4 M. E1 B, l4 ]8 C) z1 Q
  181. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>" Y$ w( V9 i5 V# @7 u
  182. * 时间                        :        2018-01-03& E5 k0 K6 Y9 W, I3 @- v+ ?: ^( Q
  183. * 最后修改时间         :         2018-01-03. ?$ O. d, c6 p2 B
  184. * 说明                        :         警告,地址必须为4的倍数, n' m: y0 L  A4 a& |3 p) S
  185.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    : K0 T6 l0 l; o
  186.                                         不会判断是否能写入# R2 f& n6 ~+ o  \0 G+ V" Q
  187. *************************************************************************************************************************/
    + y0 Q; k& r  n( d- ~
  188. STM32FLASH_STATUS STM32FLASH_WritedWord(u32 faddr, u32 data)( U% E8 _' O* u* m6 ?9 O7 u
  189. {, k' D& `: J# o- P2 z' f1 [/ F( E2 l
  190.         STM32FLASH_STATUS status;
    0 K9 z$ X1 Y# }4 K. \- l" w
  191.         , M- y  m! D5 y4 d% G" l
  192.         status=STM32FLASH_WaitDone(200);                 //判断状态1 k- Q# [5 f! j, x# S
  193.         if(status==STM32FLASH_OK)                                //没有错误
      e5 t5 ^; Q3 Y3 c0 X# f3 G
  194.         {1 k  B6 r3 q1 c) D5 B
  195.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置, n/ `. {/ ^4 K
  196.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
      `. ]4 P/ ^% b9 P
  197.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误8 |& T1 z- N. H; Z* y* F' {: h) K. O
  198.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    + K; ^5 k( F3 N1 O" V
  199.                 *(vu32*)faddr=data;                                        //写入数据* H, u! d7 p( P7 g+ F  r1 K
  200.                 status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.3 R3 v/ s6 D: v' w4 N& `, ^
  201.                 if(status!=STM32FLASH_BUSY)                        //非忙% r- ^) X9 W8 T. K+ ?8 O
  202.                 {        + F- x! H9 P) }! d& R! F5 `0 s
  203.                         FLASH->CR&=~(1<<0);                                //清除PG位
    1 Y4 V. p4 F- [/ a$ g
  204.                 }
    ; |/ ^' S: ^6 ]
  205.         } 7 t+ ~3 J' Z4 \  L- D

  206. 1 V8 ]& }% g! x
  207.         if(status != STM32FLASH_OK)+ H5 `6 B1 ]2 W' O
  208.         {
    % \: N& |  Z, B7 V- [2 q
  209.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);/ v3 V9 |8 @3 l8 Q
  210.         }# ^% P- _  o" q+ ?; Y) v2 G) A
  211.         % B4 q* J1 E" E, Y
  212.         return status;0 g" Q' Q0 w( V( b6 M$ _. w
  213. }
    3 ~1 \$ ]' E8 f1 o
  214. $ t1 t( q, {1 k5 p$ U. w

  215. 3 Z; @% i1 k# _  z
  216. /*************************************************************************************************************************0 i% r) ~* K$ X0 d0 u0 g
  217. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)0 B- g4 N9 y  V, E/ e8 o  S
  218. * 功能                        :        在FLASH指定地址写入多个字的数据(32bit连续写入,提高效率)- }% a' K7 T2 }3 W. c' I( A# y- q
  219. * 参数                        :        faddr:指定地址(此地址必须为4的倍数);data:要写入的数据
    ( O: U9 R4 u# L0 {; q
  220. * 返回                        :        STM32FLASH_STATUS
    6 }( \; J* x9 F/ l0 I
  221. * 依赖                        :        底层- o& v5 f# z+ q6 b, ]
  222. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    6 ~, T, S) g: z; A- \7 ~0 ^
  223. * 时间                        :        2020-02-08
    , }/ Q& M9 ~2 W: ~4 H3 Z2 }4 a
  224. * 最后修改时间         :         2020-02-08
    6 Z8 F: g" G4 Z/ S! a) D
  225. * 说明                        :         警告,地址必须为4的倍数
    7 ~+ c/ k! Q& F% Y# w  X: ~( Q
  226.                                         2020-02-08执行PG=1须增加延时,否则可能出现顺序错误,不会执行flash解锁
    1 w' \, B' K+ t5 M4 j% t6 B+ }
  227.                                         不会判断是否能写入
    6 M! y8 s/ p/ g  C4 F
  228. *************************************************************************************************************************/$ E3 t7 Y! z7 r0 u; ^7 R# l7 d
  229. STM32FLASH_STATUS STM32FLASH_WriteMultipledWord(u32 faddr, u32 data[], u32 dWordCount)
    1 I0 _- F) ?7 a, X; r0 O! l$ \+ z
  230. {3 I" N' S" y" J9 _; j; p: _
  231.         STM32FLASH_STATUS status;7 ~, u' |; T0 y  `4 @4 [4 z

  232. 2 W* S; c' i: o
  233.         status=STM32FLASH_WaitDone(200);                 //判断状态' F( U  F, j6 U
  234.         if(status==STM32FLASH_OK)                                //没有错误
    , n, \5 F& h1 u- L/ u
  235.         {+ U) y; d/ C# j' [# R
  236.                 FLASH->CR&=~(3<<8);                                        //清除PSIZE原来的设置
    % b+ u4 {" l+ s  w* s3 v: o
  237.                 FLASH->CR|=2<<8;                                        //设置为32bit宽,确保VCC=2.7~3.6V之间!!
    7 ], m" O# G' S, |' c. y. _
  238.                  FLASH->CR|=1<<0;                                        //编程使能,测试发现使能编程后不延时会出现编程顺序错误
    1 h7 Q7 d6 O# G  U2 ^
  239.                 nop;nop;nop;nop;                                        //2020-02-08 此处必须增加延时,否则可能出现顺序错误        
    0 V7 B5 p3 i+ ^4 j
  240.                 while(dWordCount --)# z* _2 @- [2 I  S' j# k: Y7 t1 I
  241.                 {  L1 i3 _0 k& o* a* t: \. Z( v9 U, I/ z+ b
  242.                         *(vu32*)faddr=*data++;                                //写入数据
    7 N: A& Z+ t- i) {# x4 C* _: W5 \
  243.                         faddr +=4;                                                        //地址自增+40 s6 E; g/ f5 t$ f7 d! B
  244.                         status=STM32FLASH_WaitDone(200);        //等待操作完成,一个字编程,最多100us.
    $ @6 k" n& J) J, t9 s
  245.                         if(status!=STM32FLASH_OK)                        //有错误9 n- P- t. u3 h
  246.                         {
    : g1 n+ [& t$ I$ c* Q/ p
  247.                                 break;3 F, M, w$ p9 J+ N* E
  248.                         }2 y+ \5 z3 X. c; V, t
  249.                 }" m7 Y$ }7 Y7 b( O

  250. 4 [& d) c! q# s7 u4 B
  251.                 if(status!=STM32FLASH_BUSY)                        //非忙
    8 @- ?, {- K+ }# L: K
  252.                 {          k+ [- ]; Q0 D* L% f5 o* C: ]4 y
  253.                         FLASH->CR&=~(1<<0);                                //清除PG位
    - e# l. r) Y# \  R) ]+ \# S
  254.                 }5 S8 ~. V6 y3 e8 L. e1 P1 M
  255.         }
    : Z$ d- n% F2 i: W9 }4 ?
  256. 2 J1 s  l- s. ~
  257.         if(status != STM32FLASH_OK)
    $ t  k+ z! H+ y4 W- v2 U
  258.         {- o- y" u& ?) R) X
  259.                 DEBUG("FLASH写入错误(%d)FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",status, FLASH->SR, FLASH->CR);
    , O7 ?6 x  t0 w$ p# x
  260.         }4 Z% X' `: _1 g* J* C7 u& T+ y, o; ~6 ^
  261.         
    * h. G0 K  w3 ]# r
  262.         return status;- B, }, X2 M# S
  263. } 1 E% U) P; L9 M9 @/ V2 N6 P/ v+ `

  264. 1 }* ~: @1 m) y) o

  265. 5 q0 p$ O2 _0 w$ _3 V; ?8 a' ]. |
  266. /*************************************************************************************************************************+ m% V$ P0 n0 S  |4 @
  267. * 函数                        :        u32 STM32FLASH_ReadWord(u32 faddr)
    . V& j& d. D) \
  268. * 功能                        :        读取指定地址的一个字(32位数据) . }# V% L4 |) U/ [, S
  269. * 参数                        :        faddr:指定地址(此地址必须为4的倍数!!);
    , i' ?$ f3 r  S
  270. * 返回                        :        数据( F: ]& k7 N% [6 z8 A
  271. * 依赖                        :        底层
    / ~# o7 B2 |8 `
  272. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    9 N. S# Y! j1 f/ i9 t, }
  273. * 时间                        :        2018-01-03
    3 c+ k6 Z% F1 [' g
  274. * 最后修改时间         :         2018-01-033 l# |% m- ?7 Z( M" _; F
  275. * 说明                        :         警告:地址必须是4的整数倍
    / @! z3 J! j' {# ]; C" H
  276. *************************************************************************************************************************/
    ) d+ m5 E/ J* Q' }+ i
  277. __inline u32 STM32FLASH_ReadWord(u32 faddr)
    # T' z/ x3 h1 ^8 A5 ]1 M/ j
  278. {
    " d3 M3 \9 G" z! o' R+ c
  279.         return *(vu32*)faddr; ' h7 p. f1 ]3 V' a9 p# ^: X+ `0 L
  280. }1 R* j) Q# m6 h; K( \

  281. ; l: l7 O( D# |- D" Q
  282. & l6 r4 U2 e, E6 `6 I3 N# G
  283. /*************************************************************************************************************************# j2 C  G% `: X! v
  284. * 函数                        :        u8 STM32FLASH_GetFlashSector(u32 faddr)
    ( @8 R, L0 g, a
  285. * 功能                        :        获取某个地址所在的扇区/ a! k0 M; b9 W. A
  286. * 参数                        :        faddr:指定地址
    $ o+ E8 b  W  r% M' N9 d; y
  287. * 返回                        :        删除编号,0-6,如果超出了也会限制到6& |3 Y9 v& o3 [7 i
  288. * 依赖                        :        底层2 m1 z4 Z( s& u* z- ]7 H! `3 `
  289. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>' N3 l! h; I1 w: Q8 d( _" X3 ?
  290. * 时间                        :        2018-01-033 b: |2 U% F' h5 V. r4 [) ^
  291. * 最后修改时间         :         2018-01-03
    * A/ r/ c* T0 P/ r
  292. * 说明                        :         地址请不要超出范围$ e$ j9 Q9 R' C/ d  D% m
  293. *************************************************************************************************************************/7 u4 |/ Y$ l: X+ O1 c5 r- O
  294. u8 STM32FLASH_GetFlashSector(u32 faddr)
    * s) d/ d* G" y" |# p
  295. {
    ( [6 x+ Y+ b) ]$ x5 f7 F/ e
  296.         if(faddr<ADDR_FLASH_SECTOR_1)                return 0;3 C  F. C* C% V6 ]/ r5 I' A/ d2 Y
  297.         else if(faddr<ADDR_FLASH_SECTOR_2)        return 1;2 T, d* A, O. G  t( D1 `( L
  298.         else if(faddr<ADDR_FLASH_SECTOR_3)        return 2;
    . P3 t8 b* ?5 |& `
  299.         else if(faddr<ADDR_FLASH_SECTOR_4)        return 3;
    ! o( A( s# b4 Y2 K# x
  300.         else if(faddr<ADDR_FLASH_SECTOR_5)        return 4;8 O% |: u+ C- t$ K. q% L5 R1 {
  301.         else if(faddr<ADDR_FLASH_SECTOR_6)        return 5;
    : @, W) X$ n/ I$ d% G
  302.         else if(faddr<ADDR_FLASH_SECTOR_7)        return 6;1 W- p5 g4 `2 l9 v' v0 n" ?
  303.         else return 7;        / |0 B/ {: @  g: G3 x4 g
  304. }+ @( P( `- w) n! A+ l; X- S1 ]

  305. 8 G5 Z# \. p$ d* A+ Q; ?; F
  306.   g8 {1 O4 s: t- q4 h8 D" @+ Y& G
  307. /*************************************************************************************************************************
    6 P: W$ z! a8 n
  308. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)  
    - f/ O2 z% w- r& {# J  W
  309. * 功能                        :        不检查的写入
    1 \; f0 R9 Q1 X& U( @3 Z
  310. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);pBuffer:数据指针;NumToWrite:半(32位)数 - H  N4 c* l! U2 i- f
  311. * 返回                        :        状态) T) F) L8 u9 x8 N' q4 Q
  312. * 依赖                        :        底层5 N- r& F/ A/ p0 l) ~& r
  313. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    9 R6 K  e6 P8 X: G, ~
  314. * 时间                        :        2013-10-20
      J! k" r' A* L% ]8 c7 W/ l
  315. * 最后修改时间         :         2018-01-03
    , r4 g% Z3 _( E1 r; |$ g
  316. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)2 ]) v) r6 ~+ p7 N. Q+ v
  317. *************************************************************************************************************************/% M: V) f/ D6 i1 B0 u4 |
  318. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)   ! ]) c  g4 ^8 r' G7 c
  319. {                                           $ v! j4 @4 d( }* J
  320.         STM32FLASH_STATUS status;
      |! t1 h' C& ]1 ?: I
  321.         + `3 i) J( b3 v* G9 T% I( P
  322.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误
    3 p4 n7 b- F! Z) H5 p
  323.         STM32FLASH_Unlock();                                                //解锁 ; b8 Q, f- S! E3 g4 B, K* P
  324.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现( v2 C5 w) Y- b" l& V
  325.         {
    8 i- D) h, W' n  f9 X" r
  326.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);6 H! f6 D& U. g# D
  327.                 FLASH->SR |= FLASH->SR;
      i4 j8 b' ?2 n3 R0 ]$ O
  328.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    3 D" e* A3 M# I# T5 Z
  329.         }
    & I" ?/ K2 V7 F6 ^* ?
  330.         status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据1 M- |% V) k# E  X: N- l0 C
  331.         STM32FLASH_Lock();                                                        //上锁& k6 n) o" O0 Q4 E+ [
  332.         return status;
    ( W, E+ j- P1 I) y
  333. } . M( I0 a) ^- X

  334. 3 {9 ~/ r1 ?% T8 [1 t: L1 B
  335. . N+ u, z* s: R/ E. C
  336. /*************************************************************************************************************************% Y$ @4 W$ i, q' H8 O3 M( w
  337. * 函数                        :        STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   % W* t* ]% t. k& |2 L
  338. * 功能                        :        不检查的写入一个字
    2 g+ N& \+ Z1 E& X/ M* g/ h: s0 D
  339. * 参数                        :        WriteAddr:起始地址(必须是4个整数倍);data:要写入的数据值
    6 n) k$ ?* U9 C% ?( k  Q
  340. * 返回                        :        状态' T8 I0 J& N$ z
  341. * 依赖                        :        底层
    8 n. d% A7 C0 s5 I$ X8 D+ q6 w
  342. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>8 }! v6 f) h1 r
  343. * 时间                        :        2020-02-088 c. u2 Q0 O9 e, M% K$ N
  344. * 最后修改时间         :         2020-02-08
    / T# O1 [" }; Q1 v5 W
  345. * 说明                        :         地址必须为4对齐,如果出现了非FF写入程序会报错并返回(由于STM32硬件会对写入区域进行检查,非FF区域不允许写入)+ \" }0 x" p# z: y% A; Z# X" C
  346. *************************************************************************************************************************/
    1 U" e* R6 [; a5 o7 g; u/ T" r
  347. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data)   9 X0 Y9 E" ~# M7 @
  348. {                                           + ~) s1 E2 j9 }$ ?) l- e
  349.         STM32FLASH_STATUS status;; M/ M. Z/ v# x: M! t
  350.         
    " m. u# G8 N) i0 ~' E& D
  351.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR ;        //非法地址,如果不是4的倍数,返回并行错误
    , o) `+ S; b- [
  352.         STM32FLASH_Unlock();                                                                                                        //解锁
    ( y- F. h7 H) F  W
  353.         if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现6 v' O9 J2 z; o
  354.         {
    ! r! r# |3 W! o. F# ?- x
  355.                 DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);* O9 |/ v5 n8 m) s
  356.                 FLASH->SR |= FLASH->SR;
    - W6 @+ P; `( G5 f5 m% h
  357.                 DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    ( f2 S! X- x; v5 h
  358.         }
    7 V; }/ k  p6 f/ t6 [- {( Z* g
  359.         status = STM32FLASH_WritedWord(WriteAddr, data);                                                //写入1个字的数据; x  C' Q/ L0 n# E/ l4 D% N
  360.         STM32FLASH_Lock();                                                                                                                //上锁
    4 H7 l# b* X3 B( Y. }: v( `+ ~- ?
  361.         return status;
    - I/ b5 b# [% C% {* s* I
  362. } 4 ^. A; z0 t$ `2 L, E, O8 w9 B

  363.   @  }: T+ {* K# C$ d" ?

  364. / n; I& R. N6 r: D1 J$ x: p
  365. /*************************************************************************************************************************6 [0 L$ ?+ x% V9 c% v
  366. * 函数                        :        STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        : C- O& i8 Q* B
  367. * 功能                        :        从指定地址开始写入指定长度的数据(数据长度字为单位)& ]) X/ ^# _+ Q/ x8 L3 k1 G
  368. * 参数                        :        WriteAddr:起始地址(此地址必须为4的倍数!!);pBuffer:数据指针;NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
    $ V# R8 I5 L; K0 y4 ]
  369. * 返回                        :        0:完成;1:忙;2:错误;3:写保护
    5 g1 d( F9 r- R. l# D
  370. * 依赖                        :        底层, J) V5 ?5 ~% t5 O: T, h/ b
  371. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>, G) ?) ^  j& d0 v* f8 b
  372. * 时间                        :        2013-10-20
    ! d6 Y8 G3 e4 m* P
  373. * 最后修改时间         :         2016-01-07) N; R2 C9 B4 t$ x
  374. * 说明                        :         警告:由于STM32F4的扇区太大,无法使用内存进行缓存,如果要写入的位置有非FF,会直接将整个扇区进行擦除,并丢失其它的数据+ G6 m$ c" Y4 ]6 E6 d, h# D+ }
  375.                                         如果需要保存其他的数据,请在应用层进行实现(比如:先读取扇区,修改扇区,擦除扇区,写入扇区,需要大内存支持)" L7 G, D+ m% R8 ?4 i" Y% v, q
  376. *************************************************************************************************************************/
    , z4 a7 N4 s1 S5 t  j, K
  377. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite)        / v( _% t; Q4 u
  378. {
    + M( [1 ]$ {4 y, G6 L. b
  379.         STM32FLASH_STATUS status;
    ) J9 N( ^5 D3 U- v
  380.         u32 addrx=0;4 [1 P& r0 I8 Z0 q; U% x4 D. z
  381.         u32 endaddr=0;        
    . R. Q" |, k, k4 S! G5 V+ O
  382.           ' K8 a2 u9 C; r" l4 a. ]' ~4 K# o
  383.         if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return STM32FLASH_PGPERR;        //非法地址2 G: S' X. O, p% z4 ?
  384.         % Q0 R/ f) @$ ^+ Z0 v( n
  385.          FLASH->ACR&=~(1<<10);                                                                //FLASH擦除期间,必须禁止数据缓存!!!搞了我两晚上才发现这个问题!
    1 }' h) y5 L" d+ S
  386.         addrx=WriteAddr;                                                                        //写入的起始地址; c' r# C3 J, @3 R
  387.         endaddr=WriteAddr+NumToWrite*4;                                                //写入的结束地址( c1 ]/ j6 h+ X  I( M  m6 \. b( d0 P( B
  388.         
    8 p$ A6 y$ g2 S1 Z
  389.         if(addrx<0X1FFF0000)                                                                //只有主存储区,才需要执行擦除操作!!
    # O! T; ~3 \: R7 u/ X8 {
  390.         {
    5 s& ^6 Q' ^# x5 t% S
  391.                 while(addrx<endaddr)                                                        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
    0 ~% |) B3 J4 d1 n% |9 n- v) X
  392.                 {0 O: p8 J" Q, @* N4 ^9 }5 t/ o8 B: G
  393.                         if(STM32FLASH_ReadWord(addrx)!=0XFFFFFFFF)        //有非0XFFFFFFFF的地方,要擦除这个扇区+ @! x7 N$ x5 Q$ M
  394.                         {   
      k3 L0 _. g/ z& K6 X8 H
  395.                                 status=STM32FLASH_EraseSector(STM32FLASH_GetFlashSector(addrx));
    8 t6 z3 e! n+ g/ u
  396.                                 if(status != STM32FLASH_OK)break;                //发生错误了
    3 `1 j5 X9 ^7 l# K
  397.                         }else addrx+=4;, w  q! s; K1 B' g4 E
  398.                 }
    ! w( R& ?: a. p3 U4 ^) N
  399.         }
    : g% T1 }7 W; _# }( B
  400.         if(status==STM32FLASH_OK)1 X3 I8 m4 M2 W8 c$ a( f; U  B
  401.         {7 @$ h7 F' _7 Y: W7 |
  402.                 STM32FLASH_Unlock();                                                        //解锁
    ! E) k' X/ H$ j/ p
  403.                 if(FLASH->SR)                                                                //有错误,需要清除,测试过程中,发现偶尔启动后会有错误出现% i2 w$ w# N5 x) b" d
  404.                 {
    ) E+ v/ x' w# E: K$ ]$ p' n
  405.                         DEBUG("需要清除flash错误标记,FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    ' O* [* {. j- g4 y2 e5 d
  406.                         FLASH->SR |= FLASH->SR;2 ~5 i8 |& b3 f/ [: {+ I
  407.                         DEBUG("FLASH_SR=0x%X  FLASH_CR=0x%X\r\n",FLASH->SR, FLASH->CR);
    ) p: s5 j$ _6 L; V9 v, C
  408.                 }
    5 _) ^4 A4 L. K, a+ ]0 T5 g
  409.                 status = STM32FLASH_WriteMultipledWord(WriteAddr, pBuffer, NumToWrite);        //写入多个字的数据
    ! s  l; b  n9 m" C4 S7 |( {
  410.                 STM32FLASH_Lock();                                                                //上锁/ l  V+ u6 F/ @) g5 ~/ Z% ~1 ?
  411.         }
    6 J1 w1 Q/ t# Y* x/ n1 E
  412.         FLASH->ACR|=1<<10;                                                                        //FLASH擦除结束,开启数据fetch
    1 `  c; U: Y! C7 _: \8 u
  413.         ) y! D2 e  o) A- J" }
  414.         4 h% D$ @3 a' G% j; U
  415.         return status;, w, r+ O6 P8 o, n; ?+ [* T* C+ E* @7 J
  416. }
    - c! s1 I5 c% E" r) t

  417. 8 r- l% _% Q$ j* q

  418. 8 E3 G9 e0 _2 k$ v+ X0 s% i+ k6 t

  419. : e0 x0 s$ L; N4 S6 |

  420. ( }- G1 e/ k3 q2 M' q
  421. 6 J- U" q) C. w+ v
  422. /*************************************************************************************************************************
    $ j3 F. n4 U3 G- R
  423. * 函数                        :        u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead) ' s2 ?5 J4 h0 x/ K  k" R
  424. * 功能                        :        从指定地址开始读出指定长度的数据
    7 p+ K7 T5 i, p) G; z& E' i& ~
  425. * 参数                        :        ReadAddr:起始地址;pBuffer:数据指针;NumToWrite:字(32位)数
    ' x8 r0 ?$ `( d5 s  G0 A
  426. * 返回                        :        读取的数据长度(字为单位); a3 h9 p( {& a$ V* M- S- w) l0 q
  427. * 依赖                        :        底层
    8 F4 X8 x3 g! D1 Q4 E0 G
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>1 J! M- x4 `# l5 k( N6 W% E
  429. * 时间                        :        2013-10-20
    # Q: k1 G7 v! M& U* X1 {6 q
  430. * 最后修改时间         :         2016-01-07
    : W: M1 E1 z6 j; U% x. r. h
  431. * 说明                        :         地址必须为4对齐
    7 {9 o9 U; p8 l" ?6 F
  432. *************************************************************************************************************************/# i9 N! d, l' N" z
  433. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead)           
    : f7 w2 y3 W- M9 X, f( c' X
  434. {
    7 {( ~$ Z) Q0 j$ L
  435.         u16 i;
      R" m8 O& Z4 E) R0 R  e( f5 t
  436.         u16 cnt = 0;6 H* _2 @: _0 q0 B3 {5 v. p6 B: L
  437.         8 F6 g2 ?- f( M7 z, E
  438.         if(ReadAddr<STM32_FLASH_BASE||ReadAddr%4)return 0;        //非法地址
    # S, V! J- \# U9 K
  439.         
    ) M' b; E* I+ N  e. H6 F/ ]1 I2 m
  440.         for(i=0;i<NumToRead;i++)& Z$ o% e$ N; F5 w: w) M( b/ B3 i
  441.         {
    0 [1 y  J# c; W# _6 \
  442.                 pBuffer=STM32FLASH_ReadWord(ReadAddr);                //读取4个字节.
    1 G% {# t2 o8 @  a
  443.                 cnt++;
    9 m5 x' C* l* U( j" u" m  F6 A
  444.                 ReadAddr+=4;                                                                        //偏移4个字节.        
    5 ^. P5 \7 R* T
  445.         }
    % u6 h% Z) a8 P2 D+ i" }# P# o
  446.         return cnt;
    4 j( J" y; Z; E2 T
  447. }
    2 g. O0 g: Z! `/ m3 _5 s, r

  448. 5 S! l$ d9 @* f! W
  449. " l9 c8 A) A, j' w9 B8 o# w2 I
  450. /*************************************************************************************************************
    % v4 K$ A; y0 ]- R
  451. * 文件名:                        stm32f7_flash.H
    - Q  p1 y1 U& f6 Y
  452. * 功能:                        STM32F7 内部FLASH编程驱动函数
    0 g1 I. @6 Z3 a7 p) r
  453. * 作者:                        <a href="mailto:cp1300@139.com" style="">cp1300@139.com</a>
    ; s* S9 ~+ z  K- `# x/ f
  454. * 创建时间:                2013-10-20# |  n4 _" I0 Y2 A7 z  p
  455. * 最后修改时间:        2020-02-07' n& m  _- a! `3 v7 Y) m/ \
  456. * 详细:                        用于STM32F7内部flash读写驱动
    # n- y8 ^4 Q& C4 H6 s
  457. *************************************************************************************************************/
    . |8 f+ M  J7 F  Z$ a- v, A
  458. #ifndef __STM32F7_FLASH_H__  w& r5 }  N9 I$ ?1 M  D
  459. #define __STM32F7_FLASH_H__
    4 K" V; ^! _* {: Z
  460. #include "system.h"  
    % q9 b- l/ G. K! B: m

  461. $ H/ u7 ]: I. o: P$ P* T
  462. //FLASH起始地址. C* I- F# P* s$ j* s9 @
  463. #define STM32_FLASH_BASE                 0x08000000                         //STM32 FLASH的起始地址
    & ~; `, I; u" g' J, `( \: I
  464. 8 M  f' J: x% W3 s, n7 C( N2 S& y
  465. //FLASH 扇区的起始地址- i0 [. v5 |6 B, _: m2 [
  466. #define ADDR_FLASH_SECTOR_0     ((u32)0x08000000)         //扇区0起始地址, 32 Kbytes  
    3 a0 w* Z+ l2 J  H% C
  467. #define ADDR_FLASH_SECTOR_1     ((u32)0x08008000)         //扇区1起始地址, 32 Kbytes  
    3 V, ~; }) B. ]9 R" H
  468. #define ADDR_FLASH_SECTOR_2     ((u32)0x08010000)         //扇区2起始地址, 32 Kbytes  
    . I7 F, J" s8 M' U8 I& a; E
  469. #define ADDR_FLASH_SECTOR_3     ((u32)0x08018000)         //扇区3起始地址, 32 Kbytes  
    * ?6 K: @8 l6 P# u3 @
  470. #define ADDR_FLASH_SECTOR_4     ((u32)0x08020000)         //扇区4起始地址, 128 Kbytes  
    + s6 Q  n3 K7 w1 c$ N) s$ P
  471. #define ADDR_FLASH_SECTOR_5     ((u32)0x08040000)         //扇区5起始地址, 256 Kbytes  ' C+ k4 k0 O$ r
  472. #define ADDR_FLASH_SECTOR_6     ((u32)0x08080000)         //扇区6起始地址, 256 Kbytes  
    $ U! J( I7 }4 S
  473. #define ADDR_FLASH_SECTOR_7     ((u32)0x080C0000)         //扇区7起始地址, 256 Kbytes  " o6 v1 V. H/ N

  474. 1 O$ Z  R/ J$ a$ D

  475. ! i2 H" [2 W% U" V* z
  476. //FLASH解锁键值
    , y. H. h5 n2 g7 ^8 _, a
  477. #define RDP_KEY                  0x00A5
    ) C8 }2 u/ P/ T
  478. #define FLASH_KEY1               0X45670123
    8 K" z. z% ~. X+ N$ J) _2 n
  479. #define FLASH_KEY2               0XCDEF89AB
    " E. N6 w+ A& b; x; i. h, K* d7 k% T
  480. #define FLASH_OPT_KEY1           0x08192A3B. X1 a( N! Q$ d
  481. #define FLASH_OPT_KEY2                         0x4C5D6E7F3 H" m& g: {8 [# h, z6 }. F

  482. : R0 V3 g% W0 _) J) L- g5 p6 N# E
  483. //STM32F7 Flash操作状态3 W& b' @3 t; }! F. K0 P, R
  484. typedef enum" D9 U  A+ i0 A$ `$ B: l* D; X; ^0 Z
  485. {
    * H3 L2 t, Q, H; c4 f
  486.         STM32FLASH_OK                        =        0,        //操作完成  ~( @8 @) |0 D; W
  487.         STM32FLASH_BUSY                        =        1,        //忙
    $ f( p0 c3 j4 t% u' o
  488.         STM32FLASH_WPRERR                =        2,        //写保护错误1 ^- u' y" N) Z; }' z# f! P
  489.         STM32FLASH_PGAERR                =        3,        //编程对齐错误,必须128位对齐
    * a+ G5 C' F/ C9 A) \/ [
  490.         STM32FLASH_PGPERR                =        4,        //并行位数错误
    # N, i0 F! x8 E
  491.         STM32FLASH_PGSERR                =        5,        //擦除顺序错误
    + o2 \" b5 R4 N' |) g
  492.         STM32FLASH_OPERR                 =        6,        //操作错误
    2 R  e" x4 k; o! M- p& ^# ~
  493. }STM32FLASH_STATUS;
      G) u- i% _# a, W( c$ P
  494. ) T1 H. j7 }9 x. \
  495. //常用接口
    * ~; @# b* P( P# m" N0 r! {
  496. STM32FLASH_STATUS STM32FLASH_EraseSector(u8 sectoraddr);                                                                  //擦除扇区
    6 t& }1 s" h, [; C8 [
  497. STM32FLASH_STATUS STM32FLASH_Write_NoCheck(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite) ; //不检查的写入多个字的数据2 I) r- }* N3 G0 L' w: r
  498. STM32FLASH_STATUS STM32FLASH_WritedWord_NoCheck(u32 WriteAddr,u32 data) ;                                //不检查的写入一个字的数据
    6 t. m# L3 Q; c# B7 q' k4 f
  499. STM32FLASH_STATUS STM32FLASH_Write(u32 WriteAddr,u32 *pBuffer,u16 NumToWrite);                        //从指定地址开始写入指定长度的数据(数据长度字为单位)
    ! I( G+ i8 b$ G6 m# a& ?
  500. u16 STM32FLASH_Read(u32 ReadAddr,u32 *pBuffer,u16 NumToRead);                                                        //从指定地址开始读出指定长度的数据2 `" {6 |$ O4 G5 t, S. J
  501. # k/ A+ j( a8 ~6 c) v! E; H
  502. //不常用接口. B6 _( m, P, ?* K& o: @6 m
  503. void STM32FLASH_Unlock(void);                                                                                                                        //FLASH解锁
    " |9 ?& [$ u+ u9 U
  504. void STM32FLASH_Lock(void);                                                                                                                                  //FLASH上锁
    ) F: F5 Q% Q& K* U& Y
  505. STM32FLASH_STATUS STM32FLASH_GetStatus(void);                                                                                          //获得状态- K2 a& X. |) y, U0 q( v4 J# I* d

  506. . r- o4 J( n* \& ?2 u/ M

  507. * K: z: _& g$ D: X" }
  508. #endif        //__STM32F7_FLASH_H__
    ) F# W, ~. {- H2 r& x8 k( Q

  509. : H" U! f3 }: v4 Y
复制代码
& f- I2 ?; Y) @. `* F9 R
收藏 评论0 发布时间:2021-12-11 12:00

举报

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