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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。
8 b1 c1 V( ~* ^  ~; j
( n0 p+ Y% X! |& ~
  1. // STM32F767IGT6: 1M flash
    9 m7 r. d% A  s
  2. // STM32F767ZIT6: 2M flash
    3 H. I8 D4 X- I7 L& ^( D
  3. #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
    $ v$ x- d( |- o& J6 `
  4. #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */7 |5 t/ Z" P$ D0 V& B1 I; A' r' V
  5. #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */
    9 k) S$ C- l2 E% @) k4 f+ b- U
  6. #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */5 g0 P+ V" n" f. e
  7. #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */& Q: S7 Y2 K  N6 L( o* O: e
  8. #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
    9 W8 ?3 ]( ?' S, a" l$ S) |# B( ]) ^
  9. #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */& y8 I/ a( Q* b( ~0 k) u8 M
  10. #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */  @' N4 P: h/ P2 T: y$ `
  11. #ifdef STM32F767ZIT6
    " c  O3 Z6 M& e1 {
  12. #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
    3 B! U& X: `# F+ K. r
  13. #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
    $ ~8 s# G) o* |  v
  14. #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */
    ! o2 [' A: }# L7 E+ ~
  15. #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes *// r. Q& }2 G5 x0 b5 o: C
  16. #endif
复制代码
  1. // 获取要擦除扇区编号% y1 m0 I5 G4 {; B% H
  2. static uint32_t flash_sector_number(uint32_t address)/ e  c- F( p5 [
  3. {
    5 H: K1 F/ M0 \1 B" w$ W# W) B$ q
  4.   uint32_t sector = 0;
    : P  S- ^% F& K, l, W8 [

  5. * w3 m# y- D$ v6 ^5 X/ j
  6.   if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0)): `" C$ X+ B9 x% ^; C$ Y: B! x
  7.   {
    5 s6 X' a  K, c4 `: ^4 ~% u/ \, @
  8.     sector = FLASH_SECTOR_0;
    ) ~# R5 h- B) ~7 P. {
  9.   }1 t! _2 C, y& W0 s
  10.   else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))* t/ p5 ^, f& J+ z
  11.   {4 f4 I! b* \% I4 e! o% D+ q
  12.     sector = FLASH_SECTOR_1;% \' c% V7 [- ^
  13.   }+ q7 Q( [9 I' Z, {( D7 ?% P
  14.   else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))- I( @1 y; b& ^: ~0 d
  15.   {) k( E& I" `* B. G- _: V) [( G+ ~3 q0 w
  16.     sector = FLASH_SECTOR_2;  L3 R' r; f! u6 g
  17.   }
    - ^7 g  Q. E" Z  Y2 a. H; }1 W
  18.   else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))
    1 |! F+ Z9 P) W9 ]5 X7 @9 b8 b
  19.   {3 p8 q& H0 {9 [5 Z5 |4 q1 N
  20.     sector = FLASH_SECTOR_3;
    0 Q' h* A$ \* g/ m- \% A' \: ^& F
  21.   }
    # K$ A- ^* B+ ~7 v! A* S  x; }
  22.   else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
    # @+ R! d# M3 \; f1 d
  23.   {8 e, H( Z5 F/ j- b2 \
  24.     sector = FLASH_SECTOR_4;
    , p' Q% t8 w7 r9 B5 P1 A4 ]  P
  25.   }
    " a" v" U  b9 A& T, |$ v
  26.   else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))1 i  Z0 @  A  [* t
  27.   {7 E5 ^  J& ^4 I, D# l
  28.     sector = FLASH_SECTOR_5;* V/ O9 M8 H$ R: |: ^0 L
  29.   }( p0 a4 R1 e+ _3 d4 V; j
  30.   else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))
    0 b! v- r. G. a4 F9 V1 @
  31.   {' s; w- _/ B% q
  32.     sector = FLASH_SECTOR_6;' e' r, k. P3 o: {% d" A! o
  33.   }
    * p, t2 _& s/ s: E: d' `9 o
  34. #ifdef STM32F767ZIT69 E. a" K9 c/ z
  35.   else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
    + p1 Q( x( X% r( x% d4 ]
  36.   {' Q8 b6 S  `; B- L  {2 y+ o
  37.     sector = FLASH_SECTOR_7;
    - F( {, b7 N8 h; H5 H$ Z
  38.   }
    ( t, ]8 Q7 G; \$ `) e( z+ M
  39.   else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))& C5 {  p) E+ W4 ?  c! T
  40.   {' z" H* J$ a# Z8 q
  41.     sector = FLASH_SECTOR_8;
    + Q: G* W* z$ d! B0 }9 D! Q* b+ z2 T
  42.   }
    3 B9 ]8 N( E; S4 W. ?
  43.   else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))+ X0 p- v" Z# n
  44.   {& q: B  @' T* K9 b8 Q1 o
  45.     sector = FLASH_SECTOR_9;% D; b0 c, O3 e' Z) }: o, {
  46.   }
    ) Q! R8 o6 R" I
  47.   else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10)): a  G! E0 H$ n) Y) q  G
  48.   {0 _3 O! j8 r$ F6 P# D/ P
  49.     sector = FLASH_SECTOR_10;! l+ }8 b/ }: `5 O# m
  50.   }
    ! I8 ?) l% j* K9 `
  51.   else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))
    : E7 @4 y% b$ Z& _7 P+ A/ s/ {
  52.   {) _5 V2 M5 u# [' s, {* O
  53.     sector = FLASH_SECTOR_11;: Z# i4 h3 w8 E: E
  54.   }. o8 E- d$ l% D7 x( W. l
  55. #else
    3 j7 A! r- D: G  N; y- _! Q
  56.   else if(address >= ADDR_FLASH_SECTOR_7)" \: s) |9 w5 q
  57.   {
    2 h) x$ s- {) l3 F, k! O
  58.     sector = FLASH_SECTOR_6;0 \3 [/ M4 s  X* j2 x
  59.   }
    $ @8 x. ^" ^" J8 {
  60. #endif
    1 z! h, `1 g) Q! D) C1 e
  61. 0 ?: m  ]( h9 p
  62.   return sector;
    0 |% j4 Z1 D) t. Y' b+ a
  63. }% M; Y* Z' {& a4 Q) D
  64. % N" Q: }6 w, S8 I7 |* D
  65. // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
    & c7 w9 J$ Y" z7 B2 B$ I
  66. void SocFlashErase(uint32_t addr, uint8_t count)  H7 G$ N( H- u; i! |
  67. {
    . d# J5 n/ f/ |
  68.   FLASH_EraseInitTypeDef flash_erase;2 \) T& f* Y' |. C7 _
  69.   uint32_t flash_error;" ^% }  e! e  b: L5 v. c" }/ s

  70. 0 ~5 U$ D/ P' j
  71.   HAL_FLASH_Unlock();$ r; S4 }* ~. W% K' c

  72. . F3 M* [6 W0 N
  73.   flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除$ b8 J# U7 `# h7 L- R/ W
  74.   flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区
    & e# U1 w( i4 a: p8 H: h
  75.   flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
    3 b# Q6 N0 @9 o( V
  76.   flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!: V: c& B) O+ f3 R1 T

  77. " V( V; h, G) L% F9 s4 r- B: a
  78.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    3 D+ ~3 N! f8 r5 j# {+ H% J
  79.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
    7 y9 r5 Y/ R" ~& ?0 g! q' N
  80. ) X0 P6 h3 k+ ?6 O  y
  81.   HAL_FLASHEx_Erase(&flash_erase, &flash_error);7 e4 y0 n. r3 K8 g0 W6 J

  82. 5 q; k% d/ Z2 D1 U: u7 i( d
  83.   FLASH_WaitForLastOperation(50000);5 r8 r+ b& e! ]5 ^+ q4 O) L+ F

  84. ; Z& Y5 @( K" q2 Z5 Q
  85.   HAL_FLASH_Lock();
    3 d/ u3 ?0 Z8 L
  86. }
    3 J5 P7 V; y* P& l4 Z& S  l) ]
  87. 8 Q) b9 r- _3 b2 m  [6 u
  88. uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)
    * P* x: _1 t. \1 `/ z
  89. {
    3 G  y$ f* a* r; i/ @
  90.   uint32_t i;
    1 d8 Y  p/ ^6 h8 V- x$ T. F
  91.   uint16_t data = 0;
    7 i, r+ P- K+ Y! \
  92. 9 w7 c0 B9 a7 P  z0 r
  93.   if (length == 0)
    4 n+ s& N; ?% J' g
  94.   {$ }( n; F0 @9 x7 ?/ S
  95.     return 0;
    1 K2 r$ q4 Q& [( s: n
  96.   }
    $ T) h) L! A/ r: w) f7 g' n
  97. " w4 a8 _. b6 V$ h
  98.   HAL_FLASH_Unlock();
    ( p4 ]# U5 I. Z7 p& e5 Z

  99. - r* O- t, N* Q( m3 w0 u- O  }9 j
  100.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    1 L6 ?9 n& C( I" R# H) b
  101.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
    0 a4 A) [3 d8 K1 Z, r0 k, T" c! F7 z

  102. $ x" H& `/ C' i" ]1 W
  103.   // 按半字编程
    1 h& z- S* l$ D/ q
  104.   for (i = 0; i < length; i += 2)8 v/ L" g( g& y" `3 K' b9 i- B
  105.   {2 C$ g* ~1 n$ O, G2 U
  106.     data = (*(buffer + i + 1) << 8) + (*(buffer + i));- n& c: c9 F2 W! u7 ~
  107.     HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);; ]5 [* ^% P  s
  108.   }7 J/ g( F8 D4 \. N

  109. / Q0 Y  K4 S$ W# h6 [4 y
  110.   HAL_FLASH_Lock();
    0 U' R% {" {8 C. [1 |4 R

  111. . s, v5 x/ m: m3 M% h/ H6 [9 R
  112.   return 0;. o0 B/ F& B! ]9 Z$ d
  113. }
    0 K2 z; \+ e! @2 `" x1 }) d% k

  114. % [( D7 j" L3 Y( J# A
  115. uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
    $ ]6 m0 R7 j  B9 X6 q# q0 X
  116. {
    $ \8 P( l% J, ~2 j5 i9 X
  117.   memcpy(buffer, (void *)addr, length);
    % ~5 x* J/ C3 D8 ]7 g: W" a# U% U

  118. 9 D( d. b/ j' ]3 {/ x# Y7 R- ~
  119.   return length;9 h5 e2 p* @5 C! R/ U
  120. }
    & d7 G& a6 `9 H, M! i& r
  121. ( D. R; ]$ D) k/ q
复制代码
7 G5 F* g, d2 n5 d$ m

3 Z; \, I+ d; i; \: J: z
收藏 评论0 发布时间:2021-12-11 12:00

举报

0个回答

所属标签

相似技术帖

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