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

STM32L0x2自带EEPROM读写分享

[复制链接]
power568 发布时间:2018-1-9 15:24
本帖最后由 creep 于 2018-1-9 16:18 编辑
9 G5 P4 O2 j0 j, E( c% b2 q
% W6 \6 Q5 w2 U' V' p; F, |       STM32L的EEPROM支持字、半字和字节的读写操作。写操作之前自动擦除,如果写的数据为0,则只执行擦除操作。
# G8 ]1 z0 T# O6 c) e/ X5 C- J6 T: o/ H" w
       使用STM32Cube库对自带的EEPROM进行操作,代码如下:
- B6 n, u5 L9 R
  1. * k+ X. D0 S0 D% k) z/ U
  2. #define                EPROM_WR_TYPE_BYTE                                ((UNS8)0x00)
    6 R( L" |& C- S9 K- x
  3. #define                EPROM_WR_TYPE_HALF_WORD                ((UNS8)0x01)/ ~! S/ g' P3 H. e4 q0 ~2 O
  4. #define                EPROM_WR_TYPE_WORD                                ((UNS8)0x02)9 u+ K! ]8 k' m' F

  5. ! n7 P, p" X( H* Q& j: s2 Q
  6. #define                EPROM_TEST_ADDR                                (STM_EPROM_ADDR_BASE + 12)! U& ?5 a% ?3 T; E- _
  7. #define                EPROM_TESTE_ADDR                                (STM_EPROM_ADDR_BASE + 32)
    , K. k7 P5 Z% [! x3 {( i
  8. #define                EPROM_TESTEE_ADDR                                (STM_EPROM_ADDR_BASE + 61)
    . v; k; C+ j  p& n! ^
  9. / {  f. D- y7 |1 G" I
  10. //// Unlocks the data memory and FLASH_PECR register access; t! E; R$ U' h; G3 v
  11. //// ret :
    0 X/ `. r# W6 o/ U4 r
  12. ////   OK       = 0x00U,
      J3 F$ I& d2 Z, I4 C( D
  13. ////   ERROR    = 0x01U,, I2 B& Q' z& Y( z
  14. ////   BUSY     = 0x02U,
    . x4 e" U3 ?2 x& \8 @$ p# [. p- z
  15. ////   TIMEOUT  = 0x03U. p  v3 j* h+ o& O* T! u; g( r. a" U
  16. UNS8 StmL0xxEpromUnlock(void)9 q  Z" H* R& g% A5 y, C
  17. {3 I" l+ ]0 ^6 H" y$ U- x. C8 C6 t
  18.         UNS8                ret=0;
    / }' t: x4 Q5 ^! d" W
  19.         
    ! @* o, H0 [- e2 W4 P% ]! Z
  20.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Unlock();) @( J1 U7 H5 @6 c8 s2 l$ A
  21.         
    5 Y1 E8 y$ m2 G  f6 }6 j. w$ M
  22.         return ret;3 A- B3 c2 X8 a9 t8 A2 g& D: \! [9 J
  23. }0 a8 H, @6 Y6 \1 N& c/ U

  24. 7 i1 i% i' i- `8 T/ |# D/ q  C% h
  25. //// Locks the Data memory and FLASH_PECR register access6 c0 ?0 Z9 f, b1 G$ j: I+ G- \% c
  26. //// ret :4 b* f" D+ ]. ~8 {/ n
  27. ////   OK       = 0x00U,
    ) y8 v$ R( y) @' h+ q) R% ^
  28. ////   ERROR    = 0x01U,
    4 {; k: H& i3 d5 g- {  t0 c
  29. ////   BUSY     = 0x02U,
    7 G" p* q0 {6 c2 K
  30. ////   TIMEOUT  = 0x03U
    $ r* D2 O! g! T" f( C
  31. UNS8 StmL0xxEpromLock(void)+ V1 N6 a& M! E/ M8 }% V1 O8 Q
  32. {
    . m3 q1 @7 ?/ H+ y
  33.         UNS8                ret=0;) U; o6 }9 ^; e- X
  34.         
    9 \. r) h2 X* f0 n
  35.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Lock();
    ) i$ y/ `) l5 {" j
  36.         
    . J/ w) A. Q  f6 D: _3 f2 `
  37.         return ret;
    ! K& L6 N$ H5 c* p$ b7 N
  38. }
    1 O8 V3 _  }8 q
  39. * v& z: I/ B  A. N4 T' i: G
  40. //// Erase a word in data memory.
    - r, K. Y# N/ a) g
  41. //// To correctly run this function, the @ref StmL0xxEpromUnlock() function8 }! S8 @. n  y2 _. L+ x9 V% S  g4 B
  42. //// must be called before.
    " ]) B8 [7 G5 I  R* _' ?/ O
  43. //// addr -- specifies the address to be erased.0 l" A) k4 s3 Y
  44. //// ret :
    7 ~) p7 b' f* W% W/ l9 [& X
  45. ////   OK       = 0x00U,! z0 }5 Z4 x: o  n% F
  46. ////   ERROR    = 0x01U,
    ; O# k1 n: H2 p
  47. ////   BUSY     = 0x02U,7 ~  F2 A. o  J8 ^5 e9 J  H) C
  48. ////   TIMEOUT  = 0x03U" @- u+ v3 M5 e  O
  49. UNS8 StmL0xxEpromWordErase(UNS32 addr)  z" c. C. K* B8 W) z8 }, L. S
  50. {
    . D, o* z- `  `
  51.         UNS8                ret=0;5 f) N8 |: Z7 |2 J- i5 [4 y" k
  52.         
    3 W" k. ]7 S! R+ o: U# t
  53.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )" d* k/ o0 k7 _( I4 n6 c  p  G
  54.         {  ]. Y: ]8 C7 k$ L- e& E
  55.                 return ret;8 x( Y) e, G/ W7 p9 f# c) E
  56.         }
    - v! E0 X2 R/ o- [1 a
  57.         
    5 K0 w+ |* D8 R6 F2 [% W
  58.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Erase(addr);2 Z4 P, o: w! g6 a4 ?) S( C( L$ v
  59.         ) W5 T6 y4 q0 z+ C- K5 Z
  60.         return ret;
    # d+ `: W# d4 m% a5 \
  61. }4 S/ G# h; Z. ]9 c3 o7 d6 C

  62. ( k- }# C' |, W
  63. //// Program data at a specified address
    - g8 G5 T- v, S" P4 L0 A7 I4 }
  64. //// type :7 _! t' c5 f' e5 V3 I
  65. ////   Byte -- 0x00
    0 b1 B2 \5 l# S+ x
  66. ////   HalfWord -- 0x01
    6 D! E( V( x8 r( M9 D6 B$ q2 M4 W
  67. ////   Word -- 0x02
    ! G6 v- j" X( K. W6 h
  68. //// addr -- specifies the address to be erased.
    % ]+ R9 }: i. z8 ?; o7 b
  69. //// ret :
    . l+ {4 M' o" u9 F- {8 {3 r: I+ Z
  70. ////   OK       = 0x00U,9 c5 r4 o) v# ^. j% C" d4 k. H. {
  71. ////   ERROR    = 0x01U,
    5 l0 j9 S. ~5 a4 N9 Y
  72. ////   BUSY     = 0x02U,
    9 B- K" J$ [0 H$ K
  73. ////   TIMEOUT  = 0x03U. T- S5 C0 C5 [+ W( c/ X, v/ T8 f) O
  74. UNS8 StmL0xxEpromSingleWrite(UNS8 type, UNS32 addr, UNS32 data)7 ^+ a& h* X2 X- q; R- W  J
  75. {& ^9 F- A- H9 \! E
  76.         UNS8                ret=0;
    ; |' B: X0 r" b6 Z
  77.         - U3 u/ s9 u( n4 `. M
  78.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    / p- S: V% e9 R$ ]  I$ K
  79.         {5 R8 s' V$ N) t; D
  80.                 return ret;
    4 M+ I3 ~1 O7 ]. u; O
  81.         }) x. u( e3 _- M
  82.         
    3 \+ z- S0 d* w+ W' t
  83.         StmL0xxEpromUnlock();: x4 `( ]7 {7 w+ u- \; L
  84.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Program((UNS32)type, addr, data); //// 库函数
    ; g5 R5 q$ M) ?/ W* z# X3 Y
  85.         StmL0xxEpromLock();( m0 h; w+ f: Y) m. u' L$ ~
  86.         
    2 o) x/ l# Z; _0 P6 @* K2 ~
  87.         return ret;
    - n6 G  r+ m2 T! Z) U: ]
  88. }- d" G7 M' S" b- S) g/ ~

  89.   h5 P  E5 b0 x1 T: d, B& M
  90. //// read a byte at a specified address
    % v0 b* [; |7 M8 _
  91. //// addr -- specifies the address to be erased.
    6 R# q/ v9 m6 ]
  92. //// ret :
    8 J: l: P2 Y5 Z: \# S
  93. ////   OK       = 0x00U,
    7 P1 x) z; |+ O" _+ k
  94. ////   ERROR    = 0x01U,
    4 \, ~5 o( d3 l6 w4 `8 f
  95. ////   BUSY     = 0x02U,; [7 r5 O' a4 w- L. c" D0 Y
  96. ////   TIMEOUT  = 0x03U, K( r% p# d+ W0 H4 Q3 o
  97. void StmL0xxEpromSingleByteRead(UNS32 addr, UNS8 *data)
    9 c2 N9 R' I% A' m( z, Z/ r
  98. {" I% q+ K& r# r8 m) ~+ K0 d# \6 k
  99.         7 E; C8 Y# l4 J# U8 e
  100.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )3 u& Y  @) U( M2 y% H
  101.         {" V+ r+ h) [( O
  102.                 return ;! e+ ]/ I( Y4 u% M' j3 p
  103.         }4 W# B- s* s+ w& x5 Y/ j; r! y- r
  104.         
    * {& e$ X# Q& n5 ~+ N0 C+ v; Y
  105.         StmL0xxEpromUnlock();
    3 w" h6 F9 n6 a5 |& g: O
  106.         *data = *(volatile uint8_t *)(addr);
      Y: G8 r4 A6 h% D) H) H
  107.         StmL0xxEpromLock();% N# N, }0 ^9 X# a
  108. }
复制代码
    测试代码如下:% B5 C5 C% }  S7 P; {
  1. void EpromTest(void)5 V9 [; P- B' E9 _% h
  2. {( o- i% s0 ^! w- T$ u) E& e
  3.         UNS8        tmp[8] = {1, 2, 3, 4, 5, 6, 7, 8};7 J6 Q. G! W: U- a) h! x: L
  4.         UNS8        read[8] = {0}, num=0, time=1;: l; ~' ~" N( o/ l) t$ ]) O
  5.         
    7 k" d8 a1 C+ ]! C  A4 c
  6.         while(5>time)( f3 ~$ m3 [4 O, f3 x7 |# B
  7.         {
    % Z" Z/ n# Q: ?+ L# o7 n! H2 W
  8.                 for (num=0; num<8; num++)8 J2 H0 A+ @! ?# K
  9.                 {0 [" @& x9 L/ @% h# {
  10.                         tmp[num] *= time;
      m+ u& X" J3 I0 |
  11.                         StmL0xxEpromSingleWrite(EPROM_WR_TYPE_BYTE, EPROM_TEST_ADDR+num, (uint32_t)tmp[num]);
    . P: q* R2 K# ^9 p
  12.                 }# T# q* ]% ^3 I
  13.                   a3 Q- B( m/ z  A8 u( L! H+ o
  14.                 for (num=0; num<8; num++)
    4 E7 D! I; T& g- A+ y
  15.                 {) P6 ~. s. Y/ U7 Y) F% J' Y
  16.                         StmL0xxEpromSingleByteRead(EPROM_TEST_ADDR+num, &read[num]);
    ' H1 i/ A  v" U4 G+ n8 K
  17.                         if (tmp[num]!=read[num])
    : ^& Q) l4 [( t2 a+ [
  18.                         {9 o: [. _% B5 t; _5 p; |
  19.                                 time = 10;. `: M1 t# F6 P
  20.                         }/ \0 m4 ^. e( T" V3 y. g* @
  21.                 }* Q' v$ d  U! O% x, r
  22.         
    4 n( b( m  d' E. f! L
  23. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_HALF_WORD, EPROM_TESTEE_ADDR, *(uint16_t *)(&tmp[0])); //// 进入异常中断
    & V: x. F, k6 ?" l0 k7 j% Q
  24. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTEE_ADDR, *(uint32_t *)(&tmp[0]));//// 进入异常中断
    9 h( {# c9 M; M; K; B7 B
  25.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR, *(uint32_t *)(&tmp[0]));
    * o# a9 o4 r+ X6 ]' p" g
  26.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR+4, *(uint32_t *)(&tmp[4]));
    * `+ q, p, n3 |; v; ~; M! X) N
  27.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+0, (UNS32*)(&read[0]));4 X" p/ }& d. J" y" s
  28.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+4, (UNS32*)(&read[4]));( m# q; b5 ^' P* o7 C, v. F; q
  29.                 : [5 @6 q6 A5 O# w+ [8 u
  30.                 time ++;
    / h$ @( L) Q- f; V4 s' x! e
  31.         }
    : ^6 g. F( y! ^4 t' L6 A9 ]
  32. }
复制代码
  
    2 f3 H# G5 E% |! d0 J
    , O; }. U: K7 @2 T3 _7 t
    : g1 m: Q6 \" Z5 y; J$ q

    , [2 R  r; ?+ h8 j( m1 n5 I
    , f* E# L) z+ Q& w. Q5 r

, Z% Q" M# m/ q3 x5 {& `
总结:
* }( Z+ ^& w- E     1. 字节操作时,传入任何地址参数都可以,读写操作正常;$ B# C0 R0 M2 y. R
     2. 但是当半字操作时,如果地址不是2对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
* Y2 S0 e0 E+ ]+ n8 v# r     3. 但是当字操作时,如果地址不是4对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;% f* |3 C( M1 d' O+ T! K+ J
                 8 |! U+ I, o+ {5 H: \
     调试发现调用HAL_FLASHEx_DATAEEPROM_Program函数时进入异常中断。: V; ]/ k* w  _9 B
     原因是EEPROM在内存结构上实际是以字为单位的:
% O9 m! r! {: ^& c
7 N: W! z# v3 z2 A% [/ ^      Eprom.png      虽然可以进行字节、半字的参数,但是必须保证地址的对其方式——半字操作以2对齐,字操作以4对齐,否则会出错。
  H! Z" h9 f& b9 M/ T( \
& v3 v% o3 N8 ]! u9 ?6 |     !!!!这个代码的对其方式怎么跟贴代码之前不一样呢,完全左对齐了!!!& ]2 _# \4 N9 N. Y+ y4 \

0 ~1 S7 v6 n$ {  B, M. a& }2 A& c' I7 N, a4 c$ D7 _8 f
收藏 2 评论1 发布时间:2018-1-9 15:24

举报

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