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

【经验分享】STM32L0 内部EEPROM写读

[复制链接]
STMCU小助手 发布时间:2021-11-17 23:02
STM32L0 内部EEPROM写读
! f$ {0 q" T7 q  @- l8 [7 Y: T& c说明
; t8 }5 l* P7 K+ FSTM32L0内部的EEPROM写操作由解锁,写入,加锁过程组成,读过程则无需解锁。至于STM32L0内部的非易失空间区分为FLASH和EEPROM,主要体现在用ST-LINK等工具进行整片擦除时,只擦除FLASH的空间,EEPROM的部分不会被擦除,如同外部EEPROM芯片,MPU的代码升级不影响EEPROM的内容。后面以内部EEPROM的写读作为范例。
9 a  n. s3 D' B8 Y* x5 @
- d, j9 c7 l+ C0 f: M基础写读函数6 @/ I* Q# C+ e
定义内部EEPROM的地址空间:
8 `0 J& w" t0 B7 ~; P
  1. //STM32L031K6T6
    * Z+ t4 D( o( L5 ~1 j& s; t- }
  2. #define EEPROM_BASE_ADDR        0x08080000; ?2 ]8 R  P* G7 }+ p+ Z- j8 N% t
  3. #define EEPROM_BYTE_SIZE        0x03FF
复制代码

: q1 K' R7 o* o$ n  r/ ?基础字节写函数! I# m( ?% S) j0 a
  1. //Byte write
    , O/ u( I+ D5 z' d: e
  2. void EEPROM_WRITE(uint16_t BiasAddress, uint8_t *Data, uint16_t len)* }+ Z/ m  K: N  \3 q
  3. {4 ?- w: N2 u, j
  4.         uint16_t i;3 t, q9 V+ Z2 o
  5.         HAL_StatusTypeDef status = HAL_OK;
    9 ~& C; t: q8 R; R& Y9 `
  6. 5 V; |, e9 x; R4 I" K5 k; M$ R
  7.         HAL_FLASHEx_DATAEEPROM_Unlock();
    5 f0 ~7 v" W2 J
  8.         for(i=0;i<len;i++)
    + u5 W/ v, p) C- b: Y" M+ Q% o7 U: i" z
  9.         {
    4 b9 g% u& i. ~
  10.                 status +=HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EEPROM_BASE_ADDR+BiasAddress+i, *Data);
    $ m% n3 z2 v& k+ \" Z
  11.                 Data++;
    2 @. q9 A* Z' ]4 u
  12.         }3 b+ A( f1 \. y  j0 e4 h
  13.         HAL_FLASHEx_DATAEEPROM_Lock();4 ^% O5 M, N% p1 u
  14. }
复制代码

4 a5 p5 C% O$ I8 p基础字节读函数4 l8 j+ n4 I  n% E+ V% R( O
  1. <span style="background-color: rgb(255, 255, 255);">/</span>/Byte read" \8 E. z+ n& F6 }
  2. void EEPROM_READ(uint16_t BiasAddress,uint8_t *Buffer,uint16_t Len), K* V: O8 M: w
  3. {
      S( B& W" W5 ?3 b) r0 P3 ?" O
  4.         uint8_t *wAddr;
    2 O6 r4 U: ?3 ?7 f: p8 D5 l7 t8 q
  5.         wAddr=(uint8_t *)(EEPROM_BASE_ADDR+BiasAddress);
    : l: f, J2 R( C; L% v
  6.         while(Len--)
    2 |) b% j! F& C5 f1 F7 \2 ^
  7.         {, b0 ^! \" c2 l4 E( P0 _
  8.                 *Buffer++=*wAddr++;
    # h2 j' ]1 U* o5 p
  9.         }
    # T" |) a" L1 @9 U0 Z$ f- h
  10. }
复制代码
. g" J; d% J# ]
带校验写读函数5 N$ L/ Q7 s& z& r. G
如果考虑到写读过程中,可以出现错误的情况,为了保证操作的正确性,需要采用校验方式进行写读。
2 v$ p' b. v* A5 f/ O3 ~0 q8 B对于写过程,需要将写入的数据,读回做比较。7 l0 H' ~4 V( B9 `, u7 A' R  ~
对于读过程,需要将两次读回的数据,进行比较。: x: W$ O0 K& _" X7 M+ N( n
如果比较正确,则操作完成。
9 g0 l( l% ]% P如果错误,可重新进行写或读操作,并在设定的重新操作次数范围内,进行重新操作识别,如果正确,则报告正确,如果错误,则报告错误。
" h- V8 E7 c  N1 O1 d' {- h# S0 y+ Q+ T
设定重复校验次数
- Q* s! f' f  i& s/ [2 w/ [
  1. #include <string.h>$ N- O4 {" m, J  k# m3 e7 A
  2. #define iEEPROM_CHECK_NUM 2
复制代码

7 a0 ~4 |( [0 `5 e9 Y: x
; h1 R. L: u; V1 G- H6 C+ w3 ~带操作校验的写函数7 q6 j% ?# j! g6 ^8 j2 K2 |* x2 a
  1. HAL_StatusTypeDef EEPROM_WRITE_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
    : f8 ?3 @& V1 A- C( e; h! b
  2. {& t: d3 x) }* G2 S( N; G* l, }4 [
  3.         uint8_t buff[len];
    8 D: c: P  s' L& Z* Y* O! q" P
  4.         uint16_t i;6 P- d" P; L9 g
  5.         for (i=0;i<iEEPROM_CHECK_NUM;i++)
      G. a* s6 G( l% g# K& }4 D* M
  6.         {- t& u2 [8 g; K* ~
  7.                 EEPROM_WRITE(BiasAddress, Data, len);
      P  b; }% h- A( H6 A: p' F. |$ h
  8.                 EEPROM_READ(BiasAddress, buff, len);
    5 u5 S8 h% ]6 r/ q4 G
  9.                 if (memcmp(Data, buff, len)==0)9 f9 B8 t$ O' c* s6 A/ h
  10.                 {
    ( W; {; H( R# c) y$ c/ z5 z
  11.                         return HAL_OK;
    / I+ e) A! o# J2 x
  12.                 }$ V* L5 t( W5 L3 ~+ z$ n
  13.         }1 l- d" z7 `* V7 \+ q1 z7 E  j

  14.   V/ z: T# k0 y$ @! B" m6 b
  15.         return HAL_ERROR;9 J0 ~3 \: V( f5 M# H" Z% [
  16. }
复制代码
  x/ O8 R5 g3 R$ y' S
带操作校验的读函数" e9 m: \* X- k2 g
  1. HAL_StatusTypeDef EEPROM_Read_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)! g5 y# b, ]2 _% T  X
  2. {
    ! @2 F" u$ ^9 d
  3.         uint8_t buff0[len];
    7 _" u+ R# h. u. P; P9 {+ u) \7 m
  4.         uint8_t buff1[len];
    1 S& e% E* o) g
  5.         uint16_t i;
    4 Z1 G5 Q1 w0 Z, C
  6.         for (i=0;i<iEEPROM_CHECK_NUM;i++)1 x6 j* F5 Q, N( h- B1 {, i
  7.         {3 i) J# g# w) ]& x2 D' |4 m4 s
  8.                 EEPROM_READ(BiasAddress, buff0, len);/ v3 l4 {9 l  \  U# K! C' o
  9.                 EEPROM_READ(BiasAddress, buff1, len);
    4 Y, C8 |+ E4 d
  10. * r8 ]; `8 K2 K9 T1 N- l
  11.                 if (memcmp(buff0, buff1, len)==0)) o0 }) I9 G7 I+ t& [  {! l
  12.                 {0 a4 l+ o% M, p$ B1 X: `
  13.                         memcpy(Data, buff0, len);% X" ~; n5 l, I+ u5 |: s
  14.                         return HAL_OK;
    6 D# {& v$ c% p3 b* V' a
  15.                 }
    9 z) Y+ i7 C5 b! N6 k# e1 J; s6 {
  16.         }
    & H* i' M8 X- v
  17. ; U8 _6 K( d' ]' w
  18.         return HAL_ERROR;4 U& s$ _' q0 \
  19. }
复制代码

$ _8 ~+ |5 x$ B6 q: w其中BiasAddress为0对应内部EEPROM的0地址(EEPROM_BASE_ADDR定义了其基址),Data为数据字节指针,len为操作字节长度。! g) G6 W8 w2 a/ ]% @
' ?3 i! Y* L( j- n
需要注意的是,基于工艺制程和设计,EEPROM的使用也分为两种,其中一种和FRAM相似,可以直接进行写入而不需要提前擦除,STM32内部的EEPROM也是这一种;另外一种和FLASH相似,需要先进行基于Page的擦除后才能正确写入,对于有的EEPROM,支持基于Page最小为Byte单元的擦除。
7 ~7 K0 h# _4 w: D( |4 P, ?) W+ s3 C: x& u
HAL提供的内部EEPROM擦除函数, 只是进行一个word的擦除,即在某个地址上将数据改写为0x00000000, 和直接调用写函数在该地址写入0x00000000效果一样。HAL的内部EEPROM擦除函数如下:, ]- a" ?" f6 @# C; d; o

  e. }. w5 H; D. E  P1 t4 z9 p
  1. /**
    0 B6 c) K) T3 S
  2.   * @brief  Erase a word in data memory.* [2 y; l# F: e  R( O
  3.   * @param  Address specifies the address to be erased.
    $ a( @: s* M+ w& f
  4.   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function- p, ?( T7 y4 h7 E; F
  5.   *         must be called before.
    7 i4 p# U$ L& m2 ~6 n
  6.   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access
    # f/ Q2 Z7 W! @' Z
  7.   *         and Flash program erase control register access(recommended to protect
    ( W3 v+ F; C3 B6 h" ?/ b% I
  8.   *         the DATA_EEPROM against possible unwanted operation).
    : P# C2 @7 L) E! y/ w9 M' p
  9.   * @retval HAL_StatusTypeDef HAL Status
    + g1 p* [9 q7 p3 u0 k1 ?0 H. V7 k
  10.   */
    ! ]4 G1 }# v, n* V- S& G' t; P
  11. HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address)% l4 s. |; Z& @; T) u0 ?; \3 _
  12. {" E. N, P- d& o
  13.   HAL_StatusTypeDef status = HAL_OK;
    4 N7 Z, G; ?8 C3 B$ J% S* J
  14. ) e% l, X9 u2 V' y$ x/ O5 m) w
  15.   /* Check the parameters */
    / D+ T+ B3 u2 ^# E
  16.   assert_param(IS_FLASH_DATA_ADDRESS(Address));
    5 ^: j1 P- w7 r* m8 s% }& x2 _; t

  17. ' i  n7 w7 K, g: e2 c# h
  18.   /* Wait for last operation to be completed */
    5 Z. H3 M# e8 H2 F3 r6 N  l
  19.   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    + a9 L7 `1 l* E' H

  20. 6 m4 V3 Y; F  H+ Z' ?2 X; A
  21.   if(status == HAL_OK)$ Y% y% b3 N! g$ G8 G+ T! v6 L
  22.   {( T3 a  S5 \: J+ g. K; |  w
  23.     /* Clean the error context */+ r4 D+ g! l% J1 i" `6 w
  24.     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;3 l9 R/ ~9 j2 {7 @2 f
  25. 4 n2 j. p9 H. l9 e/ H4 R
  26.       /* Write 00000000h to valid address in the data memory */; D/ j" [$ F/ e( j9 s' p0 ^
  27.       *(__IO uint32_t *) Address = 0x00000000U;
    6 i9 ?& I9 g; r. m
  28. ! x* G% \. ?  A( ?2 Z* I
  29.     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    ) b6 n* W/ U% v) t) K) h" \
  30.   }- e. D7 D8 e7 w( Z0 ]: z9 A1 q# b

  31. 8 N, r/ B; g+ X" t- U( }
  32.   /* Return the erase status */9 K+ L1 z. y! Q( Q2 ?' _) P2 d
  33.   return status;
    / }3 m1 _8 i8 [5 V
  34. }  
复制代码

- C4 H3 Z$ A' i6 V, k5 M上述的代码,如果要用于STM32内部FLASH的操作,还需要增加页擦除操作。% Z$ A8 f5 K2 v7 _
2 b2 B6 n5 p8 v9 T" b* K3 `- @1 ], K: M
% Q5 j1 a/ j5 u* l
收藏 评论0 发布时间:2021-11-17 23:02

举报

0个回答

所属标签

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