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

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

[复制链接]
STMCU小助手 发布时间:2021-11-17 23:02
STM32L0 内部EEPROM写读8 q) u2 I  Y8 ~" P; Z
说明
$ l1 V$ a( S$ v- t- ]; FSTM32L0内部的EEPROM写操作由解锁,写入,加锁过程组成,读过程则无需解锁。至于STM32L0内部的非易失空间区分为FLASH和EEPROM,主要体现在用ST-LINK等工具进行整片擦除时,只擦除FLASH的空间,EEPROM的部分不会被擦除,如同外部EEPROM芯片,MPU的代码升级不影响EEPROM的内容。后面以内部EEPROM的写读作为范例。( r3 H- ?* c* f
  A9 n3 e' ]2 N" G2 y4 Y
基础写读函数, Y( @) z& p/ K% z& A; |* f
定义内部EEPROM的地址空间:
7 e9 E2 ]" g& b/ l
  1. //STM32L031K6T6( z; ~: P/ e& D0 r: f' W6 @
  2. #define EEPROM_BASE_ADDR        0x08080000
    & }5 @( S+ }* N4 ^) g0 }% |
  3. #define EEPROM_BYTE_SIZE        0x03FF
复制代码

9 j8 \# M, O# F6 v9 d基础字节写函数
# ^' f4 N' D/ [7 k' @3 ?
  1. //Byte write) j- G1 a/ }& G5 ^
  2. void EEPROM_WRITE(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
    ) b" X& U1 W7 ?, @  F2 t; S* e6 V
  3. {4 L8 G$ u2 G6 [- H: j) s9 i
  4.         uint16_t i;
    5 Z% n: L) V5 K& r& p5 H
  5.         HAL_StatusTypeDef status = HAL_OK;5 @8 p! i# Q9 Q5 _7 G) g8 o

  6. , j$ R9 }% b6 o+ k3 @- N
  7.         HAL_FLASHEx_DATAEEPROM_Unlock();* k& x, C  W+ Y; }+ n1 i
  8.         for(i=0;i<len;i++)
    : y6 u# r: J5 `7 ~2 O; a4 p
  9.         {% q: ~; j) h$ t4 ~  B2 A
  10.                 status +=HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EEPROM_BASE_ADDR+BiasAddress+i, *Data);4 o' k$ P4 a; ?6 ~
  11.                 Data++;2 d" c5 M6 y: ^0 {
  12.         }
    " C) b+ q) ^3 D4 T7 @8 Y
  13.         HAL_FLASHEx_DATAEEPROM_Lock();6 e$ N. n: D% B
  14. }
复制代码
& Z! Q( f/ N2 Q; }) w3 [: C
基础字节读函数5 H+ c- p6 e/ }$ t
  1. <span style="background-color: rgb(255, 255, 255);">/</span>/Byte read% E; B9 ~) |8 G# f, H) s& ?9 Y! O
  2. void EEPROM_READ(uint16_t BiasAddress,uint8_t *Buffer,uint16_t Len)
    0 E3 i+ [* z! E: v3 `
  3. {6 |4 u, J- t/ `7 X' |
  4.         uint8_t *wAddr;; t+ I0 n. y7 T+ W$ p
  5.         wAddr=(uint8_t *)(EEPROM_BASE_ADDR+BiasAddress);6 s% O$ S. U/ h) Q1 N8 @. A/ Y
  6.         while(Len--)
    $ |0 S5 x0 Z& [6 r
  7.         {$ G; F# S5 F, Z
  8.                 *Buffer++=*wAddr++;6 j( I- ]) f: D1 W
  9.         }0 T; @/ N0 T. t8 \, E7 V9 F  [
  10. }
复制代码
4 N! f( N$ w: N' L/ O/ W8 t
带校验写读函数
5 K% ^" ]8 T$ N如果考虑到写读过程中,可以出现错误的情况,为了保证操作的正确性,需要采用校验方式进行写读。! F# g7 R& A+ x/ e% b
对于写过程,需要将写入的数据,读回做比较。2 w" `2 c7 ?; O
对于读过程,需要将两次读回的数据,进行比较。
5 R+ {7 U6 G" D+ s2 t' l如果比较正确,则操作完成。
$ e1 u* S' k- Q如果错误,可重新进行写或读操作,并在设定的重新操作次数范围内,进行重新操作识别,如果正确,则报告正确,如果错误,则报告错误。' F% o8 {* K8 o! y+ T" S

8 |+ v7 Z$ }/ V. e6 e设定重复校验次数
  T$ D$ o! n0 C& ?4 E8 r4 X
  1. #include <string.h>
    3 G( j, l4 _+ M, X
  2. #define iEEPROM_CHECK_NUM 2
复制代码

; q. e. ^0 ~  Q- b  B
7 o+ d( _% L; H% f带操作校验的写函数
. f* z9 \7 d0 ~' f, S7 N% L
  1. HAL_StatusTypeDef EEPROM_WRITE_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
    & i- y4 b) r, f& ^' \
  2. {
    6 \- G5 f# J# h0 \
  3.         uint8_t buff[len];4 @) m, k3 {% s# F
  4.         uint16_t i;
    ; G8 `3 S. J. s" G
  5.         for (i=0;i<iEEPROM_CHECK_NUM;i++)
    . A3 E7 J" N& N/ G: B4 ~, q, t) V
  6.         {
    , p% _6 [; G! L8 N$ C7 y
  7.                 EEPROM_WRITE(BiasAddress, Data, len);6 o/ s+ o. W1 e& Z( }! l
  8.                 EEPROM_READ(BiasAddress, buff, len);4 P/ V) [0 C8 n& D3 r6 D' ^- G
  9.                 if (memcmp(Data, buff, len)==0)
    " O6 ~$ t5 O  t& V' l
  10.                 {0 n! s5 h9 H) T0 w( _6 |
  11.                         return HAL_OK;
    % J9 X" S/ E: g
  12.                 }5 s# }/ i' m/ r/ L; ]. l) y
  13.         }. ]% w' c; J/ X% c7 ~/ o$ E' }
  14.   [5 y% J; W7 e( T" h
  15.         return HAL_ERROR;
    5 ^) m- n# ?5 V. K
  16. }
复制代码
1 K. k% t6 _- g
带操作校验的读函数1 r% ?" V& n* a+ G; V& r$ K
  1. HAL_StatusTypeDef EEPROM_Read_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
    ( i7 T: X1 c# O1 D1 h
  2. {& Z9 f  [! |0 J1 P$ k# G
  3.         uint8_t buff0[len];
    0 V$ J. S9 C/ o: g- g+ z/ y
  4.         uint8_t buff1[len];
    # u  k- y( T8 D& u3 N
  5.         uint16_t i;
    5 h7 D, P7 y, V/ }5 o
  6.         for (i=0;i<iEEPROM_CHECK_NUM;i++)
    - A6 d4 ?2 s& @; M3 \: o
  7.         {
    5 _6 _0 M, w) r8 ~( x# c; h
  8.                 EEPROM_READ(BiasAddress, buff0, len);
    5 I  i. }( K4 h" t9 V
  9.                 EEPROM_READ(BiasAddress, buff1, len);
    / Y/ A9 _) }% Q0 E: b

  10. 8 H' L/ z: v$ Z4 k6 \
  11.                 if (memcmp(buff0, buff1, len)==0)
    & P4 Z$ [' H. d7 G# }! M; Q3 G
  12.                 {
    0 [8 z& C$ L: }- _" L
  13.                         memcpy(Data, buff0, len);
    + d5 o0 P0 q2 `6 R/ q/ n
  14.                         return HAL_OK;
    # B3 s% @# |! w1 `
  15.                 }
    $ ^4 e, c7 o! B6 i5 u6 e5 o
  16.         }
    $ E4 `' u9 r6 ], c2 j

  17. " U6 z( f  o+ a! L( n
  18.         return HAL_ERROR;4 d8 l8 f' z* E" O" l
  19. }
复制代码

6 n5 c$ @" Z- U6 m2 _- _7 F其中BiasAddress为0对应内部EEPROM的0地址(EEPROM_BASE_ADDR定义了其基址),Data为数据字节指针,len为操作字节长度。3 H' H, p' M' U3 N6 b- B
' S9 Y6 D6 N+ z4 V" U
需要注意的是,基于工艺制程和设计,EEPROM的使用也分为两种,其中一种和FRAM相似,可以直接进行写入而不需要提前擦除,STM32内部的EEPROM也是这一种;另外一种和FLASH相似,需要先进行基于Page的擦除后才能正确写入,对于有的EEPROM,支持基于Page最小为Byte单元的擦除。
9 r0 d% |7 T9 t
, u% p7 O7 m0 H+ f. lHAL提供的内部EEPROM擦除函数, 只是进行一个word的擦除,即在某个地址上将数据改写为0x00000000, 和直接调用写函数在该地址写入0x00000000效果一样。HAL的内部EEPROM擦除函数如下:; T+ `$ F9 p6 M% R6 Z8 \# R9 G

% r  Y# f5 s$ X
  1. /**
    $ z1 C( K7 ~7 ^0 C8 Y
  2.   * @brief  Erase a word in data memory.
    ) I% E6 H& l; B' I/ ]6 \
  3.   * @param  Address specifies the address to be erased.
    & }( p. K3 W! v% o( J7 o! @
  4.   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
    9 ^  _1 e3 H; n0 H& m: I1 q
  5.   *         must be called before.
    2 S* P  U8 b* L+ @/ S  I9 n) X
  6.   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access6 E# e1 o* F) x- F
  7.   *         and Flash program erase control register access(recommended to protect $ C" J6 Z3 J! D/ z; O# g+ G; B* ^
  8.   *         the DATA_EEPROM against possible unwanted operation).5 ?+ T) F0 ^$ e4 P6 E" R% I
  9.   * @retval HAL_StatusTypeDef HAL Status$ o5 e% o- e3 F( G
  10.   */
    * P9 g0 V* k2 r# E$ u; g1 K
  11. HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address)+ D6 n% R/ z0 x% a: `9 Q0 F
  12. {3 j4 z  h: t' F! V& U1 U
  13.   HAL_StatusTypeDef status = HAL_OK;7 P" n) n2 {+ h& }* [

  14.   r/ S4 A! a6 F, s' T! l
  15.   /* Check the parameters */0 ?- T3 i$ [) ]3 ~" E
  16.   assert_param(IS_FLASH_DATA_ADDRESS(Address));
    ; z5 l" j/ s' H
  17. 0 D$ y# [$ Q! I+ Q
  18.   /* Wait for last operation to be completed */
    . n8 U8 k- w- d- Y% v
  19.   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);7 s- v" \0 P+ a- \! K1 \  y

  20. ! u: B! Q' H+ x3 h' w( c. H
  21.   if(status == HAL_OK)) l7 I; `) V# B( [4 N8 P3 M- o
  22.   {4 T$ L, k9 F. _9 |
  23.     /* Clean the error context */3 g' `. \3 B+ c' L! q$ Z$ j
  24.     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
    ' U; ]: h: a5 s2 ]  g+ y0 |  M

  25. 9 B# Y& y7 p* k3 @( A9 z+ K
  26.       /* Write 00000000h to valid address in the data memory */* u5 V! }4 v( L4 n6 P" C
  27.       *(__IO uint32_t *) Address = 0x00000000U;/ k5 u: n' V; e: z. |, S7 O
  28. 8 q: B* U+ }) B" h
  29.     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);0 @8 _) m8 o4 k; v( `1 c$ x% j) E
  30.   }
    1 U; P5 w( ]2 }

  31. ( C+ f/ c4 ?! v) b' b8 p
  32.   /* Return the erase status */
    ' [: R: B. m4 ^1 l; M* |& x
  33.   return status;% I) J+ o6 T0 i# A
  34. }  
复制代码

* H( v* z$ C' ]; ~0 G" ?上述的代码,如果要用于STM32内部FLASH的操作,还需要增加页擦除操作。
8 f% H+ ?" |" G+ p) z" I, @& u# ~# D% [; T, N
: n# W5 M1 O1 X8 d7 g2 h
收藏 评论0 发布时间:2021-11-17 23:02

举报

0个回答

所属标签

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