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

STM32L0x2自带EEPROM读写分享

[复制链接]
power568 发布时间:2018-1-9 15:24
本帖最后由 creep 于 2018-1-9 16:18 编辑 ; B  m: l0 W. d/ N$ [
( Y# i2 @" U2 c: g
       STM32L的EEPROM支持字、半字和字节的读写操作。写操作之前自动擦除,如果写的数据为0,则只执行擦除操作。4 i% j( w# Q3 z2 D& T  z2 O" @

& k0 V) H& J, j  _, `5 Q       使用STM32Cube库对自带的EEPROM进行操作,代码如下:
3 ~; F) }3 v3 \* j1 M

  1. 2 R- ?3 k9 @* E9 L* H
  2. #define                EPROM_WR_TYPE_BYTE                                ((UNS8)0x00)
    ; N: X. v- b7 a1 H% h
  3. #define                EPROM_WR_TYPE_HALF_WORD                ((UNS8)0x01)
    2 v4 y/ g4 s. j# l) `/ e  \
  4. #define                EPROM_WR_TYPE_WORD                                ((UNS8)0x02)
    # i) x# K- e2 _% Z; B& D& s

  5. 2 ^* ^) U3 G8 d3 t& ~3 o0 ~
  6. #define                EPROM_TEST_ADDR                                (STM_EPROM_ADDR_BASE + 12)
      e: R; p& M  g9 H" u" u
  7. #define                EPROM_TESTE_ADDR                                (STM_EPROM_ADDR_BASE + 32)
    2 @0 c) i$ Y5 v& d  T2 `
  8. #define                EPROM_TESTEE_ADDR                                (STM_EPROM_ADDR_BASE + 61)# F- a( Q/ h/ K1 y

  9. * B4 O) U) Q+ L0 e  j, V9 [2 S
  10. //// Unlocks the data memory and FLASH_PECR register access+ E7 Z' i- M* i5 T! x- g: M
  11. //// ret :" s; P2 [1 w1 z' W" K4 ?
  12. ////   OK       = 0x00U,
      a  S: J3 u7 w, E/ S/ M
  13. ////   ERROR    = 0x01U," b! o: ~, p: i% f
  14. ////   BUSY     = 0x02U,# Z7 D3 J3 N0 q, K
  15. ////   TIMEOUT  = 0x03U
    2 u8 p8 e) O2 L
  16. UNS8 StmL0xxEpromUnlock(void)2 {- R/ U% D6 ]
  17. {
    4 h  P1 t+ G' F: u4 g% o4 |
  18.         UNS8                ret=0;/ G( E: d2 P5 m% Z
  19.         * Q  r  y6 \; Q4 }  h
  20.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Unlock();
    0 S# m4 f0 y! L# @
  21.         
    # C- P3 v5 I3 l% }/ @
  22.         return ret;, x- Z1 |7 D/ s& C1 B3 O0 J
  23. }, S7 Z- i0 A# i. I2 A3 h+ Q4 Y4 T
  24. : T$ K# {8 v7 s0 }: \- }
  25. //// Locks the Data memory and FLASH_PECR register access; I6 u2 M5 W/ d; K! a+ M/ o
  26. //// ret :- K" u1 x( I2 ^
  27. ////   OK       = 0x00U,; d- s9 t* `; _/ u% V4 n( X+ T4 f% g
  28. ////   ERROR    = 0x01U,
    # a: X& @4 J& G( M5 s' e
  29. ////   BUSY     = 0x02U,( {0 k: C" n7 j- u2 p# Z
  30. ////   TIMEOUT  = 0x03U) t, D0 p; O* D+ i
  31. UNS8 StmL0xxEpromLock(void), P9 A" a1 `2 O9 {
  32. {
    % h1 c) u; X7 Q9 t, q) U
  33.         UNS8                ret=0;
    " g8 h, s/ N) N" h" f  o
  34.         6 g) D6 q& x9 v0 w+ A& g
  35.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Lock();
    , [- k# |+ b/ |2 T; Q+ }
  36.         
    7 b2 e' D) [' t
  37.         return ret;9 a6 l! V: w/ Q' D% D
  38. }
    5 a  Y1 b* K) U1 T% J) x3 Y/ K
  39. $ M) X5 O4 {. E6 G6 [
  40. //// Erase a word in data memory.
    2 c& u/ J+ R9 H+ F; r: ~; w
  41. //// To correctly run this function, the @ref StmL0xxEpromUnlock() function# u, W, [8 u- N2 h7 T
  42. //// must be called before.% n6 V; u- m4 E6 @8 t" l4 e
  43. //// addr -- specifies the address to be erased.
    ( l6 U( H3 M& {
  44. //// ret :
    , \" N, [. U* l" |" O5 ^
  45. ////   OK       = 0x00U,' w7 q6 a4 r) G: O
  46. ////   ERROR    = 0x01U,
    & u2 u  h: o  q$ ]( X; O/ F7 o
  47. ////   BUSY     = 0x02U,
    1 {( p$ L" ~7 N0 F- P
  48. ////   TIMEOUT  = 0x03U: G/ q" f$ W; a- `# ^
  49. UNS8 StmL0xxEpromWordErase(UNS32 addr)( e7 z) z$ S4 l6 N
  50. {
    . z( e) O2 I) E
  51.         UNS8                ret=0;% l& i  F" i/ ?' H2 G
  52.           v% z* U9 r( K5 q
  53.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    + f/ l1 Y: f; a% U
  54.         {1 u" Q4 O! R9 W5 l
  55.                 return ret;1 N& _0 ^, ~' Y  k& P
  56.         }. B* `3 S6 Y+ G. {4 _( x
  57.         
    2 a& N  ^6 @# l# p# G9 r9 I( l6 G
  58.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Erase(addr);* R% B7 R: h# H/ j# Y: X5 Q8 M
  59.         * y6 X/ Q' ^( ^' h- k
  60.         return ret;
    7 ?) A5 i9 u& Q7 m7 D
  61. }0 ]$ `* Y/ {' J0 z. K, r
  62. & X. v! y& ~' R5 ~: s
  63. //// Program data at a specified address: R4 p+ ~% B& T1 O- Z
  64. //// type :/ }. R* A+ F8 m& j. d: w$ |) O
  65. ////   Byte -- 0x00+ Q3 J6 H" [# \. t* f
  66. ////   HalfWord -- 0x010 ?) ~; U  p: U
  67. ////   Word -- 0x02- k, t! T9 k( P
  68. //// addr -- specifies the address to be erased., w; k& U& `+ M* b; I9 L- O9 V
  69. //// ret :
    " O4 N' |' Q. P  I& G3 j
  70. ////   OK       = 0x00U,( \) a8 M' o; l9 J5 V; v1 [
  71. ////   ERROR    = 0x01U,, s* b; c) P# T1 V& c7 z* R1 T* |7 N
  72. ////   BUSY     = 0x02U,& |  W. l3 C1 n% o3 h4 h
  73. ////   TIMEOUT  = 0x03U
    3 k( U# k1 Q9 r  Z% X
  74. UNS8 StmL0xxEpromSingleWrite(UNS8 type, UNS32 addr, UNS32 data)9 _- d- w+ _* }8 L
  75. {- C# [8 v3 d, n  D$ }
  76.         UNS8                ret=0;' S; k( A- H+ [7 E0 p7 B% M
  77.         : b+ f. M" f; e9 a
  78.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )2 ]+ D9 v4 W  N
  79.         {! d- r4 I. Z8 W8 z1 p: x
  80.                 return ret;
    5 Z+ q# u# U; ?: f) o7 P+ d4 @
  81.         }
    . e5 b9 C3 [" @% k
  82.         * m! W! _# [: U. l4 _
  83.         StmL0xxEpromUnlock();
    3 Z5 i" B5 w' m  a2 T6 W6 x+ V7 v9 b) q
  84.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Program((UNS32)type, addr, data); //// 库函数
    ) [4 d2 j4 O! L6 H  b5 a' G" }2 ?
  85.         StmL0xxEpromLock();$ N4 Q3 F2 Q' B
  86.         7 }7 i# z; @" J1 z0 K  h' b* V- Z- F
  87.         return ret;0 n2 g: w2 {  R' E7 p
  88. }
    / U7 M5 ^! e* z1 Z3 T

  89. 4 H  P2 m" I( e) A) x
  90. //// read a byte at a specified address$ R/ `4 k- c2 R& c# J, y
  91. //// addr -- specifies the address to be erased.
    # ]4 f; J, z/ O) Q" P% C
  92. //// ret :
    8 T# h6 F& p% ]$ m5 [1 ]% n
  93. ////   OK       = 0x00U,0 [" M+ p! |( t5 p  K
  94. ////   ERROR    = 0x01U,4 b" l! H5 c2 p8 _& S6 Q
  95. ////   BUSY     = 0x02U,
      X$ @5 A/ \4 Z3 d
  96. ////   TIMEOUT  = 0x03U
    ) Q6 D3 H" w0 K1 [' V* q
  97. void StmL0xxEpromSingleByteRead(UNS32 addr, UNS8 *data)
    3 N  e; O* J. M& q/ K
  98. {9 `# B0 I* h: s" g& P! ^& `( j
  99.         , L$ n0 m# J% `6 D
  100.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    8 R: g+ M# Z; l8 j
  101.         {) i! u- ]: y: ~' Q! ~5 y6 F; z7 ]
  102.                 return ;9 q/ f* Y7 }8 d; W( Z
  103.         }0 W! N' q# Q0 \: F9 L
  104.         
    8 J% A  t, b5 z
  105.         StmL0xxEpromUnlock();
    ) |* \) Y7 \% c- A! a9 t. S( Z
  106.         *data = *(volatile uint8_t *)(addr);4 y9 l  H; t6 F0 T: R1 m
  107.         StmL0xxEpromLock();
    ' j1 t4 [$ K8 G/ h/ G; }
  108. }
复制代码
    测试代码如下:8 J6 E: W* Q$ f& C' x8 i! ^' o
  1. void EpromTest(void)3 G. i0 r7 D  m6 S& C) n: k
  2. {
    ; K4 E# h6 W% _' y# c9 X8 J  E
  3.         UNS8        tmp[8] = {1, 2, 3, 4, 5, 6, 7, 8};
    ! q$ h' E; d6 ]# I/ r
  4.         UNS8        read[8] = {0}, num=0, time=1;  t3 u2 k- V( D/ o# y3 H
  5.         ! _  Z4 q3 o% Y4 V4 G  d! N  ~$ r5 a
  6.         while(5>time)2 _6 {" g& Z' D. g
  7.         {
    ( \8 C4 C! y2 W
  8.                 for (num=0; num<8; num++)
    : {( P4 h1 T& C  \0 o
  9.                 {
    ' Z5 x" w. f; K
  10.                         tmp[num] *= time;
    8 s1 K2 g9 S5 V8 n1 b
  11.                         StmL0xxEpromSingleWrite(EPROM_WR_TYPE_BYTE, EPROM_TEST_ADDR+num, (uint32_t)tmp[num]);9 O; D* m, ]6 q7 c% a  }
  12.                 }% u2 h+ [+ f1 b" U) ~# d
  13.                
    ; ]( g1 p& ^( x
  14.                 for (num=0; num<8; num++)& Q7 g0 K# s* T7 Z
  15.                 {- F$ l6 d6 Y# c+ M! Q
  16.                         StmL0xxEpromSingleByteRead(EPROM_TEST_ADDR+num, &read[num]);
    2 o, D7 I4 Z/ @9 S' \# j) b
  17.                         if (tmp[num]!=read[num])
    0 P2 ~( |7 H3 a' l* b
  18.                         {! t; o3 E# h: m: C
  19.                                 time = 10;
    ( C( A1 e+ V/ e6 Q
  20.                         }' s6 K* _8 h# O7 o
  21.                 }/ z. E. N" ^7 T$ W  H2 m9 r9 o. N
  22.         
    7 r7 {  [$ [/ |# q# h
  23. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_HALF_WORD, EPROM_TESTEE_ADDR, *(uint16_t *)(&tmp[0])); //// 进入异常中断
    8 h7 B* T! K1 ]- n" Y- O7 t" a
  24. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTEE_ADDR, *(uint32_t *)(&tmp[0]));//// 进入异常中断
    7 J( T( }) x  k% `0 a4 ~
  25.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR, *(uint32_t *)(&tmp[0]));
      P* G8 k) y6 x
  26.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR+4, *(uint32_t *)(&tmp[4]));4 Q7 |/ l/ t. E! V) o+ \
  27.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+0, (UNS32*)(&read[0]));
    0 H0 |) o$ m  a. S6 `" v; E, K; V
  28.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+4, (UNS32*)(&read[4]));' j) k  L) |; ?1 \- k' d
  29.                 ! _& i. H4 L3 S: [" L
  30.                 time ++;
    . ~+ {+ l% o- u# S- `$ g1 |- X6 K* C
  31.         }7 S0 D+ `( G+ @% G4 N, G6 E0 x
  32. }
复制代码
  
    ! O  C& |4 k4 U; V6 G
    * R. g! B5 `+ u; i' A
    : Q* G5 @( |8 c! B7 C9 G5 O
    1 _5 L# r! x* X% G# L! A

    / P' b4 k$ T0 K+ W9 m/ k
3 k! G  ~6 s4 t/ r  f
总结:% n, v8 {0 `0 S6 K+ O
     1. 字节操作时,传入任何地址参数都可以,读写操作正常;0 d+ Q- @6 R" I( K7 ?7 N" O7 d
     2. 但是当半字操作时,如果地址不是2对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;. Q- Q0 p0 w8 T- G5 ?$ N" _
     3. 但是当字操作时,如果地址不是4对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;+ @' [' u! O; V3 o
                 
; g; y1 K( x$ K9 S" C6 p     调试发现调用HAL_FLASHEx_DATAEEPROM_Program函数时进入异常中断。- w7 J. b3 g7 T: H# @
     原因是EEPROM在内存结构上实际是以字为单位的:& Q. q4 ]3 l% T5 O+ Y, }* q- c+ @1 b

9 }' ^- \# X2 \( B6 P( v- W' H      Eprom.png      虽然可以进行字节、半字的参数,但是必须保证地址的对其方式——半字操作以2对齐,字操作以4对齐,否则会出错。
! F5 r3 [' H/ f* t# R
! Q0 V. x5 f% \' ^' ?9 {     !!!!这个代码的对其方式怎么跟贴代码之前不一样呢,完全左对齐了!!!
3 Y  {+ J; U7 j; [1 W' Y5 N6 B! N" N! [2 e# n7 i; g9 A9 p

# f' v, K/ B6 s/ ]% s: f
收藏 2 评论1 发布时间:2018-1-9 15:24

举报

1个回答
zero99 回答时间:2018-2-1 09:30:02
来晚了,感谢支持,已汇总到1月技术原创
4 Q; i7 ~7 I$ l6 o$ t" N. Thttps://www.stmcu.org.cn/module/forum/thread-614550-1-1.html
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版