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

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

[复制链接]
STMCU小助手 发布时间:2021-11-17 23:02
STM32L0 内部EEPROM写读
, y5 b9 e/ h! I8 x0 `( J* u说明+ G# F* j- x4 L: }/ M
STM32L0内部的EEPROM写操作由解锁,写入,加锁过程组成,读过程则无需解锁。至于STM32L0内部的非易失空间区分为FLASH和EEPROM,主要体现在用ST-LINK等工具进行整片擦除时,只擦除FLASH的空间,EEPROM的部分不会被擦除,如同外部EEPROM芯片,MPU的代码升级不影响EEPROM的内容。后面以内部EEPROM的写读作为范例。: Q) F+ V. a/ l* G" ], b

- Z4 l" z& G- W1 B基础写读函数
, f. C! z; l" S9 L- W- z! _定义内部EEPROM的地址空间:; A: Z0 F# N- b& H
  1. //STM32L031K6T6
      F% T- z* l% V& p( A
  2. #define EEPROM_BASE_ADDR        0x08080000% L% f' H+ o2 W: G( I
  3. #define EEPROM_BYTE_SIZE        0x03FF
复制代码
0 [% h8 z, V$ ~4 Y) M7 O( q
基础字节写函数
3 J7 o  y) a- d; X
  1. //Byte write
    : [' b9 K/ B! r4 t1 r+ j+ r0 y
  2. void EEPROM_WRITE(uint16_t BiasAddress, uint8_t *Data, uint16_t len)* _  {- i3 Y/ K2 r) a% q
  3. {
    ) [$ |* `3 s2 ~& C' c3 k
  4.         uint16_t i;( e4 q1 E+ p* I1 `
  5.         HAL_StatusTypeDef status = HAL_OK;! b% d) j: q( V* T& {4 C5 Y" _' R
  6. 1 _! k$ q( O1 W( F4 H' q/ I" H3 v
  7.         HAL_FLASHEx_DATAEEPROM_Unlock();! F5 |, g* D( Y
  8.         for(i=0;i<len;i++)
    + U& a/ Z! a! A, m- f5 j+ r9 m- l
  9.         {4 F5 f, @8 {- X0 p! c' B" `0 X
  10.                 status +=HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EEPROM_BASE_ADDR+BiasAddress+i, *Data);
    7 m- }/ c' K% U4 G& h% h! O1 ?
  11.                 Data++;! @2 ?# m! B6 ~9 a! x
  12.         }
    1 P1 a4 Q. p) {" z( f
  13.         HAL_FLASHEx_DATAEEPROM_Lock();6 ?$ y# q- g; \, b
  14. }
复制代码

1 [1 x& Y+ N/ ?8 b' N% [4 C基础字节读函数/ J) O* t  [, A: ^! n5 L
  1. <span style="background-color: rgb(255, 255, 255);">/</span>/Byte read2 L6 B& X: A  Y+ h7 ]
  2. void EEPROM_READ(uint16_t BiasAddress,uint8_t *Buffer,uint16_t Len)/ I2 i& I; l( s
  3. {+ u5 y1 N6 G% j3 M/ V, D7 R( i
  4.         uint8_t *wAddr;( p8 m$ g7 Q5 H% n7 O6 W) {
  5.         wAddr=(uint8_t *)(EEPROM_BASE_ADDR+BiasAddress);6 g/ J7 w& ^! a! ]5 n8 g" g0 z
  6.         while(Len--)
    & r- x% {+ N) J; b1 K' y) f
  7.         {1 l! C2 k$ \, \2 f4 \" V- H
  8.                 *Buffer++=*wAddr++;0 l. J# h. U7 E, o
  9.         }# Y/ p) N7 v7 N& Y1 k7 x% Z
  10. }
复制代码

6 J* V8 c5 _, _带校验写读函数
$ s, U/ b% p5 _: c如果考虑到写读过程中,可以出现错误的情况,为了保证操作的正确性,需要采用校验方式进行写读。
2 o) Q! a: j& P; ]3 y对于写过程,需要将写入的数据,读回做比较。
6 G7 k5 n$ V# Y对于读过程,需要将两次读回的数据,进行比较。
- f6 J8 {% d* S/ C- T* [如果比较正确,则操作完成。+ N# l7 t0 c/ @& Z7 G- L
如果错误,可重新进行写或读操作,并在设定的重新操作次数范围内,进行重新操作识别,如果正确,则报告正确,如果错误,则报告错误。
1 ~6 ?( M# \7 B6 W) q
7 q, v( [* {7 \' h设定重复校验次数
  N3 @. Y) K' P8 i' V
  1. #include <string.h>6 N2 i4 U3 f  B) A( O
  2. #define iEEPROM_CHECK_NUM 2
复制代码
- b: ]2 h; G" j( n5 t1 i

4 u4 U1 V: F1 A: v6 T" x9 t带操作校验的写函数
/ B2 I  d0 P0 f9 M, S( q( b1 \5 G
  1. HAL_StatusTypeDef EEPROM_WRITE_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
      V; D6 o. H  Q
  2. {* {% `0 b, k* d1 m) Y
  3.         uint8_t buff[len];5 ?" h4 Q1 {& ~' P
  4.         uint16_t i;" X8 k2 M$ x0 y. K. f
  5.         for (i=0;i<iEEPROM_CHECK_NUM;i++): m8 F1 S  A. B7 p/ c9 `$ l7 e
  6.         {; E  L5 q* E) b2 ^4 _! J
  7.                 EEPROM_WRITE(BiasAddress, Data, len);
    & ]- @$ Y6 O6 U& p
  8.                 EEPROM_READ(BiasAddress, buff, len);
    5 O3 n4 ?9 n7 o4 [4 Z! U% t
  9.                 if (memcmp(Data, buff, len)==0)) q# s% V! n0 N) U6 ~( A7 F
  10.                 {
    & P8 d- |' L/ b' {
  11.                         return HAL_OK;
    6 m1 O% _: x6 S2 D
  12.                 }2 z+ C3 V+ Z. i" l5 E' c
  13.         }
    3 C) i6 H  t; c* O9 @

  14. ) b0 R$ j. u$ C8 T3 ]! e) p! a' C6 v; p- L
  15.         return HAL_ERROR;% R, }7 {; K; I( K6 t* g0 ^# h6 a: Q
  16. }
复制代码

; X( d: A$ e6 N# b! M: G带操作校验的读函数
- x0 q& s, z, u- A
  1. HAL_StatusTypeDef EEPROM_Read_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
    ' w6 \+ }- a, r$ K! s' f' G6 Z0 b
  2. {* G0 d4 ~4 i: u9 t9 w2 i: r3 x, `4 R
  3.         uint8_t buff0[len];. V; k( }+ V1 j% n! W$ x# g8 f
  4.         uint8_t buff1[len];
    1 f$ B" y1 s% o& @7 h
  5.         uint16_t i;
    $ `7 x; b* s) M) R1 r
  6.         for (i=0;i<iEEPROM_CHECK_NUM;i++); j' u( ~2 w' ]4 @) ?6 ~
  7.         {3 K9 y' F0 ^& I/ U" s3 M1 u1 B* z; O
  8.                 EEPROM_READ(BiasAddress, buff0, len);
    . U7 h  O4 R/ n% `
  9.                 EEPROM_READ(BiasAddress, buff1, len);  Z) u, D' k& I* q0 K7 G( X, X

  10. - J: D( E" [; n1 i) L3 N
  11.                 if (memcmp(buff0, buff1, len)==0)
    : r: L- {5 R; U8 u
  12.                 {& ]! {/ ?3 H8 Q
  13.                         memcpy(Data, buff0, len);; A; S6 u/ d; {6 C$ {
  14.                         return HAL_OK;
    & `1 k3 _0 U) ]
  15.                 }# c% e* _2 H+ }5 O  g0 K
  16.         }0 S# E1 @3 H/ J

  17. 6 D8 V" W. G, R0 b0 F$ I9 p! n" H
  18.         return HAL_ERROR;4 M, @: a+ ]& Q8 C! r* q# D6 b
  19. }
复制代码

4 B5 v3 u' {, ]其中BiasAddress为0对应内部EEPROM的0地址(EEPROM_BASE_ADDR定义了其基址),Data为数据字节指针,len为操作字节长度。
" O( j8 [! e4 X- \. v& J
8 b4 T: p0 C/ l' T2 n需要注意的是,基于工艺制程和设计,EEPROM的使用也分为两种,其中一种和FRAM相似,可以直接进行写入而不需要提前擦除,STM32内部的EEPROM也是这一种;另外一种和FLASH相似,需要先进行基于Page的擦除后才能正确写入,对于有的EEPROM,支持基于Page最小为Byte单元的擦除。
" i# E8 h4 @. d6 D+ r6 a" g
7 ]  i1 W) I, p* V0 l1 [) eHAL提供的内部EEPROM擦除函数, 只是进行一个word的擦除,即在某个地址上将数据改写为0x00000000, 和直接调用写函数在该地址写入0x00000000效果一样。HAL的内部EEPROM擦除函数如下:* a  y0 u+ E$ U

! N+ T' i% j; N+ L, o; G
  1. /**
    . k1 {* {: g* N8 q
  2.   * @brief  Erase a word in data memory.
    7 h8 M7 ]) o4 ^; V. R- M( O& @
  3.   * @param  Address specifies the address to be erased., \% H% ^" G8 Y. @$ x
  4.   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function5 K2 @% y/ I7 m. U% g
  5.   *         must be called before.
    $ f9 k& j3 r- i5 w
  6.   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access! ?; M% r/ T+ G1 T! }3 Q/ H
  7.   *         and Flash program erase control register access(recommended to protect
    ; d+ j! t! z& m$ l- R. S
  8.   *         the DATA_EEPROM against possible unwanted operation).
    ( s- M  y( A* y5 ^# v
  9.   * @retval HAL_StatusTypeDef HAL Status* W4 m# ]+ o9 W2 h
  10.   */
      g: U) b8 g5 e/ j5 {4 u7 k; h
  11. HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address)7 i9 w* R: U# O0 r2 C
  12. {6 Q# l4 b2 k9 t3 L5 `6 P6 S
  13.   HAL_StatusTypeDef status = HAL_OK;  I* a# U" c8 q1 ~
  14. - X! K3 _' Y1 a9 N6 x
  15.   /* Check the parameters */" ~% j" t9 O2 S, E, D+ T1 l: v
  16.   assert_param(IS_FLASH_DATA_ADDRESS(Address));
    6 f0 ]; U, y5 N
  17. 3 u1 T# n# q# v* G2 \' E( i
  18.   /* Wait for last operation to be completed */2 b9 {$ n. P( X5 R5 L
  19.   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);8 X5 t+ ^: K4 @& [# Q0 L4 D0 H0 C" T

  20. : R- ~# t+ j/ @+ M0 r6 l1 r0 i
  21.   if(status == HAL_OK)0 v; H- z5 q1 `8 B) ]
  22.   {9 o/ `5 w. O0 H' n& E
  23.     /* Clean the error context */. Y. b4 v: t' b+ {
  24.     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;5 n) [6 o- }; \: A1 O0 q5 x- r9 c
  25. / l, U" C  R% Y. b3 d8 L
  26.       /* Write 00000000h to valid address in the data memory */
    : \3 }: {' z' d' \0 ]
  27.       *(__IO uint32_t *) Address = 0x00000000U;- J$ f! g. D% R) B# W0 n
  28. * O; S2 f3 E7 v& G% Z
  29.     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    ; v3 }0 X8 {# c! u% n% M/ }3 [
  30.   }/ e$ d3 W, X/ C* W! B

  31. ; x4 p1 l# r9 r6 ?7 U* H4 [1 y0 F
  32.   /* Return the erase status */+ p! c$ e- C' i! F, h  e3 ~
  33.   return status;' i! E& o9 z2 C! L4 T$ O( Z
  34. }  
复制代码
4 N6 c" M* l4 d6 m
上述的代码,如果要用于STM32内部FLASH的操作,还需要增加页擦除操作。
; k1 \, H  x- X# \- I
3 O; U6 \! {6 R1 a, Z. i4 n) `! l% D
收藏 评论0 发布时间:2021-11-17 23:02

举报

0个回答

所属标签

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