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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。2 {, Z: V/ I' Y* v% e- V
& Z  i3 W$ p& P
  1. // STM32F767IGT6: 1M flash! k) C! N( a* n6 M* J
  2. // STM32F767ZIT6: 2M flash! _& U/ \% E* S4 M' F2 X: n
  3. #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */6 l( m/ E/ G6 f3 s5 h- x1 p7 l
  4. #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */" u( a7 C7 e2 ]
  5. #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */; Q' r/ q0 h% J4 S, o' E0 ?8 l3 m
  6. #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */& i6 x* c+ a5 U/ v* b
  7. #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */- \3 n; `7 f4 u( s* i- j/ D
  8. #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
    ! q- f2 {+ X3 ^
  9. #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */9 e/ [3 G* k/ a0 t$ l* k  Q& L" B
  10. #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */$ r. t& `, t3 D9 A/ x
  11. #ifdef STM32F767ZIT6: p. q3 ]4 A, F
  12. #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
    & q" Y6 r( Z8 _5 q
  13. #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
    2 M/ ^* X6 O4 n; `
  14. #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */) a* T* m+ E: g+ z; Q- f. `/ ?5 T
  15. #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */" j2 B, Y7 y  j$ J; [
  16. #endif
复制代码
  1. // 获取要擦除扇区编号
    ; Y' c: ]# j6 y3 C' l
  2. static uint32_t flash_sector_number(uint32_t address)  H* S. y6 N9 ~8 t' v( f
  3. {) R" i) H8 _* X
  4.   uint32_t sector = 0;. N" ^, S/ X$ Q$ ^% `: M

  5. 5 Y  O3 k1 p4 d. _8 p
  6.   if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))
      w& X) F3 L- a# _% T+ S! D0 o8 V7 f
  7.   {
    " c, j- y% D$ H0 c9 F8 S/ `& I8 y  ~
  8.     sector = FLASH_SECTOR_0;8 b; ?+ x' z6 o" N/ H/ k- U
  9.   }$ _% ]- ?" }0 E: c& \  C- v4 Q7 p
  10.   else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))
    + S3 G1 \0 A( X% K# O
  11.   {
    ( t: \5 o! d% Q! b4 p
  12.     sector = FLASH_SECTOR_1;
    8 l2 ?  G6 B  s2 ^9 g) Y9 H; G
  13.   }
    , J" H4 g% B2 i
  14.   else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))
    / Y' }; F, v4 L) d: w) C  j: w
  15.   {
    ' y8 r/ H& J$ Z. t
  16.     sector = FLASH_SECTOR_2;, p0 x2 m' r5 J* L* o
  17.   }
    9 {! Z% c1 f/ N+ H& U: N
  18.   else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))% j9 C) j* N5 C+ ]8 S& p0 P3 v
  19.   {
    5 w% k7 y  c1 C5 F8 x! B9 J" L1 e. k
  20.     sector = FLASH_SECTOR_3;& F" A8 _* W$ V9 L
  21.   }
    8 |% l- T! M! O) h8 _( l( C
  22.   else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
    6 \: @, K1 `* p1 J
  23.   {
    8 K. D/ w: |  R. y
  24.     sector = FLASH_SECTOR_4;
    + a* X5 ~/ A( t$ S0 J6 q
  25.   }+ T" e+ q+ x- j
  26.   else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))( d6 D  K) d6 n6 F$ t  X  q1 j
  27.   {7 l( n& U$ }, k  s3 ?& ^/ J
  28.     sector = FLASH_SECTOR_5;
    , [* W: J0 L+ W8 {2 q( ?
  29.   }' C$ U6 z5 r7 {& O) T9 s
  30.   else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))- Y+ N, y& p) L% [: L
  31.   {  s8 V7 W7 a& H3 |, `, ~
  32.     sector = FLASH_SECTOR_6;/ l0 T# s* j* L! ~' _
  33.   }
    & D' Y6 L4 m1 \8 R6 R, t( e- _, @) U- ~5 E
  34. #ifdef STM32F767ZIT6
    4 K, I4 j! K6 J
  35.   else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
    9 R" N  ?5 Q- X$ A" R
  36.   {
    9 H: v" f! G$ o8 L8 [4 V7 T) w/ W
  37.     sector = FLASH_SECTOR_7;
    ; W, L, }/ t, ~! f# F& @
  38.   }
    6 T, V* D1 c6 K/ b' k6 n+ A. M. M
  39.   else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))6 a% G* B4 F0 v2 y% g" x
  40.   {0 I9 \; z6 E+ s& h' H7 b+ {4 n6 d0 [
  41.     sector = FLASH_SECTOR_8;  r* P/ V6 `& J" w
  42.   }
    3 d6 @8 n; c: q/ h9 o* E
  43.   else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))3 I. {7 q' X0 w$ y$ X
  44.   {6 b) l/ Q" B7 |0 t; C5 f* |; X3 ?- _
  45.     sector = FLASH_SECTOR_9;
    * n$ V& w* c" P
  46.   }
    / l% J) v8 h- p6 N) K: V
  47.   else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
    6 X% Y" ~  T( U3 i, w
  48.   {% k' i) S0 d+ c+ T2 m: g3 h
  49.     sector = FLASH_SECTOR_10;
    # F# ~2 k. \, ]) h
  50.   }! R8 A- w7 e" ]/ C6 ]$ G
  51.   else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))
    3 P. U# f; \; r; j% A
  52.   {9 o( D( D7 n. T* Y7 j, V7 Z
  53.     sector = FLASH_SECTOR_11;) \) a9 |  \( f" I8 ~% O
  54.   }
      l3 X8 c0 c8 p# Z5 M2 ]
  55. #else
    $ v0 l% x% X; p- w
  56.   else if(address >= ADDR_FLASH_SECTOR_7)
    . B  y! M8 _' p
  57.   {/ V4 a  K& w" h% V
  58.     sector = FLASH_SECTOR_6;: y3 w2 d- u# ~' a, ~5 y
  59.   }. [1 Y6 D; K- S2 U+ U8 X4 d2 ^! x
  60. #endif
    " |; j7 K, }9 n+ z; \: T
  61. 4 \9 P: ]/ Q. t
  62.   return sector;
    4 K: S  T6 T( \
  63. }3 C1 Q. e6 P& Z- |

  64. # j8 W: I4 K+ B6 ]3 a# Z9 ]3 }
  65. // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。( K. n/ F0 X4 ^: }4 d8 A
  66. void SocFlashErase(uint32_t addr, uint8_t count)& n9 K. ]+ D* I7 U) j2 [$ e# M
  67. {
    ; V6 V4 i1 R' A7 i' w7 {' @% M
  68.   FLASH_EraseInitTypeDef flash_erase;
    ' x% i" G* R4 t0 L. H' \2 `
  69.   uint32_t flash_error;
    6 W% H  k7 J* N! N& [  ?: E

  70. + M+ Y9 ]" g1 F
  71.   HAL_FLASH_Unlock();
    8 q( J! C8 j7 _+ i" O, f) c

  72. ( E% T6 T" Z3 `2 }# g* Q+ c* N6 p
  73.   flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除
    4 w# P( L! Y$ P3 A/ d9 ^
  74.   flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区
    8 I& v7 U) I. K, V
  75.   flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
    5 [0 I2 q/ P4 t- ?- b# W! b8 u
  76.   flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!* X4 w# F8 f5 M- m+ L5 w9 K
  77. % z8 [6 p$ B, U1 }, |4 ]5 C2 c
  78.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |, ?, @. ?  X  g% I2 h
  79.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);  f. E! A+ ~' p0 j* D

  80. 2 P( @8 d% h, V: H1 T" x3 V  ]4 Q
  81.   HAL_FLASHEx_Erase(&flash_erase, &flash_error);( P' e8 M3 i- I# j6 c
  82. ' r$ j! e( C4 d# N
  83.   FLASH_WaitForLastOperation(50000);) h/ G8 E, H) a4 I; k& O
  84. ' q/ G6 s: \/ a$ F' @2 E& g
  85.   HAL_FLASH_Lock();) N: M/ g$ @/ c: d4 u( l
  86. }: `4 W3 v% z$ C$ W% O' t$ q4 P

  87. 7 |; {$ c: c# C
  88. uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)6 ]  N% y& c( T& ]
  89. {
    ) e* _4 M. a8 L1 M2 z* y
  90.   uint32_t i;
    8 g( T, [- @- U1 v; ]) j. a" q  J7 q* ~
  91.   uint16_t data = 0;
    4 V( ]- W: A$ x4 r4 L, ]0 Y& q

  92. 5 K# G. X* u* ]5 m5 X( f  A5 N3 A
  93.   if (length == 0)
    & h' W* W6 h# T" v& \
  94.   {, Q, C/ F  f6 z0 ?0 S# }: k: S
  95.     return 0;
    7 |3 G  B+ X% w
  96.   }( u) G, l* Z& |7 ^5 q# c  V

  97. / h: e) ?! _& F* k# m' n
  98.   HAL_FLASH_Unlock();* [% Q% |: B! p3 L8 k3 ?( u5 \

  99. ; W  U& V7 K$ _$ z. U7 h
  100.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    ' a0 ~* S, Q# q8 i! I
  101.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
    7 |, ^8 f, Q7 w8 S  V  A; U8 y
  102. 8 B# Y. Z' H9 V$ }8 M. v+ m  w
  103.   // 按半字编程
    5 k( ]# i' |# @
  104.   for (i = 0; i < length; i += 2)
    8 o1 y. z+ `( G0 ^1 ]1 v. n4 ?
  105.   {7 d" O5 d5 H5 b& {
  106.     data = (*(buffer + i + 1) << 8) + (*(buffer + i));( t9 k7 B: i. A9 u8 a( Z
  107.     HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);
    / ^8 S* O: h! @9 F- t
  108.   }/ t& R* |, j: `
  109. 3 I3 K/ j& {; V/ \$ G7 R  h
  110.   HAL_FLASH_Lock();$ Y: W; Q% Q; Z& E

  111. 4 ^) {# a: H4 A
  112.   return 0;
    6 J5 S1 x1 s& w" X! G2 ]
  113. }5 i: l. S# s; x- a, f* y3 T! ~
  114. 4 f4 ?7 F- L2 C1 D; j
  115. uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
    ; k* w0 f9 C4 \% t! C4 D
  116. {) O/ s  X' ?  B- G1 Q
  117.   memcpy(buffer, (void *)addr, length);
    : S- e) M& ^* ^" d. m
  118. : \5 ]5 H) K9 j2 O+ \
  119.   return length;7 i6 w/ v: S& y4 _7 ^9 W9 C
  120. }
    - \  r6 z* I+ b  D4 O
  121. 1 t8 @* o. n# I6 M4 `
复制代码
& s% J0 \2 Z" W6 b( F

4 m, l9 c0 f5 h) t
收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

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