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

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

[复制链接]
STMCU小助手 发布时间:2021-12-11 12:00
这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。
: X- Q% p0 b& x( ]$ `8 k9 v8 ^6 n9 l0 B
  1. // STM32F767IGT6: 1M flash
    4 _* o; g& ^! S! M( n1 k2 Q1 f
  2. // STM32F767ZIT6: 2M flash) ]" W. `3 u1 A$ R
  3. #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
    & V% v" x" N' a; }1 u' M
  4. #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */) m$ N6 ]$ p- g% C7 I: x3 b
  5. #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */& @! ]4 q+ t5 |/ c) C
  6. #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
    1 p5 b9 X1 Y. I& R; P
  7. #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */+ N" j2 q0 g8 o0 N
  8. #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */! j( Z, t; c4 S5 G) {/ S! }
  9. #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */
      W( a; q: Z0 G4 L; a' L. k# x
  10. #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */% [( u' ]3 T2 t5 T, H
  11. #ifdef STM32F767ZIT6
    ( B0 O  L" _3 B/ s# q0 f
  12. #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
    # S! x( U2 E# z  U
  13. #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */$ ?/ \$ \1 m/ ?+ m' Y" s
  14. #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */
    0 K1 }2 O( A8 m; ~
  15. #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */( i* u( k' E4 i* M  p3 i
  16. #endif
复制代码
  1. // 获取要擦除扇区编号
    6 `  R) p* W- W: l6 k
  2. static uint32_t flash_sector_number(uint32_t address)
    . ?( T/ _1 `" u4 T3 H0 {# N3 W
  3. {
    ( s% ^( ]: i/ _2 i, U$ i
  4.   uint32_t sector = 0;0 C/ c7 C. h$ `! [2 p) }( g
  5. # A% t4 O8 y* v( M, {5 _: s. @
  6.   if((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))5 Z/ t, y/ A' A% X6 r9 U
  7.   {
    4 p; ^1 E" `' V% G$ [$ ?
  8.     sector = FLASH_SECTOR_0;2 X- k0 q& J' [2 w; |
  9.   }
    , |' k) ^, F9 O. \! Z8 c% j
  10.   else if((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))* z& G# u% ~1 d, n
  11.   {( N0 i0 X( A( b; j/ A/ a7 e
  12.     sector = FLASH_SECTOR_1;! w# U7 m) o) S' `. n5 S
  13.   }
    + q- A7 i7 z, D- h" a9 Q0 R3 `7 r
  14.   else if((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))
    5 f' k  n& T7 ^4 T3 f5 t% M
  15.   {
    ; _* X( `3 ~" z4 Y' ]
  16.     sector = FLASH_SECTOR_2;: {6 L7 d( u8 a" x9 D+ P' J% E
  17.   }
    9 A4 M- |8 I/ E8 B& A
  18.   else if((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))
    9 A0 n" v. @% i
  19.   {
    ( a" M) M  @- m, C5 @1 m  O
  20.     sector = FLASH_SECTOR_3;* X( r) I! U! y0 `0 D- K
  21.   }3 C2 J. ~& k6 B9 I- I( A
  22.   else if((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
    ) O- {" o; ^* u2 C8 F* f: p) o
  23.   {
    1 t0 N  ^" K6 M- J# o$ u9 G7 j  Y2 ]7 Y, K
  24.     sector = FLASH_SECTOR_4;
    8 e, k  ?9 |$ b( g5 Y
  25.   }
    1 _( d* d  u  U  a. ?. u6 x
  26.   else if((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))7 F: l4 o! r# ~. ~
  27.   {
    $ `( P+ A/ i$ P9 X) T' V
  28.     sector = FLASH_SECTOR_5;" U: Y  b) p3 U' e
  29.   }
    ( D# @7 @9 q1 i, ?5 k7 G( P8 d; q# x
  30.   else if((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))* U$ j! G9 ?+ J+ X- d6 z; E
  31.   {1 s, @0 s5 x$ [1 r1 ]8 q. q
  32.     sector = FLASH_SECTOR_6;4 f# C4 i8 I1 R; |% Q
  33.   }1 L" ]% s+ v4 F: b2 W* D
  34. #ifdef STM32F767ZIT6
    2 Q5 J; B  G4 a' F! r
  35.   else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
    : |1 v) e! ~) I" F8 I7 d
  36.   {( U7 b' a1 V8 K, s# ^! g5 b: B# d) i% w
  37.     sector = FLASH_SECTOR_7;3 F4 Z3 d1 v3 K. Y+ A" v1 c6 _1 k
  38.   }
    * ^0 b, V% E5 V
  39.   else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))/ \; b  |, Q0 T' }) M
  40.   {
    ! Q! z; h3 [) `9 J/ _
  41.     sector = FLASH_SECTOR_8;
    . E7 @6 g& [" \3 A) L
  42.   }
    # a: _1 m; Y' n9 f2 U- Y
  43.   else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))$ F- q1 q6 Q* x* @
  44.   {
    7 Q7 Z% \  [9 [% S* _: H
  45.     sector = FLASH_SECTOR_9;
    ! J+ y8 d0 t2 y6 K6 M% z
  46.   }
    % q1 l8 `4 _: L, g; v" p
  47.   else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
    " D+ e7 n" N$ `- t$ i4 j4 Y
  48.   {: n# s8 x& m1 Z( t; z
  49.     sector = FLASH_SECTOR_10;
    4 b& V( s2 X0 s2 g' i) q! R
  50.   }+ W0 `8 k& b3 {2 l9 @' x
  51.   else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11))" V( t/ F5 B3 X8 O6 k
  52.   {
    & ]5 L( G% o8 G- ]. M
  53.     sector = FLASH_SECTOR_11;$ T9 g. k5 @8 W  Y( ]4 h
  54.   }
    9 {# H; q7 D6 u+ B
  55. #else; {+ |$ z( ]- V4 L4 \, w% Y& O: V. {
  56.   else if(address >= ADDR_FLASH_SECTOR_7)* \0 a. }# \% c. E
  57.   {2 E  `  b0 u5 a' R* C0 l; p2 U: O
  58.     sector = FLASH_SECTOR_6;
    * T4 I; z4 R2 h5 p# v0 k
  59.   }9 C# d  J0 r) w# ~; X7 Y7 v
  60. #endif
    8 v# Z9 B. {0 y, k/ C: N
  61. ) E! u' b9 ~* ^- T
  62.   return sector;/ E' J; J9 k( a, b2 J$ }7 W  `
  63. }
    1 S* T1 u8 E2 I2 G& M2 v- m& Y

  64. , q8 W0 j+ d9 ]' w, a+ P' c8 C
  65. // 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
    8 Q9 Z; [+ _, t
  66. void SocFlashErase(uint32_t addr, uint8_t count)0 M1 i6 @' o; f' f# n" @
  67. {
    2 T& g9 |8 {. c! }- s
  68.   FLASH_EraseInitTypeDef flash_erase;. M/ Z( ^7 t/ g! W' q2 q
  69.   uint32_t flash_error;
    $ m0 Q7 s7 `/ v1 W1 i. t/ J! p( O$ o
  70. : _) `; c8 v3 @' Z/ w& c* L0 `2 U
  71.   HAL_FLASH_Unlock();
    ) d) l% Z2 N: i) J  R8 E

  72. 6 ?: ?# {- Z. \
  73.   flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除
    . o* n% F" Z0 G% l# ^2 Z; |
  74.   flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区  C9 I# p( l% L
  75.   flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1
    + n& }8 J$ x) F; A/ k
  76.   flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!1 _5 m+ n: |2 |0 ^/ l
  77. 6 G, e% I' R; [: k7 I
  78.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    2 d4 f+ L; M3 N& P
  79.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
    7 Q5 W; m6 K+ T  a

  80. 3 D/ h5 H2 s! U. w0 S! k
  81.   HAL_FLASHEx_Erase(&flash_erase, &flash_error);# F3 h2 p5 F* ?" L7 p

  82. $ {1 t, E- i; H" ]! m6 P, Y; {
  83.   FLASH_WaitForLastOperation(50000);
    9 p1 e3 X6 L' W/ E
  84. / v" U6 r: p* |! t. H% m
  85.   HAL_FLASH_Lock();# {! q3 C% `$ ^
  86. }
    : o" [+ e6 Q, A: x, l9 |

  87. 3 P. U+ ~3 Y0 L; u) Q
  88. uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)
    - {( W. Q3 @9 G- a( J, q
  89. {
    . a% }, u; x1 c
  90.   uint32_t i;; @4 k. w( A' {  j8 V3 q  W5 r
  91.   uint16_t data = 0;
    " [6 V2 _- P5 Y- H7 O2 J
  92. 9 `" ]' B' E  |$ F
  93.   if (length == 0)
    ' S4 Q  @5 p, a2 @  o: i
  94.   {" J) A6 G" _0 s5 F2 c- c  q
  95.     return 0;
    % i  B" m. L4 a9 U
  96.   }
    & E( ?  a# B3 Z6 a' v" n3 a

  97. $ E+ X$ U' |+ ]3 Z
  98.   HAL_FLASH_Unlock();
    1 h) [# L: A0 c) F; ?

  99. ) |3 ]+ [9 P" O) U
  100.   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
    $ A. S9 ?1 a( ?0 ?  G0 m
  101.                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);
    ; x# a2 W+ ^: e- b" H1 K
  102. 9 o/ z; N' U4 u. ~
  103.   // 按半字编程
    ; b, I: R& N7 C( D) V
  104.   for (i = 0; i < length; i += 2)+ V% [% Y) \, g5 C) Z0 g
  105.   {
    * f+ ~2 H* S6 Z; J7 M; ~8 ^
  106.     data = (*(buffer + i + 1) << 8) + (*(buffer + i));$ y! G1 f" ~" u2 Z" w& H* _6 M& o
  107.     HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);
    ; I0 C$ A, y$ n3 ^
  108.   }
    . ~' l4 h: x: S0 v) f8 x

  109. * z4 E5 I. b8 v8 G
  110.   HAL_FLASH_Lock();
    . u  R2 p, s  D% J; `

  111.   Y! b: e3 F3 R7 v
  112.   return 0;! N9 a% I% o4 M6 Q$ z# G4 V+ n0 u
  113. }
    5 w' f' z; \: G( x+ F: b
  114. : v( ]$ c$ E3 Z+ h1 U7 q
  115. uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)& f; \# R7 ^1 o5 W
  116. {3 i6 C7 f. N. W+ n5 I9 L* ~
  117.   memcpy(buffer, (void *)addr, length);; a" e3 a7 O" U' F8 Y

  118. , Z+ z1 w. ?: h2 [1 m3 ?
  119.   return length;  j, l5 b% W8 c' h3 b
  120. }- U' L5 T# m% d, I3 p) k
  121. 0 E3 ?- D. f5 |; E- g: |5 W
复制代码
8 `* e8 I. g3 }: j
. ^" {+ P+ G' A9 H- ?$ N/ L
收藏 评论0 发布时间:2021-12-11 12:00

举报

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