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

STM32L0x2自带EEPROM读写分享

[复制链接]
power568 发布时间:2018-1-9 15:24
本帖最后由 creep 于 2018-1-9 16:18 编辑 ' J# ~, W% C8 c* f" z* D- I
9 f9 o% n2 e* z# L
       STM32L的EEPROM支持字、半字和字节的读写操作。写操作之前自动擦除,如果写的数据为0,则只执行擦除操作。
6 z& ^( Y# |6 {$ O. p- i: [) B
, \0 P- e, H8 c7 V! n, f4 C6 p       使用STM32Cube库对自带的EEPROM进行操作,代码如下:
5 x3 D' a2 C1 a; _9 l2 C
  1. / J& _, [) k; o& Q
  2. #define                EPROM_WR_TYPE_BYTE                                ((UNS8)0x00)
    2 s" `; }% |2 Z5 B
  3. #define                EPROM_WR_TYPE_HALF_WORD                ((UNS8)0x01)! w( {- L$ R5 d" |: j' P0 k
  4. #define                EPROM_WR_TYPE_WORD                                ((UNS8)0x02)* w; k1 @) E( `8 `

  5. % t' F" O1 x4 E) f1 m. ~) W  V
  6. #define                EPROM_TEST_ADDR                                (STM_EPROM_ADDR_BASE + 12)2 n) E2 o/ f5 u1 l' J
  7. #define                EPROM_TESTE_ADDR                                (STM_EPROM_ADDR_BASE + 32)- n0 O! u6 R7 ]; W  [5 f
  8. #define                EPROM_TESTEE_ADDR                                (STM_EPROM_ADDR_BASE + 61)0 O. ]6 t% j- x! f3 {
  9. , w9 j& C* k; J
  10. //// Unlocks the data memory and FLASH_PECR register access
    $ X2 {! q0 Y) _, h3 T/ {+ v# B0 G
  11. //// ret :
    & A6 V/ m( q& Q0 b8 L) h
  12. ////   OK       = 0x00U,! x( U* i6 m1 |$ U& l8 ?9 \2 B
  13. ////   ERROR    = 0x01U,1 |/ E( J" Z; c5 `* n/ V0 p/ Q
  14. ////   BUSY     = 0x02U,
    ; m4 _! ^5 t; q) w/ G* a
  15. ////   TIMEOUT  = 0x03U1 s  l, p" s' f0 H5 X4 N
  16. UNS8 StmL0xxEpromUnlock(void). g* C+ v2 q, h) X7 E+ J5 p
  17. {2 H& ?( F3 `8 m
  18.         UNS8                ret=0;
    9 v# k5 L, Y3 r4 r
  19.         
    4 F; |+ _( T6 b* o& y% p  ~: I
  20.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Unlock();9 g7 H7 f/ `4 I" f) I- E
  21.         7 C5 [% x4 N2 ?6 u' S3 V# E% z, J
  22.         return ret;
    . l9 a1 H/ q2 e3 g9 {
  23. }
    9 ^/ N9 n" o3 {5 h: w
  24. 1 @  m/ L" U* h
  25. //// Locks the Data memory and FLASH_PECR register access
    $ i$ y1 l& t6 e3 i
  26. //// ret :
    . O5 q% _' o- Z3 o8 ~
  27. ////   OK       = 0x00U,) M( e7 K: z$ C. K9 K: p# Q3 \. R
  28. ////   ERROR    = 0x01U,
    , G8 c. D2 Z3 c  N1 ?' K. \$ R0 \' E
  29. ////   BUSY     = 0x02U,
    # a% h/ i: k5 c/ A; r4 @- d
  30. ////   TIMEOUT  = 0x03U
    ) D9 C( B: h1 W# P
  31. UNS8 StmL0xxEpromLock(void)
    8 g3 B" P5 t# ]
  32. {! U* P( D* E( X, T. _6 L; {
  33.         UNS8                ret=0;
    - _+ ~4 S3 r! j* H; j
  34.         
    3 p. z  \% m1 H
  35.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Lock();% v  ?. C& h% s9 }9 E* K
  36.         
    8 n; D( F7 v* c  m
  37.         return ret;/ A& Z# M4 y' r
  38. }9 O" d7 }8 a' q( j
  39. 0 o! }, \  [6 {  C8 q
  40. //// Erase a word in data memory.- S! M8 i$ ~4 Q- N
  41. //// To correctly run this function, the @ref StmL0xxEpromUnlock() function
    2 B: P+ j' ?5 f/ E. F6 l
  42. //// must be called before.
    & e$ ]9 n! r7 u: T8 e% Q! @4 r! `
  43. //// addr -- specifies the address to be erased.
    . x# X# c$ K0 z) g
  44. //// ret :
    ' ]8 a. u' Q/ J- ?3 m- v
  45. ////   OK       = 0x00U,
    + h! r$ B( D$ \% v7 q' R
  46. ////   ERROR    = 0x01U,% i2 A  G: h) J
  47. ////   BUSY     = 0x02U,
    . ^. o; B5 D5 `' p& w( ?+ }7 h; k
  48. ////   TIMEOUT  = 0x03U
    ; [8 m+ G0 q" G- I7 ^0 c% x
  49. UNS8 StmL0xxEpromWordErase(UNS32 addr)
    5 m8 S2 s; K( |+ U
  50. {
    / n: O) |) F; I6 _
  51.         UNS8                ret=0;+ |. F% c5 w3 H% A2 y
  52.         4 K6 r' v; T! F& Z
  53.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    7 F$ [# h, G5 A. o' c
  54.         {
    $ ?. q" H1 L! G7 ?* n5 f. b$ s
  55.                 return ret;
    " O" U8 C" C! B) ]  [/ ]
  56.         }0 {! Q; l; R1 i5 Z! K3 x
  57.         & ~9 i) G5 l  b3 ?' N
  58.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Erase(addr);
    - m- q, q; [9 o4 X6 l
  59.         * @! l7 Z# y3 b6 M9 U+ @5 M+ E
  60.         return ret;" Z1 W9 q1 a& B$ r/ ]/ e
  61. }
    1 Q  ?  ~/ X1 i. ^! N9 h
  62. ; p" \8 m+ H6 D& I
  63. //// Program data at a specified address. f0 Z# Q6 e9 V) j
  64. //// type :
    + X' T8 g& B8 @
  65. ////   Byte -- 0x00
    5 Z2 e; i; q& N
  66. ////   HalfWord -- 0x01
    ! e  S* I: \" Q, |9 z
  67. ////   Word -- 0x02; C3 l: Q1 e. g2 \, u( \  k& U
  68. //// addr -- specifies the address to be erased.
    3 j$ b4 a  {; ], X
  69. //// ret :" z8 m/ {& u# M; D* s$ w
  70. ////   OK       = 0x00U,
    7 N) M9 z5 k8 b! u/ W
  71. ////   ERROR    = 0x01U,' S  r' `. J3 C7 e9 o7 c3 d1 ?
  72. ////   BUSY     = 0x02U,
      _3 k# ]2 F9 r6 ^- o
  73. ////   TIMEOUT  = 0x03U
    , r2 N  S2 G+ v3 n5 ^9 w
  74. UNS8 StmL0xxEpromSingleWrite(UNS8 type, UNS32 addr, UNS32 data); _/ j4 I( ]: g0 x* G6 D
  75. {$ U) a& U5 p" D( l) P8 B
  76.         UNS8                ret=0;
    . C3 @3 N& b+ K9 t( T) e' ]$ o) @7 y
  77.         , ~; J9 a5 k3 k6 |( l
  78.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    6 W& X9 r7 p& H5 X. w2 ?
  79.         {/ d1 p5 r! w- C& j- a" W& M
  80.                 return ret;
    - Y% E# v3 x, q$ ?1 a* w. a, J
  81.         }. l" x% f* m, P' o, E, n! E$ d
  82.         
      j* A; H6 z; q6 U+ Y
  83.         StmL0xxEpromUnlock();" j4 k' o, J: d- h7 t  f" Q$ I
  84.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Program((UNS32)type, addr, data); //// 库函数5 s( w8 u. ~, M" q
  85.         StmL0xxEpromLock();
    0 m  r- n* C1 R. n& N) F
  86.         
    3 k/ u. F3 E4 V- b
  87.         return ret;: \) [% c5 Q7 s
  88. }& T$ H% a  W* I- V% z

  89. # C  }6 k! F' ], E
  90. //// read a byte at a specified address6 V' W9 y% R2 |9 U2 `
  91. //// addr -- specifies the address to be erased.
    . Y; @4 [0 u: d1 K/ d0 R& K
  92. //// ret :, U! W+ f9 ^+ P+ v. ?1 ~
  93. ////   OK       = 0x00U,
    2 {/ P3 O* a% `! ~
  94. ////   ERROR    = 0x01U,
    ! L0 }3 B& E6 T: k( C# x& ^
  95. ////   BUSY     = 0x02U,1 |0 l* X" _: \5 h
  96. ////   TIMEOUT  = 0x03U
    ) A  j- C; ?( ~; w' d) H% e
  97. void StmL0xxEpromSingleByteRead(UNS32 addr, UNS8 *data)% q1 {; O+ Z$ @
  98. {
    5 _1 j- J* k  ^
  99.         
    5 ~% h) L; t% }- J# N
  100.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    9 n" H: k: \1 K- P
  101.         {; t  ?1 ~6 z% o. Q8 b/ q
  102.                 return ;4 \( ^( _+ s2 ]; @" a2 \' _
  103.         }4 k  i1 w6 v2 H) [/ L/ Z
  104.         
    & i' G3 y& u1 [* a
  105.         StmL0xxEpromUnlock();4 D; B# o/ W' v- R, _$ W
  106.         *data = *(volatile uint8_t *)(addr);% }# l; G$ a* c( {! K) x
  107.         StmL0xxEpromLock();
    * l& P+ N/ n9 U* e
  108. }
复制代码
    测试代码如下:
0 k% j3 W7 h  @6 O. L, h  Z
  1. void EpromTest(void): v. k1 N- I, J+ K
  2. {
    , g* l3 @; L, |7 h
  3.         UNS8        tmp[8] = {1, 2, 3, 4, 5, 6, 7, 8};2 b8 `9 g( B' S
  4.         UNS8        read[8] = {0}, num=0, time=1;
    2 u2 v: A8 {3 {( v
  5.         2 I. p/ t8 i! M4 M
  6.         while(5>time)9 T$ i# d0 S: Q9 M
  7.         {
    7 v2 u4 e. V% y# [
  8.                 for (num=0; num<8; num++)( r9 N! K" y/ z+ @3 y
  9.                 {
    5 P; k& \$ o! z! [
  10.                         tmp[num] *= time;
    . v+ B( O  d5 L
  11.                         StmL0xxEpromSingleWrite(EPROM_WR_TYPE_BYTE, EPROM_TEST_ADDR+num, (uint32_t)tmp[num]);* N( Q/ z) W/ j' L, a5 M2 f
  12.                 }- m4 ~! H' L6 `! P0 D3 `$ _' e# N
  13.                 % K5 l) t8 l4 ?2 `. m
  14.                 for (num=0; num<8; num++)2 Y8 s* P4 L- D2 y# J, T- O2 q
  15.                 {9 Z) z* L# v, _
  16.                         StmL0xxEpromSingleByteRead(EPROM_TEST_ADDR+num, &read[num]);
    3 V% D( T+ D5 ~. y8 X& `& F- X
  17.                         if (tmp[num]!=read[num])$ v) `8 G2 N9 N6 F
  18.                         {
    $ T1 j5 p$ Q( U; ]' i& E. K
  19.                                 time = 10;
    * R* e$ W" V8 V" E0 r0 K3 s1 h' `
  20.                         }% H, p# g2 n! Q. N: z/ Z
  21.                 }
    * H& c" j: c! G  j
  22.         
    5 c! c7 \& T  B9 J+ g
  23. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_HALF_WORD, EPROM_TESTEE_ADDR, *(uint16_t *)(&tmp[0])); //// 进入异常中断
    % }9 k3 U2 S2 q9 V* n- ?5 U
  24. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTEE_ADDR, *(uint32_t *)(&tmp[0]));//// 进入异常中断# O  m+ v0 h  d
  25.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR, *(uint32_t *)(&tmp[0]));
    : ?2 a7 B# ~7 t% h8 P8 ^2 I/ v- V
  26.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR+4, *(uint32_t *)(&tmp[4]));1 k! m% [  o/ f& b) a; l% W/ d/ j( R
  27.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+0, (UNS32*)(&read[0]));. P& e" I% B; F
  28.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+4, (UNS32*)(&read[4]));
    8 v2 m. d: O7 L+ A# A
  29.                   y) k5 I( Y4 t4 A
  30.                 time ++;
    , \. G6 z5 A; [0 s1 [
  31.         }
    7 V6 v% H! x$ X
  32. }
复制代码
  
    ! W! X0 [! z# B) F

    $ J2 A  d: p; W* {4 t
    2 f! l( U* G: R3 d2 U5 n  \: z  a2 X# E' e

    2 ^3 F2 g  H8 C* i
! N! k$ ~" [" H6 G8 M, M9 W* y. x
总结:" I  C6 M9 W$ k7 N7 w5 H; r" N
     1. 字节操作时,传入任何地址参数都可以,读写操作正常;& Y! a; c0 Z. `. a( W& l6 G
     2. 但是当半字操作时,如果地址不是2对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
" n- X+ L: B* l7 x, s     3. 但是当字操作时,如果地址不是4对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;' z. }  s+ z* T
                 
8 j* W: X3 s0 d1 z% ^7 ~3 k- ?     调试发现调用HAL_FLASHEx_DATAEEPROM_Program函数时进入异常中断。
5 g$ M' c6 s& A0 V2 e/ ~     原因是EEPROM在内存结构上实际是以字为单位的:# M4 d. ~1 ?1 u: D8 C  f

, I' w* F" i; w: z. _      Eprom.png      虽然可以进行字节、半字的参数,但是必须保证地址的对其方式——半字操作以2对齐,字操作以4对齐,否则会出错。) n, J7 ?0 i2 ~- ]4 U
. X) L9 y' B+ f/ v1 e% f9 v& _. E5 P4 r
     !!!!这个代码的对其方式怎么跟贴代码之前不一样呢,完全左对齐了!!!* k9 N1 `- o) A# T" S( T7 S2 B; E" M3 ^3 B
; X) F+ H4 N  O

6 L2 h5 ]! P9 [  N, m
收藏 2 评论1 发布时间:2018-1-9 15:24

举报

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