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

【经验分享】STM32F7xx —— 内部flash

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。
$ k1 N  ?7 p+ j1 M* H+ R, ^0 t. o% K7 o* i' E6 I, Q% W8 N
  1. // STM32F767IGT6: 1M flash" a$ B* d9 Y/ N8 n* y* B
  2. // STM32F767ZIT6: 2M flash
    " ^$ T4 E- X' C: Z
  3. #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
    1 U: |# M1 B) E2 t# I$ s
  4. #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */
    0 I9 Y: v9 w$ N$ b( _  S& p
  5. #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes *// n$ {( z- ~2 H# Q, `
  6. #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
    * C# C" O2 c# y9 Q7 s. r
  7. #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */$ k$ e7 f7 |' e1 Z# k2 d- k% F
  8. #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
    7 S3 d& p+ J3 ^5 g/ k2 z4 F/ ~
  9. #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */: N* a) A7 A. c3 x: |# e4 l
  10. #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */3 [" w3 u% J6 V! W5 s4 Q8 e- A
  11. #ifdef STM32F767ZIT67 O, d, f+ U) v. J1 S* F( {
  12. #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */3 g8 O% i0 B, y) E. m. J( f1 v
  13. #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
    ; f) O8 V% Z) J% F# h+ ]
  14. #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */* e' ]1 [$ K7 e1 e( I
  15. #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */8 `4 X/ v0 d5 d& I$ O
  16. #endif
复制代码
  1. // 获取要擦除扇区编号+ E" l  F' V- q8 k
  2. static uint32_t flash_sector_number(uint32_t address)
    4 ^9 e  t  B3 W% q" [, ]5 V
  3. {6 j( }. a! O; E. n* R3 F
  4.   uint32_t sector = 0;
    3 K7 V/ T0 B( g1 s
  5. 5 _( y* @. y, m9 t- P* e+ U
  6.   if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))% o+ Z$ h% L% Q1 m, g. y2 D6 f
  7.   {: g) Y& G' L4 _! h% q7 n5 H
  8.     sector = FLASH_SECTOR_0;
    + j, x) a, u! ~0 O+ ]
  9.   }" V% U6 k+ V5 Q# P! H, x/ q
  10.   else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))
    ) k. ^- s! Y0 v$ e5 _
  11.   {
    ! b7 m6 ^. d1 W2 f& d5 s: ^) l% d
  12.     sector = FLASH_SECTOR_1;
    7 g: d6 Q. M; w! q8 _5 S7 x0 a
  13.   }
    & @& c# ?+ k) u3 r  A
  14.   else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))9 E$ o) A0 _% e1 P) k
  15.   {
    3 x$ j9 N+ m* x* c1 V
  16.     sector = FLASH_SECTOR_2;7 b! Q3 |) @3 u
  17.   }
    2 l7 Q1 q! y& X" S% \
  18.   else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))" y' K+ w1 W" e- N7 Y
  19.   {
    & E8 t4 Q- n# x3 m3 m
  20.     sector = FLASH_SECTOR_3;
    + q+ M. F* d& u4 Q
  21.   }
    9 W3 e, e# h; o5 t: i" f3 y. ^
  22.   else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
    ; ]' l4 ^7 Y% F
  23.   {
    ( A# L# W$ H9 @7 L" j
  24.     sector = FLASH_SECTOR_4;
    6 o( F" U9 w% Y9 A+ h/ M: W: i
  25.   }
    1 b, T3 \# M6 A& A6 r2 a
  26.   else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))
    ) R2 J5 E# G8 M+ ]: n1 F8 O# Y: ?
  27.   {
    ; y& \6 H  A4 k4 T3 e
  28.     sector = FLASH_SECTOR_5;
    + y! {7 i( v; k4 k& N
  29.   }
    7 E# ^; z6 p& y( s
  30.   else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))6 ]3 Q8 c4 _! T0 j: i& a1 b% }# B
  31.   {6 e* k' w( W. H% i3 \
  32.     sector = FLASH_SECTOR_6;8 h/ i) ?0 U- A) x$ I7 Z$ y
  33.   }
    3 [  T; X7 {& m" l( E$ U" ~7 k7 w$ J, U
  34. #ifdef STM32F767ZIT6
    ; [* _0 k6 g! T3 n  J5 u
  35.   else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
    : _" a0 S" t3 u4 U* @
  36.   {1 E6 ]$ s3 T: A- p2 E
  37.     sector = FLASH_SECTOR_7;( t- X  J7 |3 H5 _
  38.   }! C  o% T* h  f  h0 z
  39.   else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))
    ; D" ?% e8 o3 A) ^/ ?+ G& F6 W& D
  40.   {
    1 u  a- D, ^, o8 z1 f# O
  41.     sector = FLASH_SECTOR_8;
    7 j9 k; |3 d- U: _9 M4 C! ?: a
  42.   }
    8 {$ ?7 B) F) Z6 g" E8 {
  43.   else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))
    4 G7 A4 f9 ?; M& S3 Q3 y, `2 O
  44.   {9 M. b/ y7 \: B5 L* j9 f% R) ]
  45.     sector = FLASH_SECTOR_9;
    . `" s+ E# M6 w9 a' G2 F
  46.   }
    2 V( U. e6 L1 t8 T' y
  47.   else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
    ! R% s: K- x/ k. J* f6 \
  48.   {
    ! C- A; q" n0 ~( I1 {& h
  49.     sector = FLASH_SECTOR_10;
    " y3 X  G1 K% r3 L0 U* {
  50.   }
    * j3 k: v6 A) a
  51.   else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11)): D6 r# G  |0 b) y- ?- w% Z
  52.   {
    3 r6 w: R' i) I# f2 V
  53.     sector = FLASH_SECTOR_11;
    ! o$ L6 ~) D+ D  k
  54.   }9 ~4 i  G& q# [1 g% ^$ s
  55. #else( D3 O6 U  B6 b3 y
  56.   else if(address >= ADDR_FLASH_SECTOR_7)
    5 f6 V9 R7 Q2 M2 |/ U3 W
  57.   {
    / [( H) ?  [4 U7 b% o
  58.     sector = FLASH_SECTOR_6;* g  _0 @5 J+ q8 g. \
  59.   }* c: C/ p9 x0 j" f
  60. #endif9 d6 P" z7 X( ]
  61. $ a9 Y& }" f2 R
  62.   return sector;3 X  i7 x2 }5 q5 v
  63. }1 ^) }0 a9 C5 n

  64. " s; G+ v# T! c0 N: U
  65. // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
    , R  q( V4 X5 x) h3 u9 c4 k7 u) l; A
  66. void SocFlashErase(uint32_t addr, uint8_t count)
    & r: o9 Y$ T9 y: {) r' C
  67. {
    # O/ W$ v$ K, i. l3 d# m
  68.   FLASH_EraseInitTypeDef flash_erase;" C9 V; F8 F$ q' U; @6 O
  69.   uint32_t flash_error;7 H* |$ x. o1 l! Y
  70. : {3 T" Z1 B& H. f. H* K
  71.   HAL_FLASH_Unlock();9 l, \0 k  }( K' [, u) t# B
  72. / C3 i  t& O+ T9 U6 w9 ]5 l- P
  73.   flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除+ e1 d  i( X/ K  d
  74.   flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区
      Z! p4 m  g# |8 O& s4 Y* t
  75.   flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
    , w% i5 a1 R5 K  ]+ M
  76.   flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!& g7 o0 g% @% K9 o

  77. * ^# l* _- h. Z( v
  78.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    ; J( W1 Z7 o* j3 R2 X3 Y
  79.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);! D" g8 y- `8 V

  80. # W  s) t' P8 t0 Z
  81.   HAL_FLASHEx_Erase(&flash_erase, &flash_error);
    2 k0 U0 z- Q& N8 Y5 u  e
  82. 1 R; z5 ~' s4 _7 a/ N5 f
  83.   FLASH_WaitForLastOperation(50000);
    0 x9 V' y8 d2 N5 B5 l
  84. * @5 @$ D2 r$ F' K
  85.   HAL_FLASH_Lock();
    9 l3 G. _" S; U, u0 }
  86. }4 `, d6 B, Q+ M6 g0 }+ _+ ]1 Q$ o; n% v

  87. - F; v$ j; y4 G
  88. uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)2 L1 Y) K/ M! i0 L
  89. {$ k1 g- ~8 X( s/ Q' A6 u, G" u9 o
  90.   uint32_t i;
    7 j( }3 z* f* ^7 M, X$ \# e/ |3 \
  91.   uint16_t data = 0;
    3 k% p1 E$ F$ d, t; M- W
  92. ' t: W/ X; S: k9 ^1 f* Z
  93.   if (length == 0)
    . G3 O2 ]" o1 J* S- j8 w9 E
  94.   {
      y6 p; P- G+ k
  95.     return 0;
    & ^- G6 z9 a/ m+ O- D0 p# N
  96.   }* U+ e2 x$ g( v0 e0 z+ f

  97.   J- \  O' u4 a
  98.   HAL_FLASH_Unlock();1 L& d' R  t9 O8 j! F4 D

  99. ( \/ S( S) ~  |5 L) h
  100.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |" H2 F- X6 {1 b; {
  101.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);# l) P2 H& ^7 G
  102. 2 o; w' ?3 P1 B& t/ w
  103.   // 按半字编程
    : V! b% B' n8 l# V, \) x7 M
  104.   for (i = 0; i < length; i += 2)
    ! g# n& ]' r" T4 i6 F' x
  105.   {8 b6 c" i* r$ r3 V8 L5 ~9 S( X7 D
  106.     data = (*(buffer + i + 1) << 8) + (*(buffer + i));3 |7 `0 R- L5 s! }& J2 q
  107.     HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);
    " r$ ]! T# M3 X7 ]0 L
  108.   }
    6 e+ l/ t5 e! x) d8 ?  d4 x$ e' k1 q

  109. 6 [9 t' f- u) H
  110.   HAL_FLASH_Lock();6 Q% w# x! B( {. u
  111. + J" ?  G% V0 f! J
  112.   return 0;
    " h) o- H5 ], t/ t
  113. }! B6 K1 _' }2 F0 \  H; o5 i
  114. 6 J# x1 b" l. J4 Q
  115. uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)5 F3 q1 T$ b0 N" E0 p% G/ K
  116. {" q& v) @' z6 K, w/ O
  117.   memcpy(buffer, (void *)addr, length);
    ; G# o6 F1 S# K9 \$ }

  118. % ^- a* M. s/ ^" F" N) J2 J' O
  119.   return length;
    / T2 `0 a; B9 H- n1 U% t1 N& u
  120. }
      f4 Q! \3 L& C  r) m: Y3 f' R

  121. 2 v9 T/ J& k8 t  |; \- v
复制代码

+ q* j; X$ `  p5 ]5 q  j
5 @5 X7 m" F1 L3 w. Y6 q
赞 收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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