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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。* _4 N' F6 \) {3 V4 J2 p1 M

0 p- k' F  v* A5 g6 ?# \
  1. // STM32F767IGT6: 1M flash
    . s' W1 b+ }  ?- o2 A
  2. // STM32F767ZIT6: 2M flash: t9 Q! v1 V" E; Q% ]
  3. #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
    ( |/ c  a5 E$ Y9 I
  4. #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes *// }$ `  U$ j) c9 ?& n6 \5 {
  5. #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */
    / C9 y3 r0 H/ F
  6. #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
    * c6 _: Q" ~% S/ {# m4 R, E4 v- m
  7. #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */' }9 l4 K3 f% ]' z! `0 C
  8. #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */1 |% i3 Q2 R3 A' }& F# Q, N
  9. #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */
    3 |" J' }: m1 m: x9 X0 Y
  10. #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */
    - t* r. F3 d# @2 r
  11. #ifdef STM32F767ZIT6
    1 R5 L5 c9 }1 B4 z% J
  12. #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */5 Q8 M; @- o! ^, E/ }
  13. #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
    4 C" e' e6 C, @  B* G: j
  14. #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */
    * E9 ?, z( J( B, S
  15. #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */, [0 z9 O& p4 f+ K/ j
  16. #endif
复制代码
  1. // 获取要擦除扇区编号4 k% E5 e5 H' |# F* E1 S% H
  2. static uint32_t flash_sector_number(uint32_t address)1 L2 p$ T+ S- c5 }' p1 p0 }
  3. {; \" v. a# n8 s# ]6 s
  4.   uint32_t sector = 0;
      o5 q. U. y6 O. r) r0 f

  5. 9 W" o8 |6 I7 V' K' Y1 O
  6.   if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))5 z0 }2 p, a% r! m% y+ M
  7.   {
    3 D9 g% y9 v/ }8 s% s# J$ T( a
  8.     sector = FLASH_SECTOR_0;
    ! O0 \5 a' z) B/ c& r1 M0 P
  9.   }
    * @- n$ a, [# b9 _+ F. D8 F
  10.   else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))
    6 R- r, }  o0 C0 w
  11.   {
    ! \$ ]; o( `6 ?2 e
  12.     sector = FLASH_SECTOR_1;# c* @1 c. s; P0 F7 g7 m0 e
  13.   }
    / q1 F% @; `' _' T/ ?
  14.   else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))$ [! P$ o+ j/ i* w3 U# O9 b, g
  15.   {
    7 ^: b2 a0 k9 Q4 o
  16.     sector = FLASH_SECTOR_2;' c. N8 h' {- {+ S! t( L
  17.   }
    - J( R5 @* V  C; ]7 X
  18.   else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))
    % n& ^( \9 o5 z
  19.   {& x5 `  x' c* O4 d: S+ ~+ V
  20.     sector = FLASH_SECTOR_3;* c. |6 y/ V+ K) {& E4 }
  21.   }# y  Z8 G. Y8 j; c+ U$ Y3 W/ Z8 R! F6 L
  22.   else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))$ r' Z: r% ~- R. A0 C- C- g  H
  23.   {
    3 D9 h. U" t# M
  24.     sector = FLASH_SECTOR_4;
    $ ]! s. @4 \1 o' O) x9 @  m5 j
  25.   }4 C! x/ p, a+ b( z( i7 I* I, P9 L
  26.   else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))  D* x* y; m9 E$ e
  27.   {' Y; J  z$ W  S* K+ c
  28.     sector = FLASH_SECTOR_5;  r6 V9 N' P0 F( j! X
  29.   }% p0 ^) o4 `: A
  30.   else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))
    3 p  }0 e: X. {1 \1 P
  31.   {" _$ H- ?* }, l$ ]. G( R1 m
  32.     sector = FLASH_SECTOR_6;0 b! O+ d+ s9 S5 U$ Y, Y
  33.   }
    " z1 Z- E/ o7 F, S1 y# _9 c
  34. #ifdef STM32F767ZIT6
    - {$ F3 H9 e6 a% X
  35.   else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))3 {( f& ]$ ?7 U
  36.   {, c6 m4 i  _" {! ~9 c. O. a
  37.     sector = FLASH_SECTOR_7;- N" `9 l: q4 U) G- a0 A
  38.   }; r% v: `/ J+ }
  39.   else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))5 u2 j1 @. C8 n& g
  40.   {) n  _5 ~3 {5 ~& x
  41.     sector = FLASH_SECTOR_8;
    . @; j$ O8 o7 y! ^. }
  42.   }3 r6 R  a+ @& t2 X$ x
  43.   else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))0 L6 E, C5 T, ]* G. s
  44.   {7 e9 U1 H2 z  a, F+ h
  45.     sector = FLASH_SECTOR_9;' g- b5 i. H5 e0 O& R$ ]( k- M
  46.   }
    ! d; t6 m5 ]; z% v
  47.   else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
    ; y- K; Y8 Y; e
  48.   {5 o0 E2 v  R; z0 O
  49.     sector = FLASH_SECTOR_10;( `4 W6 q8 j6 t/ i# c9 }' u3 x
  50.   }
    8 E' R3 ?7 Z/ o: P5 @4 x$ a
  51.   else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))
    ( [% x- _# t; D+ e% t# |7 X
  52.   {
    & Z8 H6 |# F$ `. r+ H7 C. G
  53.     sector = FLASH_SECTOR_11;1 C: S6 l% p2 i* ?2 D- t! `
  54.   }7 {: X; m* `" I9 b( ~" x& C0 b
  55. #else
    4 s1 X# y; d  l2 c$ J, T
  56.   else if(address >= ADDR_FLASH_SECTOR_7)2 D5 x) r' N* ^  b' \
  57.   {5 Z& V% u9 N# j2 V# }6 c
  58.     sector = FLASH_SECTOR_6;
    . f+ W9 o; L& I& {" e5 F- t4 T
  59.   }
    . F8 w  K# Y& T. R8 \% l/ B
  60. #endif
    2 A1 {9 P7 N$ P, R9 c; e
  61. : l4 q- U1 d; Q4 Q9 |/ {, L
  62.   return sector;1 x6 m% P2 O$ u0 s& P# m8 [. C& s
  63. }3 b( h9 `; z5 `* b/ L

  64. 7 b5 i' S( P% k) M
  65. // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。8 x% M6 A! m  ~* ?9 P
  66. void SocFlashErase(uint32_t addr, uint8_t count)5 R9 v/ V& D7 D
  67. {
    / \+ u) g* w% y
  68.   FLASH_EraseInitTypeDef flash_erase;
    $ J/ t9 S- q* e  i4 t
  69.   uint32_t flash_error;! I8 J% |$ x$ i9 E& g: G
  70. ' s" ]& z$ {: w. H: n) k
  71.   HAL_FLASH_Unlock();
    $ u) f( \+ |. n6 J6 @: p0 P

  72. 9 j; _( m7 b: P
  73.   flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除
    # H* o# S; U1 J- R: k
  74.   flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区
    ; ~: d9 u, L, y5 `+ V
  75.   flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
    & J; I7 n& C5 ]0 ~/ a
  76.   flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!
    . b7 a4 S% |: D! ^6 }% X1 Y

  77. + E/ z9 \& r- P3 s1 |, N; T3 B' H& U6 E# {
  78.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |+ B. b  y% Z' a$ _$ I
  79.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);( ]" f" \0 N& [

  80. 9 }( n) m: l( B8 }. {
  81.   HAL_FLASHEx_Erase(&flash_erase, &flash_error);7 }4 k6 F0 A/ U+ k2 w' M) R% y* l; D

  82. 4 K( z; Q! ]. H. v! {0 ~
  83.   FLASH_WaitForLastOperation(50000);0 G, m; f5 l0 T

  84. 5 @* r: O8 h' E& s: r# [5 a: F6 F! R: I
  85.   HAL_FLASH_Lock();$ @' H( h  @9 B+ C, d- U  O! g
  86. }
    , `; s5 |/ o* Z+ e% W' _( Z6 z  v

  87. - i& |( t; B" ?) x0 ]0 H8 V( A
  88. uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)& M# f" W0 l: d& f* E
  89. {
    + S# o& ]+ G  @# o# x
  90.   uint32_t i;
    7 @: b/ g2 o0 B4 U
  91.   uint16_t data = 0;; `0 R+ N$ T$ O* N2 F3 a% U
  92. 8 l7 E+ Q! w$ d1 O) C
  93.   if (length == 0)* v4 y1 A* [2 ^% j
  94.   {9 V8 G5 c/ U# \
  95.     return 0;
    & i" @; r  N% ]" m
  96.   }
    3 t' i: Q9 @+ V# q! \2 r/ [
  97. ( J6 h9 v1 t+ @% v
  98.   HAL_FLASH_Unlock();
    / ~  u  T( X  {  r6 p( n0 o9 ~

  99. ' p3 e5 x0 }$ f
  100.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |3 m* @1 k8 D! R
  101.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);" P' ?+ O$ n+ P) [
  102. , k( T4 I5 A, k; ?2 o
  103.   // 按半字编程
    1 i1 m3 [8 A5 B
  104.   for (i = 0; i < length; i += 2)
    * R+ p$ Q/ b, c# i1 q0 M
  105.   {" V7 a2 e0 [+ ^2 Z
  106.     data = (*(buffer + i + 1) << 8) + (*(buffer + i));/ Q$ t6 Z: z* j
  107.     HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);' y9 V2 ^. Z: c* C  R
  108.   }- R9 T0 ]: R6 h: @% f

  109. 1 c; L$ L, }) y7 E+ h7 {9 h% h
  110.   HAL_FLASH_Lock();
    . X- e2 }- ?% ^) a

  111. 9 }: L# L7 K/ u0 {( Z5 J
  112.   return 0;+ P& ?$ E$ K6 W6 G8 P% R
  113. }7 P+ b2 c& I5 G3 ?* Z. S5 }

  114. 7 M2 S% |4 X# }& k! U' B4 E4 n6 R
  115. uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
    : h' R, j# D) p4 [+ H+ l2 V
  116. {" x7 W2 |  j5 P0 E. R
  117.   memcpy(buffer, (void *)addr, length);% h. |9 b! S) m* S
  118. " f5 {( p# x+ n: L
  119.   return length;
    / O" Z2 w" i1 R# r5 l% p7 f3 @2 E1 ^
  120. }. {* v7 q7 H- c, ^5 W6 j3 l6 H

  121. 1 v' J+ V; Q( E0 }' r+ G
复制代码

3 e: D6 t$ g0 ?, U# d$ l' u" I% [' s& o8 f+ D/ W) f* p
收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

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