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

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

[复制链接]
STMCU小助手 发布时间:2021-11-17 23:02
STM32L0 内部EEPROM写读, V0 x" h$ b5 A
说明
0 h5 Q8 ?# A1 C0 ?STM32L0内部的EEPROM写操作由解锁,写入,加锁过程组成,读过程则无需解锁。至于STM32L0内部的非易失空间区分为FLASH和EEPROM,主要体现在用ST-LINK等工具进行整片擦除时,只擦除FLASH的空间,EEPROM的部分不会被擦除,如同外部EEPROM芯片,MPU的代码升级不影响EEPROM的内容。后面以内部EEPROM的写读作为范例。, w5 B1 T2 \" j- t: Q. ~# k' F4 z

4 \* ^$ |0 [+ E% r  n基础写读函数1 _! ?  w- k1 N4 S2 _: ?0 F, [4 l' s
定义内部EEPROM的地址空间:
% \2 p2 r( C2 L* H9 e
  1. //STM32L031K6T6
    : X) t; j' Y  v! d9 ^- d
  2. #define EEPROM_BASE_ADDR        0x080800008 o& p- \! {9 K
  3. #define EEPROM_BYTE_SIZE        0x03FF
复制代码

3 Z: H9 x) g2 J2 f) C基础字节写函数
# r6 r% a4 c7 w+ r- ^; H( j
  1. //Byte write
    # P6 n  t6 `/ ?7 N: H
  2. void EEPROM_WRITE(uint16_t BiasAddress, uint8_t *Data, uint16_t len)
    4 x, B& P7 i1 L& g( d
  3. {
    4 u) Q" O9 E4 M& P# i" p
  4.         uint16_t i;
    ! n: l3 y6 m$ Y* T0 M
  5.         HAL_StatusTypeDef status = HAL_OK;, u8 H9 l! t/ t& `
  6.   O+ u8 b# r9 y( E2 p; h) N# L) ]
  7.         HAL_FLASHEx_DATAEEPROM_Unlock();
    % f7 \) k. k) Q& V
  8.         for(i=0;i<len;i++)
    & B9 {9 q. d: ~# v6 d7 d
  9.         {
    ' }6 c; \3 c4 W- u( Q7 Q* I, m
  10.                 status +=HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EEPROM_BASE_ADDR+BiasAddress+i, *Data);
    & y$ ~1 R! Z6 @- n6 W$ X
  11.                 Data++;/ j# S  [1 H( M* P0 m
  12.         }) ?4 ]6 l" \9 l* O7 t& M
  13.         HAL_FLASHEx_DATAEEPROM_Lock();
    + e) `. o" x. W
  14. }
复制代码
( @% f8 s1 V0 ?$ Z
基础字节读函数
8 m; q' i2 Y' g9 H' ^
  1. <span style="background-color: rgb(255, 255, 255);">/</span>/Byte read
    8 M4 y) ~, m* @) ^
  2. void EEPROM_READ(uint16_t BiasAddress,uint8_t *Buffer,uint16_t Len)8 d8 ]3 u- @# M+ a
  3. {
    5 t3 N9 I1 j3 R3 \
  4.         uint8_t *wAddr;
    ! Y/ O5 G8 g- T6 c2 @1 s! b
  5.         wAddr=(uint8_t *)(EEPROM_BASE_ADDR+BiasAddress);; H! Q5 q8 w/ h( W/ a$ [) O  ]
  6.         while(Len--)8 W3 Y" K. L. g. a, j
  7.         {
    ' \9 t8 x1 [2 l4 F! ~
  8.                 *Buffer++=*wAddr++;
    # k7 v# n$ n2 q: r1 \. H- _5 G% U) |
  9.         }% S* {" [* d# ^7 i& t* A
  10. }
复制代码
, R3 x: t% V+ c6 d$ @
带校验写读函数
; ]& v) A/ t; V* _( |如果考虑到写读过程中,可以出现错误的情况,为了保证操作的正确性,需要采用校验方式进行写读。, y' b. x# y4 {; C! C2 n
对于写过程,需要将写入的数据,读回做比较。
5 }7 s5 ~3 y; @5 p0 Q对于读过程,需要将两次读回的数据,进行比较。# k' \) g! j: J: ~" J( o
如果比较正确,则操作完成。7 p$ d1 o. J2 I5 d+ j
如果错误,可重新进行写或读操作,并在设定的重新操作次数范围内,进行重新操作识别,如果正确,则报告正确,如果错误,则报告错误。
* a5 F% Q7 \) u, q
/ y" a; `' k, f设定重复校验次数
' p$ y2 N: S. |! y! y8 T5 @4 R
  1. #include <string.h>  a5 @6 F0 Y; L8 D4 \1 x
  2. #define iEEPROM_CHECK_NUM 2
复制代码

' r. Z! S+ I0 n+ _4 ]: s3 v6 b& I- j7 ^4 o8 m  P# T
带操作校验的写函数
" k# l' j) U# [) C, {' h
  1. HAL_StatusTypeDef EEPROM_WRITE_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)& q3 x& ~* n+ Q9 s# P
  2. {# m5 n0 I" Y6 B3 _8 S  I
  3.         uint8_t buff[len];
    0 J6 z  f4 @5 g6 {5 i6 c9 |
  4.         uint16_t i;
    / A. }- C# x3 F' T9 r* l
  5.         for (i=0;i<iEEPROM_CHECK_NUM;i++), ^8 y7 g- a' @8 k$ B% O
  6.         {
    4 _+ V3 j* o, f6 y+ r4 Z
  7.                 EEPROM_WRITE(BiasAddress, Data, len);% I7 a9 h- _' B9 j, X: a( E
  8.                 EEPROM_READ(BiasAddress, buff, len);
    & A$ e0 h6 o: e# H: g
  9.                 if (memcmp(Data, buff, len)==0)
    ) G; g* _. X! v" t, O
  10.                 {
    & K; _& D  z! {+ N5 s$ |7 D
  11.                         return HAL_OK;
    6 B0 S: A* H1 y. F2 ?  b
  12.                 }
    7 F4 t& V5 x0 j7 E5 L
  13.         }
    . \9 P5 w! |( g* ~8 ^: `% b

  14. 4 K0 w" v. a" U# P+ j5 H
  15.         return HAL_ERROR;
    4 Y# D+ \$ i4 w( W! |
  16. }
复制代码
3 Z) I: X2 a/ A* R/ T4 Q% P
带操作校验的读函数) E; o; j6 U9 v! T) Z! r
  1. HAL_StatusTypeDef EEPROM_Read_W_CHECK(uint16_t BiasAddress, uint8_t *Data, uint16_t len)( N( p+ D1 j. ]8 H
  2. {
    ( M7 m  u+ h0 y* b3 u6 v* Z" A
  3.         uint8_t buff0[len];, u" u: p+ }; V, o! d6 W
  4.         uint8_t buff1[len];
    4 H: I1 i( ^# Q: F5 e* B9 D9 A; |
  5.         uint16_t i;
    + ~6 Q) J" ?* h) A. `3 {
  6.         for (i=0;i<iEEPROM_CHECK_NUM;i++)' }7 f0 ]4 _! e) ^- n
  7.         {$ ]7 B* h8 a6 b4 ^8 Q0 s& [
  8.                 EEPROM_READ(BiasAddress, buff0, len);6 W  K6 l1 {/ V4 g7 w, P2 H
  9.                 EEPROM_READ(BiasAddress, buff1, len);* @: D+ l8 n* B$ X

  10. 5 N, T2 C+ \$ b( a" g: T
  11.                 if (memcmp(buff0, buff1, len)==0)
    ' |* {+ |0 z# E: s# T3 @
  12.                 {
    / ?4 ~0 [5 K9 i) q3 I: U7 }+ h4 y
  13.                         memcpy(Data, buff0, len);
    6 w( V9 z5 d) q0 y: a
  14.                         return HAL_OK;
    ! `1 a8 a2 v, e. Q* E+ X2 r
  15.                 }# S6 A4 y) n: ^# X/ C
  16.         }
    2 I0 V! a2 P2 ^; q7 C

  17. ( e: [! g$ \. e! x4 y' g. R; k
  18.         return HAL_ERROR;7 p: ]# U: _& [& W6 |) F2 A: t
  19. }
复制代码

3 U/ }) R3 k; v4 O& P% f% G! J其中BiasAddress为0对应内部EEPROM的0地址(EEPROM_BASE_ADDR定义了其基址),Data为数据字节指针,len为操作字节长度。! t. _- K" a/ k  l" C4 X0 ?7 h7 c
1 c( b  _3 w+ D$ u2 }: i, S
需要注意的是,基于工艺制程和设计,EEPROM的使用也分为两种,其中一种和FRAM相似,可以直接进行写入而不需要提前擦除,STM32内部的EEPROM也是这一种;另外一种和FLASH相似,需要先进行基于Page的擦除后才能正确写入,对于有的EEPROM,支持基于Page最小为Byte单元的擦除。
5 D! K' o/ a8 ^
/ [$ V! c$ T( o% t& P6 XHAL提供的内部EEPROM擦除函数, 只是进行一个word的擦除,即在某个地址上将数据改写为0x00000000, 和直接调用写函数在该地址写入0x00000000效果一样。HAL的内部EEPROM擦除函数如下:: ~9 w. s/ ?0 Z' j4 I0 L. q
- @6 m, u. C8 d5 A; `
  1. /**2 C; K5 D+ ^, t& x, A
  2.   * @brief  Erase a word in data memory.7 @, j4 A) G# `, l4 w, L
  3.   * @param  Address specifies the address to be erased.* e$ l! C( q! M; U% d& @' i
  4.   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function; K, j$ K2 j$ @1 n
  5.   *         must be called before.+ M) k6 x. ?7 ?% S
  6.   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access/ z  i) n9 S7 k
  7.   *         and Flash program erase control register access(recommended to protect
    ; f- |1 a( @& U. G& c
  8.   *         the DATA_EEPROM against possible unwanted operation).. Z4 J3 y3 f1 ^1 w3 @" N2 M  S9 [
  9.   * @retval HAL_StatusTypeDef HAL Status
    , {0 E% j$ l; p" ?7 C
  10.   */
    5 z  v# L! @9 I) R( B
  11. HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address)  B1 \  T6 G) E& q& w$ Y
  12. {
    ' [. R% X" S8 h4 T) R
  13.   HAL_StatusTypeDef status = HAL_OK;
    ( r) h% @6 E4 J6 C  P3 U
  14. + X9 b# @! U# N' K0 }1 @
  15.   /* Check the parameters */
    + N. E: h: Q7 X0 ~; K! u
  16.   assert_param(IS_FLASH_DATA_ADDRESS(Address));) ~" s7 l4 `7 o4 c

  17. , o( M% O! F$ E6 _; D/ `
  18.   /* Wait for last operation to be completed */4 W; e0 ?5 Q+ q8 \
  19.   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);3 u2 [) `& z# c  d

  20. % U0 ~+ l7 ~, O$ U1 P
  21.   if(status == HAL_OK)
    0 k/ w6 Q4 w, A" l5 T. C
  22.   {
    1 H$ S# t1 q+ ?! t& u
  23.     /* Clean the error context */
    * A- h$ z% X% I1 U
  24.     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
    : {3 a* T( a0 V

  25. 4 R% F' f; y  ?8 c" w& {
  26.       /* Write 00000000h to valid address in the data memory */
    $ B1 n( L; \6 c, E$ a+ {4 _
  27.       *(__IO uint32_t *) Address = 0x00000000U;0 H; p2 r2 a5 N5 v( b' A5 U

  28. * j# C4 _# J7 f+ B- X  e
  29.     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    , Y* S0 v# F/ Q4 L$ l7 Q
  30.   }0 y, O' x2 B! |) t8 @- w, s

  31. 7 r# [9 X% n; `2 g! H! t
  32.   /* Return the erase status */
    # r6 N3 A* ?3 Q0 Y7 o' v
  33.   return status;
    1 S4 u: \& }, H! y3 [9 e$ o. A
  34. }  
复制代码

. g- c% {9 ]9 i$ [/ b上述的代码,如果要用于STM32内部FLASH的操作,还需要增加页擦除操作。
, q' s# s& M, ?# y) r; L6 ]
1 k/ h, h4 U4 u6 [$ I$ S0 i5 n9 E; d/ k7 E
收藏 评论0 发布时间:2021-11-17 23:02

举报

0个回答

所属标签

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