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

【经验分享】STM32G070进行flash读写操作

[复制链接]
STMCU小助手 发布时间:2021-11-10 18:02
STM32G070的flash读写问题# |) W4 t* V$ }/ y2 i: O
STM32G070xx的flash分布如下图,打算将Page 63用于保存用户数据。, v9 B2 T/ i3 _( S$ @2 I9 x$ G+ U

# S" G' u1 m7 a1 ^1 \% N
2019102511214233.png
& N' @. @5 w$ Z7 g3 p( G

' p3 C$ U& B% a. D5 z问题
0 q! r# Y% [' M开始一直出现flash写入失败,从返回码来看是FLASH_FLAG_PGSERR,一直找不到原因,代码如下:
" V9 ^0 M4 _1 u' P. g; }
5 x  w/ G! N9 W6 G; h/ ]6 [" u* e
  1. #define ADDR_USER_DATA  0x0801F800; {% Y! J& \* T2 j

  2. 2 e9 u7 ~5 i7 M. e( L# Y  v8 \
  3. HAL_FLASH_Unlock();
    + K: n/ _2 J2 v9 `
  4. FLASH_PageErase(63);5 w3 O: Y) f& u9 L
  5. ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, ADDR_USER_DATA, (uint64_t)data);
    ) u, a( E8 Y5 j. Y* m/ {: y% H
  6. HAL_FLASH_Lock();3 l6 e" v; n/ [3 g$ Y: x
  7. ' Z" h# V; S* U! W
  8. if (ret != HAL_OK)
    * L8 Q+ L5 q, ]: w% l$ B- a- F( u: w
  9. {. H$ Q6 Y, \: X8 ]
  10.     printf("\r\nuser data save failed, ret = %u, flash err = 0x%x", ret, HAL_FLASH_GetError());3 p& t$ O" u0 W
  11. }
复制代码
, M- p4 Y$ b+ b) ^
2019102511181630.png
5 M) V. C4 _/ ]- ]
9 D# j* P2 ~# J  Y% X
后来终于在community.st找到了答案:  }/ s+ Y1 {' n. I% v

5 ^3 X4 a+ g+ l: l
20191025112810625.png
6 |( s6 Z9 g3 S1 c6 t; Y: n

5 E0 ~1 |, p9 R2 R- SSTM32G070 flash驱动代码1 d& e7 S4 F$ k! W) s$ M7 K
好了,话不多说,直接上最终的代码,亲测有效:4 x1 {9 h! D% L" F0 s& `0 U! P5 ?
, e# W% U; `9 W/ M
  1. HAL_StatusTypeDef flash_write(uint32_t address, uint64_t data)
    / O6 f% I1 q* a5 O5 N  ^  w' o
  2. {
      E$ @( c$ _' a$ [
  3.     HAL_StatusTypeDef ret = HAL_OK;
    / h0 ^1 u  w4 \, k
  4. 0 I4 C% c; K( a% k" F
  5.     HAL_FLASH_Unlock();
    % N& O; V' [+ w# K5 J" b' x. n
  6.     ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, address , data);
    1 s+ W5 b. f3 c1 ^, v$ g
  7.     HAL_FLASH_Lock();
    ' P0 S+ a) m/ A7 p: f1 g! i! f! l7 \
  8. 6 r& y  R; z9 W  q+ C
  9.     return ret;/ U2 W; e# N! F, ?8 m$ E
  10. }
    . z+ f  P# H! {0 F" @

  11. & m% ]; v. l# C2 `
  12. void flash_page_erase(uint32_t page)+ P+ p3 \# J) b% ], C5 a) _
  13. {
    . |- A: m- g5 a" t& U9 Y1 t# X
  14.     HAL_StatusTypeDef test = HAL_FLASH_Unlock();
    8 J( ~# O" {+ L" A1 q

  15. 3 H  d* G7 l  u1 |5 q6 @& u4 V. h
  16.     test = FLASH_WaitForLastOperation(1000); //1s timeout
    + T& ~' @$ [1 L8 y4 H; M
  17.     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);3 O: [8 Z2 N( _; U& y+ }/ f9 W2 O
  18.     FLASH_PageErase(page);
    / j# B- T3 J) |# j
  19.     test = FLASH_WaitForLastOperation(1000);
    5 g4 m/ e0 H6 K# v6 E& ]7 l3 _
  20.     CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
    , w3 ^7 M( z3 w1 K  s5 M

  21.   C+ @* U) [. \$ \( E; B* F$ D$ ~0 D
  22.     HAL_FLASH_Lock();' a8 ~- b  z* _" M  f- K% [( {
  23. }
    1 L* e+ c  B- P* c0 f

  24. % \" J3 x4 s$ e+ {6 `
  25.     /* 调用上述两个函数即可实现flash的擦除和写入 */
    % N- k  o0 o3 ~  b2 h' ^: i+ o: k
  26.     flash_page_erase(63);% T, j3 ]5 p$ }" u; d4 y% c6 l
  27.     ret = flash_write(ADDR_USER_DATA, (uint32_t)u_data);. w" o% j' m3 d- Y5 P
  28. 6 G& j2 S" n' X; L% v7 i
  29.     /* 读取的话就简单了,直接使用地址即可 */! u' ?* c1 X. ]6 A5 P$ D9 w
  30.     uint32_t u_data1 = 0;5 Q# ~/ y, a$ O; T- T) s3 p+ K# r
  31.     u_data1 = *((uint32_t*)ADDR_USER_DATA);
复制代码

  P# f$ c: }3 {5 R% v; [; V注意点% e+ J6 ^7 [- C
flash_write每次写入的是一个uint64_t类型的数据,其最终调用的函数为:
% v0 a: C/ X+ b( j

  1. % }3 h2 E1 z7 P$ O
  2. static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
    ; [/ N( l' S: Z: h* d- j5 l5 w5 |
  3. {
    7 d% W4 ]; C2 b3 Y  [9 H* P
  4.   /* Set PG bit */
    6 f- i4 l7 f% O7 G+ y5 w5 g
  5.   SET_BIT(FLASH->CR, FLASH_CR_PG);! N" p/ Q4 ~" O) @

  6. ( l' P5 _7 e- s; w+ ?
  7.   /* Program first word */! A% z  U4 v; M! e3 S
  8.   *(uint32_t *)Address = (uint32_t)Data;: @3 z4 {& M2 b/ [$ T( n

  9. ! g+ l& \" |$ A- R. C4 |
  10.   /* Barrier to ensure programming is performed in 2 steps, in right order' }0 O4 D+ o8 M6 ?3 U
  11.     (independently of compiler optimization behavior) */9 c( J# @7 C+ O3 l
  12.   __ISB();
      u5 y" Y3 E! D$ N) n1 q6 j

  13. 7 A: a4 R* |' r# q2 ^' U& k  r
  14.   /* Program second word */% W3 i; S& x6 \4 Z" h$ H7 R, l+ Z
  15.   *(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);
    . T% m/ L" S/ \" ^6 |8 r
  16. }
复制代码
! J9 p: ]8 v# V2 @2 }. v3 K9 O# g
该函数每调用一次,其实是写入了2个word,所以在使用时需要注意Address的递增。. n6 y4 `9 e, a2 o) j
/ n7 q+ K& C1 ^1 O4 ?

) c' w; b% L* N6 {. B. [) O
20210405170242660.png
20210405170242660.png
收藏 评论0 发布时间:2021-11-10 18:02

举报

0个回答

所属标签

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