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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。! C2 T+ K! n& d+ m7 ^+ @7 D' m

" d4 |) O5 o$ b) J
  1. // STM32F767IGT6: 1M flash
    " S# g- m. `7 t
  2. // STM32F767ZIT6: 2M flash5 {0 [7 @6 S9 h4 v7 k' M
  3. #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
    1 x$ Q6 p; Q5 G% J
  4. #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */
    ( B9 |' M' N  }1 F
  5. #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */
    4 J7 R% z% B0 B5 [0 _
  6. #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */+ o! V/ e' }+ @  z1 D
  7. #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */
    ! v7 D8 O7 a$ ~- C! ]
  8. #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
    4 Z! Y1 m% q1 i) ~) X7 o" p
  9. #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */5 u* S" a4 u8 F* e* R2 b! g
  10. #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */6 q8 _8 A5 r9 T- ~  L2 L+ X) g
  11. #ifdef STM32F767ZIT6
    6 d  ~' q) j" _
  12. #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
    * Y" C9 n) |0 O- @/ ^
  13. #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
    - n5 C6 _0 c: r% j
  14. #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */; T5 M9 t/ X$ V  u5 H- _# B* o
  15. #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */
    $ j* q4 ~, V, K$ j
  16. #endif
复制代码
  1. // 获取要擦除扇区编号8 T2 M9 S$ u4 V/ M- j! w0 r
  2. static uint32_t flash_sector_number(uint32_t address)
    , c% ]; y% b8 ]+ w3 j
  3. {# q2 k0 U  k0 K8 y
  4.   uint32_t sector = 0;7 s0 e. E# l! j, ]  L0 }5 \- e

  5. 1 w2 R+ O4 H5 R
  6.   if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))& P: ^6 L0 y# F: D1 P( ^6 J
  7.   {# C& f) _0 P7 N% s  \9 x3 m5 c, v: I0 K
  8.     sector = FLASH_SECTOR_0;6 ?$ f1 Z' K& W1 d
  9.   }
    2 ^! Z0 U0 Y% Q* `
  10.   else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))1 Q3 i3 I3 o: F
  11.   {
    $ ^. N3 b0 ?. [* |
  12.     sector = FLASH_SECTOR_1;( A$ E: l1 B7 K- ]/ w9 f! @
  13.   }
    ( u" r* W* v$ T  s, m1 Q! ^
  14.   else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))
    6 z' B6 ^) A0 h7 X8 h" s
  15.   {* _3 r: e) h2 u- X
  16.     sector = FLASH_SECTOR_2;
    : w1 F; Q; A* C: m
  17.   }. Z3 e: S% ~$ E- `0 Y
  18.   else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))8 Z# p- P" u& {" k; w6 n' F% f
  19.   {
    1 i+ x7 P+ Y# M
  20.     sector = FLASH_SECTOR_3;
    0 d; x, }( b, f2 V# Q$ E
  21.   }$ }$ ?! ?3 N8 @* U
  22.   else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))+ i" }4 h# s! E8 N, W1 s8 x
  23.   {
    4 k$ @5 A' M( c, U+ c) s
  24.     sector = FLASH_SECTOR_4;6 l) n8 h6 w2 I2 e
  25.   }
      c' a" W. r8 C7 `
  26.   else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5)), d* T* ], g) t/ i+ T4 K* x! N! o
  27.   {1 C' l' M6 o% B$ `2 Q) `
  28.     sector = FLASH_SECTOR_5;/ }9 ^) |2 K( C& d1 S5 N' u
  29.   }, u; Y( ?- o/ f6 \6 K
  30.   else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))% Q: i9 _" }7 _% L0 L7 K( B
  31.   {
      C' i$ I% R+ e6 J2 O
  32.     sector = FLASH_SECTOR_6;5 ^  s& q5 _; u/ s
  33.   }
    * I) r& V# W2 U* \8 l; E
  34. #ifdef STM32F767ZIT61 _9 G/ j: E# f( D# Y& \. R) g
  35.   else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))" d! \- ?: f0 W- u
  36.   {
    ) L) ?; O, i3 I0 r, f3 r
  37.     sector = FLASH_SECTOR_7;. l( g& V% J. H+ J- B0 u; @
  38.   }) {5 I' V3 y" S' q  O. [
  39.   else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))
    7 s* S) y, b; \. i! ?
  40.   {3 d& [0 M0 @+ t. g
  41.     sector = FLASH_SECTOR_8;) l" D- @, f+ K2 s% H* [: z) C' V
  42.   }/ a) {* i" A4 u8 S
  43.   else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9)). c/ b& ^: Q- }! r) L
  44.   {( `# q% F& L% h7 T2 ?% u
  45.     sector = FLASH_SECTOR_9;
    % u( j: t6 n; W4 c8 ~, r; `8 {
  46.   }; p! |+ m. s  ?/ j$ h* Q
  47.   else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
    8 O# H, X7 k7 J& o9 U! i9 p3 ^( R
  48.   {  w( c/ J7 [6 }! g' M
  49.     sector = FLASH_SECTOR_10;
    & \- Q1 F8 f/ M& y
  50.   }$ N9 z: j/ H! I; f- t- x4 K
  51.   else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))$ E, x( x3 C7 @' W
  52.   {5 z/ R+ t& Q* ?- B2 _- z$ j
  53.     sector = FLASH_SECTOR_11;
    8 i6 l0 ^7 L) P
  54.   }% v. ^6 ~2 |' b! ?9 G
  55. #else
    1 Q4 R# Q6 e4 e
  56.   else if(address >= ADDR_FLASH_SECTOR_7)
    6 Y7 Q, T6 Y9 z2 n: n
  57.   {: }5 z8 \% t3 v0 {  m% ^" C+ N
  58.     sector = FLASH_SECTOR_6;" a: d' ^6 Y2 G% p9 B
  59.   }4 W1 s% j) ^. }  q7 K
  60. #endif
    6 }# ?6 J/ r% X
  61. 6 R5 R! O9 `, b; X; C4 [
  62.   return sector;
    9 b6 n/ M+ {( H! w7 K5 D
  63. }7 o, b" C- \( T* x, f
  64. * K4 e8 b! g: d. u! s
  65. // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。1 K/ d' s7 h2 |" {4 U
  66. void SocFlashErase(uint32_t addr, uint8_t count)
    5 I' R$ r; [! T
  67. {
    1 g1 ]) j. `) t: P4 z- l
  68.   FLASH_EraseInitTypeDef flash_erase;
    " |0 ?" T; a2 T$ p+ m$ A: n) k
  69.   uint32_t flash_error;' Y* v5 r0 l% j) B; v3 D

  70. & a: u4 t2 r* B/ \9 Y
  71.   HAL_FLASH_Unlock();7 S' g# ^; `1 e6 k" _1 w9 z% `5 E

  72. . F+ Q! |4 q# O8 X1 w% F
  73.   flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除* B& h9 n0 U& u6 ^. B
  74.   flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区3 z0 S) P  }( U5 |- e& ?
  75.   flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1" A" e% \# [* s) d2 B; Y
  76.   flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!& y9 `& l1 x  `' x( c

  77. 2 t! u; x7 V) l  ^
  78.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    9 F" r9 X* ^  J9 b1 l
  79.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);3 W/ p) |4 P: v/ |, j
  80. ; E: L: p" c9 }( Y
  81.   HAL_FLASHEx_Erase(&flash_erase, &flash_error);
    % R2 T7 [9 V% j# `8 r- ^* P
  82. % q1 k# m( {6 i
  83.   FLASH_WaitForLastOperation(50000);
    " [9 u$ l* [' i4 W" A
  84. . T+ {0 g% g1 v" W% v# ~
  85.   HAL_FLASH_Lock();
    + Q1 [' {0 v/ I& u* c. j' J7 w
  86. }( r2 P) H" K& B8 w
  87. % i1 ^' i$ ^5 o' }9 x
  88. uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)# e4 \3 B/ ?8 s
  89. {) d9 j5 U. \: B. q, M8 }8 W
  90.   uint32_t i;9 V3 f" G+ U) D
  91.   uint16_t data = 0;
    , Q6 i+ S) n7 o1 k+ \  J% f. r: O+ }
  92. 6 ]% P4 p  B( O# v) P# B
  93.   if (length == 0)
    * H5 F5 K# ~8 J
  94.   {" g1 v9 T$ [( ?
  95.     return 0;7 K9 y1 [2 B' J9 W3 b
  96.   }( d( n( o6 X* p4 S4 v# l

  97. + r1 p* [2 I( F4 j5 i/ K
  98.   HAL_FLASH_Unlock();
    ! m- t, n& T* R+ L: H% b
  99. 7 y' h5 K8 K+ ]5 ~& n+ K: v8 _
  100.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |  \& Q% G6 r" L( C- f: T; B
  101.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
    % U/ c% U- O# @7 S% @  q" b* w
  102. 8 ?, E1 E% M8 E5 C
  103.   // 按半字编程
    ! w: |  A: D9 N5 m. F
  104.   for (i = 0; i < length; i += 2)
    $ P$ ?4 i/ z' c" o# S2 j$ s
  105.   {
    ) M- f- r+ `) i: W$ K
  106.     data = (*(buffer + i + 1) << 8) + (*(buffer + i));4 ^0 ~# a# Z5 v
  107.     HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);7 y/ D2 }/ [1 Y# {; S
  108.   }+ u- M" k# c0 I" |
  109. 3 x1 {2 A* m" E+ ?. V3 w
  110.   HAL_FLASH_Lock();
    / ?1 {- k/ c3 N9 y
  111. ' i/ m) E8 j: m
  112.   return 0;
    7 {% S2 _8 @# c! s' P: d; M
  113. }
    / d: F, D0 s* u; |& n* C3 R

  114. ) o% D# Y! `% M( |- i, e6 b3 Q4 }! p: J
  115. uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
    0 ^) v- X9 t  I/ P) u- Z
  116. {
    - e3 g  d) ]1 G2 G8 N. N
  117.   memcpy(buffer, (void *)addr, length);
    2 c; h; r0 E# H8 k, z, |, B
  118. : P) a9 |6 a; n, G
  119.   return length;
    * e4 c5 ~& R, X' I2 O
  120. }' s- C* v) V& Y/ f& E: I: s
  121. ( W/ ~; {4 @1 T) r8 ]
复制代码

. V# j3 x  s- [6 D$ z: r, r4 h% Q
收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版