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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。7 C( O/ ~/ t- J9 ]/ Q! g% R" d
! w! l' a) q& \( J+ g! k
  1. // STM32F767IGT6: 1M flash: p: W7 l5 \7 y, s6 I
  2. // STM32F767ZIT6: 2M flash& y' A; {- U- h$ _  `
  3. #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
    ) J+ p1 Z5 W$ ]# d- n5 p
  4. #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */4 y  _4 R) s8 K1 g
  5. #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */% h# t- d, V0 ~3 y' H7 N/ W3 s
  6. #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
    , B' v+ i% h: v8 s5 _9 n
  7. #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */: _( v( `& D/ A+ L, _" `
  8. #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes *// k+ y0 ^2 A8 f2 F* Q9 n- \( X
  9. #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */( e  F5 d/ C, a6 f0 x6 c; a+ K
  10. #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */, B! Y; g  P3 s4 p
  11. #ifdef STM32F767ZIT6+ C+ W9 M) K4 L& ]
  12. #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
    ) U' t1 I. v4 d! o+ [6 M
  13. #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
    / H( R4 y# Y0 d
  14. #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */$ ^1 c* C1 i; e% [& i
  15. #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */; L: N$ j: s+ T+ e" p# |" }/ d
  16. #endif
复制代码
  1. // 获取要擦除扇区编号
    8 Q8 A5 G" [7 T* G
  2. static uint32_t flash_sector_number(uint32_t address)
    - b3 }4 j7 Q- K
  3. {
      r, z$ ?$ D% W( j5 {) X! G" g: F
  4.   uint32_t sector = 0;
    2 j: p- U) k; {" t

  5. ! @/ m3 a$ z) M" `" |: y0 e) v- c
  6.   if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))
      R' H1 A3 |9 P( V3 `0 Y
  7.   {0 t6 @6 }9 }& `$ v( v. X
  8.     sector = FLASH_SECTOR_0;3 B. M3 G8 O4 X( [" r. X
  9.   }) Z2 }. i  |& o4 e  r) @) p
  10.   else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))4 x. `7 \' {/ L; h9 j8 X2 C
  11.   {" h" A1 K2 ]  }: l- O
  12.     sector = FLASH_SECTOR_1;
    8 `4 ], [5 L0 J! S  n! W! a4 g1 w4 }
  13.   }
    0 B4 A( B8 _# {; ]4 Y/ u) ?. \3 W
  14.   else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))+ N7 t# J3 O6 [
  15.   {3 h" y3 z" W6 f% I% V
  16.     sector = FLASH_SECTOR_2;7 p, }. }$ B. e+ D, d
  17.   }4 \; q8 X. I0 o3 ~8 P! J# C5 ~% w/ {
  18.   else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))9 Q. I4 @$ a2 f6 n2 q$ M* N1 ?3 e
  19.   {: U, c& I* }0 P3 X. b' m
  20.     sector = FLASH_SECTOR_3;7 V% \6 h0 b, [# ^
  21.   }- M2 I, Z# p3 n! A4 y
  22.   else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
    7 z8 Z' l. b: ^
  23.   {
    # N" C1 L: I  u. Q; q; x) r. _
  24.     sector = FLASH_SECTOR_4;
      O  \9 }  b6 ?
  25.   }  R1 l# E) v/ w) I: k" l2 @
  26.   else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))4 I6 z) {, ?2 X9 n- o2 H- k  u8 S
  27.   {
    2 B4 S; M$ L4 ]# E1 W4 ?: z
  28.     sector = FLASH_SECTOR_5;
    5 o' P  i) }- W* u# G
  29.   }
    $ s# l, ?+ M6 i9 _
  30.   else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))! D8 r! h2 b  C- D4 ?. f
  31.   {2 c4 i+ e/ b+ I" M6 F3 R+ S7 l
  32.     sector = FLASH_SECTOR_6;0 ~5 ], r  x( a. t7 X7 J
  33.   }
    ! v5 }: a5 R8 Q& A/ i. B4 U' r) N6 h, t
  34. #ifdef STM32F767ZIT66 Y$ B- s( Q$ a6 [
  35.   else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
    # T6 Z* g1 k" U7 u$ }* t3 K
  36.   {. f2 w+ Y0 q! y/ y
  37.     sector = FLASH_SECTOR_7;
    8 }* F4 n1 c# _8 y! Y
  38.   }
    8 D) U3 _6 U1 U& J' T% J
  39.   else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))+ u1 N# D6 I* `9 F) k
  40.   {
    1 p1 g0 ?2 d8 L1 ~' x# G
  41.     sector = FLASH_SECTOR_8;
      T7 Z7 ~" T7 d
  42.   }5 `3 X- f# @2 ~6 z# \+ H, m
  43.   else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))! v+ o; x- R+ @% i
  44.   {
    / j9 B! l. n& A3 v* B
  45.     sector = FLASH_SECTOR_9;
    9 l6 F- i9 O% L" C
  46.   }
    ! F3 b- [, {; C0 u
  47.   else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))) `# z0 u+ s) e; N1 t
  48.   {0 L  E4 n% T0 {# c( v  Q0 R2 v
  49.     sector = FLASH_SECTOR_10;+ l3 d7 ]0 U/ k4 C3 }( ?% ]9 r8 \# E
  50.   }2 H2 h) a* t3 h
  51.   else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))9 E4 W$ w% x9 Y. f$ L: T+ Y1 H, B
  52.   {8 y, J) n$ a2 b+ B3 Q# o4 _
  53.     sector = FLASH_SECTOR_11;0 h+ f) k& n+ n! H
  54.   }
    6 G4 r* A6 O6 L6 D2 I: ?. `1 G( G' q
  55. #else; M9 K) K/ A2 S# [
  56.   else if(address >= ADDR_FLASH_SECTOR_7)+ w/ S) b. E5 G1 ~
  57.   {( ^6 L8 G3 q4 J$ |
  58.     sector = FLASH_SECTOR_6;0 V5 J9 A# e: Y: q! ?( j, U- S+ q
  59.   }+ g2 k, Y" E# g$ H7 [$ O
  60. #endif; z9 x0 L2 P2 p. @: L: k
  61. 9 G. V, K  R  e# \$ X( I3 J- @: i
  62.   return sector;8 ~: n: }, {6 |3 p# y$ s
  63. }
    % ?0 P% o: P* D. ?' c8 Y& x) q  h8 r
  64. 2 P3 \: ?. Z) F1 {
  65. // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
    # P& X( h  ~& X3 K% q  n  ~' ?
  66. void SocFlashErase(uint32_t addr, uint8_t count)
    4 A' t% Y/ ?7 v& p& r% P# G, F
  67. {, c- u# U9 j3 f6 T! D, M2 {
  68.   FLASH_EraseInitTypeDef flash_erase;
    & S! m( E* }* g5 X9 }8 h5 }
  69.   uint32_t flash_error;
    - @  ]; y/ G  ^) f$ I, |
  70. , n" H, a6 @! V; P6 V/ a1 \3 V! h- ~
  71.   HAL_FLASH_Unlock();1 j8 o# o6 O* n5 w- f9 q8 O

  72. 0 e! [! y& g( s% [) o
  73.   flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除1 _/ Z: n3 t- T9 G, U
  74.   flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区
    ! F5 {, D  c9 N1 `! _, e
  75.   flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成18 v: t! }# L4 R: [
  76.   flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!
    * ^$ R/ K* A+ m/ q7 f% L7 D

  77. 6 K1 t/ v6 B) M
  78.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    & I3 }, l- h' S1 [6 U2 S
  79.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);; D; x- Z2 h6 n' E0 r7 \( O

  80. - |4 y" b( h) ~- ?. P2 e
  81.   HAL_FLASHEx_Erase(&flash_erase, &flash_error);
    1 o8 @  e' z6 T6 w- ]6 P

  82. & J  }' A% q; m# J
  83.   FLASH_WaitForLastOperation(50000);
    7 A7 Z# z: E% r1 Y' \# f
  84. $ o3 s+ l8 h( D' L2 ?6 m9 a
  85.   HAL_FLASH_Lock();$ \  r" p' L7 t" P1 y9 @
  86. }+ x7 I1 E  u* ^3 Z* W7 k
  87. ) e$ }2 E& D/ a. q; {2 i
  88. uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)+ a6 b2 r$ [/ s4 L. v
  89. {
    ' z! ?# S3 Q# T; O, i
  90.   uint32_t i;
    ! T$ G) o/ I/ R. u
  91.   uint16_t data = 0;
    ; i( Z; E3 \- m; W8 D
  92. : }$ o* k7 a, h+ `9 ]1 p
  93.   if (length == 0)0 S8 N* R" D  v# }  Z
  94.   {8 X2 ^3 d: w- C  l  D0 d
  95.     return 0;! z$ l2 L: A* {6 D9 J! ?1 I: r
  96.   }, ]; K/ V- `. z

  97. - f/ p% x# u/ |
  98.   HAL_FLASH_Unlock();
    / N9 V0 q5 k8 Q$ r; j
  99. ; B" P  y; x( @( K" d; y! u* p
  100.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |4 w: r% u: G9 C; [2 Z* p
  101.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);0 ]- y" ]9 t3 N6 v# M; e. @
  102. - p- |. m) E) s3 o! g% R
  103.   // 按半字编程
    * A/ U7 G5 F; S
  104.   for (i = 0; i < length; i += 2): K; g! T: Z, h+ t( B) [! J
  105.   {+ h4 t! C( R: I' b+ i
  106.     data = (*(buffer + i + 1) << 8) + (*(buffer + i));
    2 Z4 U5 i! P1 V" {+ O
  107.     HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);$ J- ~5 F, i# l0 |7 j# \5 q
  108.   }" C) Z  p" N& z- i1 Z0 o" K) t  B& r

  109. 4 t) O+ k* }7 p9 X3 i1 F7 Q+ _
  110.   HAL_FLASH_Lock();
    9 L" u1 Q5 A2 f1 ?0 z3 k

  111. 6 j- h( y9 v$ k. G9 d
  112.   return 0;) G+ n! \6 E6 e3 A' r' B4 k6 v3 N8 F
  113. }0 }+ O# r; \9 I; `

  114. + Y2 o, ^: G/ Y  @, Z2 J' h5 @  y
  115. uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
    , g6 m1 p/ M' R  A5 w
  116. {
    1 p- p* O. q9 \/ o6 g4 O
  117.   memcpy(buffer, (void *)addr, length);
    2 ~/ y' M9 w4 i, i" E: G
  118. + K: K7 T# S3 J1 n
  119.   return length;
    2 M% q5 _% {( A8 K
  120. }
    : r0 r. N# C. \3 T& g; a6 _7 M3 D

  121. ' W" k) K. \5 E! j; w* [
复制代码
7 e7 G3 i' F- T# H* G2 q) {7 f2 y1 q9 q
4 u& [3 w0 P$ Y: W; f
赞 收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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