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

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

[复制链接]
STMCU小助手 发布时间:2021-11-10 18:02
STM32G070的flash读写问题% S; x! J( P, b# o# \  n4 J1 ^
STM32G070xx的flash分布如下图,打算将Page 63用于保存用户数据。
1 u3 Z3 K  R  \4 \4 T7 G
! U1 _' F3 {- z; E1 W! Z
2019102511214233.png

( K* c" R1 f, a; u" G, m/ \/ a- S  a6 w& \9 ?
问题& c# w7 E: g8 h6 q& ?
开始一直出现flash写入失败,从返回码来看是FLASH_FLAG_PGSERR,一直找不到原因,代码如下:
6 y$ d, T9 p7 G5 x! E- t$ a7 v- ~. X8 d$ B% I0 Y
  1. #define ADDR_USER_DATA  0x0801F800# G2 L4 c' [6 ~' l! `: j

  2. ) |* Y0 W, q( N- k; S& c; w) ~8 ]
  3. HAL_FLASH_Unlock();
    5 l, [3 n. m/ j. n8 C4 y
  4. FLASH_PageErase(63);
    # ?0 Z0 D- r2 v( y
  5. ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, ADDR_USER_DATA, (uint64_t)data);. S7 r. a7 l. h) b- F
  6. HAL_FLASH_Lock();
    4 I( |0 D1 J0 j" K1 ]1 o
  7. & w9 e  A) X  @* J4 W+ |( x
  8. if (ret != HAL_OK)' k0 ?: M( F+ v' o- J4 P; I
  9. {4 Y# r5 n' E! l: H+ i9 T
  10.     printf("\r\nuser data save failed, ret = %u, flash err = 0x%x", ret, HAL_FLASH_GetError());& C' ~( \4 ?* Q, r. O4 z
  11. }
复制代码
, Y( l9 R; j2 o/ [8 l
2019102511181630.png
; c& {. P" _9 t: X

8 z& C/ c2 V5 j1 g3 u1 L6 O后来终于在community.st找到了答案:2 \% I4 s( K3 k1 a5 X, g
* q" @) L6 E+ v4 }2 H6 u
20191025112810625.png
2 [0 F; J7 z; P  I  o. e; S# L
: C4 c) N4 @; r: g8 `
STM32G070 flash驱动代码7 ^. ]% C' T# M5 J
好了,话不多说,直接上最终的代码,亲测有效:8 v6 _. h! z: p

" o+ {& w# c1 A$ L; H& L/ {
  1. HAL_StatusTypeDef flash_write(uint32_t address, uint64_t data)
    & K- J9 i- \! K1 b" `: |2 O+ W+ w+ T
  2. {
    + s1 z9 ~3 O" G) U0 X4 o
  3.     HAL_StatusTypeDef ret = HAL_OK;
    * {7 Y9 J* ~- z' {) Z0 M6 w

  4. . f! k) ^% ^6 ?) o
  5.     HAL_FLASH_Unlock();
    8 \; b* A) G  y- J3 n7 j) q5 U
  6.     ret = HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, address , data);
    " k9 [/ N7 w  }
  7.     HAL_FLASH_Lock();
    6 `, I7 W  O/ x' f& h) J
  8. 2 S1 b- p: }6 l; E- O" r
  9.     return ret;
    3 f0 S$ B- m7 J1 U8 ^; o
  10. }
    8 W- x' @0 s& i' ^: l0 X/ M
  11. 0 x, Y. P4 @3 q# B1 F: D
  12. void flash_page_erase(uint32_t page)
    ) a- e5 N. u/ c8 F
  13. {
    0 z0 s3 l9 n2 B4 Z0 m* r2 K; m# U& h
  14.     HAL_StatusTypeDef test = HAL_FLASH_Unlock();
    9 Z& _8 \8 r' t7 L$ n) q3 \
  15. : a) D- J7 t% U, S$ i$ a
  16.     test = FLASH_WaitForLastOperation(1000); //1s timeout
    2 |) r0 G  G, R7 k
  17.     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);! I' [1 b) ^0 R' S1 M2 H2 X$ T
  18.     FLASH_PageErase(page);
      Z. e2 _8 I7 K% z) e0 s
  19.     test = FLASH_WaitForLastOperation(1000);
    % ~% G, C. W" h4 Y
  20.     CLEAR_BIT(FLASH->CR, FLASH_CR_PER);: D8 J3 a- t# I9 g) f3 U; t
  21. 2 P( J: L9 [3 j8 M5 Y+ `
  22.     HAL_FLASH_Lock();
    , e) y; |1 h- b% |
  23. }
    ! c) `0 \' u" P# Q3 Z4 k
  24. ; `# c+ @8 f) n' P8 M
  25.     /* 调用上述两个函数即可实现flash的擦除和写入 */6 E: a( F  V- p. |: R! d5 ~0 c
  26.     flash_page_erase(63);
    # [( ?4 k7 I9 O, E9 C" _7 R. }
  27.     ret = flash_write(ADDR_USER_DATA, (uint32_t)u_data);
    7 K3 n1 W2 r# t+ {. d: s$ o
  28. 8 d. w: y9 J# Y3 |
  29.     /* 读取的话就简单了,直接使用地址即可 */
    8 M4 |; q% h3 L2 I. t. ^2 L8 [  M8 |! c
  30.     uint32_t u_data1 = 0;
    7 Z( W/ `" I" v3 v" f% ^- x1 @+ x
  31.     u_data1 = *((uint32_t*)ADDR_USER_DATA);
复制代码
. i. [8 Y  {' v5 w  C
注意点
, `& I+ d1 d7 }2 U7 e% Fflash_write每次写入的是一个uint64_t类型的数据,其最终调用的函数为:; Y- N  L6 w$ H9 t* V

  1. , g8 ?$ r  {6 e( K; \3 b) ~
  2. static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)( j6 G/ t6 J# ^% v- o6 K
  3. {
    8 |; h# V% ]4 P( }' `
  4.   /* Set PG bit */) Q' P' k: y; z3 q- v2 v# ?
  5.   SET_BIT(FLASH->CR, FLASH_CR_PG);, x; ?% k4 j! S6 G- Y! o
  6. # d: r, O% G: ]- m
  7.   /* Program first word */+ J9 c  W7 m* Q, r5 E3 ?9 m
  8.   *(uint32_t *)Address = (uint32_t)Data;
      G( P, e7 O' W

  9. $ s* X, |+ ^- E& r/ G
  10.   /* Barrier to ensure programming is performed in 2 steps, in right order
    0 j$ e0 m" F0 i: Y  R
  11.     (independently of compiler optimization behavior) */
    + {+ V5 z1 T6 c) l) |- C# [
  12.   __ISB();+ J' H7 N4 g$ X( o9 X

  13. / I" B5 `" |3 {% b7 i! D
  14.   /* Program second word */0 N/ G6 b; Y! {; {4 @7 g' m
  15.   *(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);) j6 Q" M9 f+ X0 e6 [' y+ `
  16. }
复制代码
( o; ]0 N+ N2 ~. L: ^, C
该函数每调用一次,其实是写入了2个word,所以在使用时需要注意Address的递增。* i' z8 x" i1 Y# ?3 R. p# h* I
1 i' S  M1 }' @
; x/ T9 {1 \* J$ ]9 ]4 N
20210405170242660.png
20210405170242660.png
收藏 评论0 发布时间:2021-11-10 18:02

举报

0个回答

所属标签

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