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

STM32L0x2自带EEPROM读写分享

[复制链接]
power568 发布时间:2018-1-9 15:24
本帖最后由 creep 于 2018-1-9 16:18 编辑 2 e1 F( J8 A1 Y, V

% J$ M  W7 w& {3 M/ D' X( E       STM32L的EEPROM支持字、半字和字节的读写操作。写操作之前自动擦除,如果写的数据为0,则只执行擦除操作。
9 d, w1 _# M( s' z! ^
! m' u3 D- \; x( V4 R2 ^       使用STM32Cube库对自带的EEPROM进行操作,代码如下:0 N5 y/ U. X; E( R' M9 B4 Y

  1. * y" t, P+ Z  g2 \+ P# b, a' ?: }
  2. #define                EPROM_WR_TYPE_BYTE                                ((UNS8)0x00)
    $ }7 A8 T* }8 d6 N1 O. n+ Q3 R
  3. #define                EPROM_WR_TYPE_HALF_WORD                ((UNS8)0x01)
    , V4 D( U6 W+ `6 P
  4. #define                EPROM_WR_TYPE_WORD                                ((UNS8)0x02)( @0 A. ?4 s% n4 ]' N) _

  5. ! Q! W8 C# C' d! x& N- e& E6 y
  6. #define                EPROM_TEST_ADDR                                (STM_EPROM_ADDR_BASE + 12)
    ; M; G0 Y8 `) L7 r7 W' J
  7. #define                EPROM_TESTE_ADDR                                (STM_EPROM_ADDR_BASE + 32)
    3 f# y$ T( S( o: m' O$ J
  8. #define                EPROM_TESTEE_ADDR                                (STM_EPROM_ADDR_BASE + 61)
    ' A5 E+ l: \; N

  9. 9 k. j# J5 O% ^3 r( Q! ?# q
  10. //// Unlocks the data memory and FLASH_PECR register access
    3 W0 ~% f8 T! y/ \1 Z" q% c
  11. //// ret :' e6 e/ F( H$ g7 W# ~+ n
  12. ////   OK       = 0x00U,
    ' z% A! u& M2 w# P, h
  13. ////   ERROR    = 0x01U,
    , x7 w' s9 X9 ^3 f$ Y" \' e0 z, J. H5 |& @
  14. ////   BUSY     = 0x02U,
    ! Q+ U1 w; A6 R0 u! x! J' D
  15. ////   TIMEOUT  = 0x03U
    : u8 X  I! A) ?3 R. r3 E. F3 l& j
  16. UNS8 StmL0xxEpromUnlock(void)
    ; P( w& v; Q# N+ L. [
  17. {
    - g6 J* J& n- w9 K# z* x
  18.         UNS8                ret=0;
    ( _2 W. ~; Y7 H0 ~9 ~8 W. S
  19.         ( R( P. O9 E. n4 {1 B
  20.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Unlock();5 C9 I- J/ `) o/ F( e9 G4 x
  21.         & {& r5 G+ X" w
  22.         return ret;' Z/ \6 J: [: f
  23. }
    " t$ P# u. C0 e  f. A7 b

  24. 5 w8 ?5 T9 H8 {6 z
  25. //// Locks the Data memory and FLASH_PECR register access
    4 j- G0 t9 g& D1 E; g
  26. //// ret :7 Z  @- a4 j7 C& V: B
  27. ////   OK       = 0x00U,
    / }. ^. N1 u, X
  28. ////   ERROR    = 0x01U,( b5 A6 t2 l7 S) J) y' w- F0 Z
  29. ////   BUSY     = 0x02U,
    4 i/ \2 k# C1 x$ I, h* b
  30. ////   TIMEOUT  = 0x03U
    ' g9 `% t4 j6 f0 V4 v, S- s
  31. UNS8 StmL0xxEpromLock(void)# v, A0 {. \$ ^4 x- a
  32. {
    % Y: X8 M7 W: m
  33.         UNS8                ret=0;
    2 j7 c1 }- B; t* v: \
  34.         
    9 Z" y% j) P! G
  35.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Lock();
    # X& G# s. [" z7 k) D, B
  36.         1 g. \9 E/ R4 B+ ]4 ~' t' a
  37.         return ret;: d& W; i2 {3 N$ c! c, a/ T( Y5 o
  38. }
    7 m8 s4 O  ]6 R/ J. Q9 D, o

  39. 0 G3 J  G: s7 V* q5 w
  40. //// Erase a word in data memory.% T$ w! E' m) _5 M4 g' f
  41. //// To correctly run this function, the @ref StmL0xxEpromUnlock() function
    ; W) {; A- h1 E; V: X: i- r
  42. //// must be called before.
    * b$ U  S) i1 C' C7 N! K4 l* w2 c" X
  43. //// addr -- specifies the address to be erased.! c" m5 m& k6 Y6 w, s) |# T
  44. //// ret :8 n$ l9 @4 m* Q# d
  45. ////   OK       = 0x00U,/ i8 g4 H  k/ D1 J$ x
  46. ////   ERROR    = 0x01U,# V" m5 Z* b& p7 r
  47. ////   BUSY     = 0x02U,# X& y, o1 M7 H1 h! i
  48. ////   TIMEOUT  = 0x03U: q+ Y6 h3 ?1 D3 e# e% ^8 l/ q
  49. UNS8 StmL0xxEpromWordErase(UNS32 addr)" r4 K3 v8 [$ e. Z, a
  50. {+ V8 T! W1 g( v4 h2 O) K
  51.         UNS8                ret=0;
    : D' @) x- K+ ?4 k# ]# |7 x
  52.         ; w# f' @/ Z( H+ u
  53.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )- f4 ~6 Y0 O' G/ z9 S' h0 k$ c
  54.         {
    , C) p$ q& s1 ^7 |1 f! Q( B' S* ?
  55.                 return ret;
    6 W8 A) ]( Q% m5 }& ^0 u8 M% ~# z/ Z8 h, C
  56.         }) Z' a/ P  i6 h) r! ^4 @' I- l
  57.         
    : H! |5 F( W& l/ \! s" o8 [
  58.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Erase(addr);
    4 ~/ s* E1 A6 S% Y
  59.         
    5 l: j9 E) Q/ l# r1 ~! e2 ~
  60.         return ret;8 y6 h$ G# o3 f' B% P; m; d' D3 t  q
  61. }8 p! h3 f$ {& M0 L: b

  62. * ?( T; n' V, g: U5 t8 n- t. r: H( m
  63. //// Program data at a specified address7 T. T! t+ J" X2 U: S: L
  64. //// type :* a# H) K! F) W( z3 _
  65. ////   Byte -- 0x00* x6 u# t7 L6 V
  66. ////   HalfWord -- 0x01
    . L# D6 W) x% I$ `" x! x# N5 ]
  67. ////   Word -- 0x02# p* m+ l- C- }* i; z# s
  68. //// addr -- specifies the address to be erased.
    4 F" W+ Y# B& c$ U6 A# V
  69. //// ret :: o  \" Q8 w9 Y" S, V
  70. ////   OK       = 0x00U,
    * x% S# l7 u$ s/ a  Y  M' ^
  71. ////   ERROR    = 0x01U,
    ) l, ^9 F3 O. M
  72. ////   BUSY     = 0x02U,
    3 \1 `! _) Q! U  g
  73. ////   TIMEOUT  = 0x03U
    7 F  D! u9 }" f( L1 ]
  74. UNS8 StmL0xxEpromSingleWrite(UNS8 type, UNS32 addr, UNS32 data)
    * q% l7 d$ U) j! O0 O
  75. {
    : I* Q4 M4 o5 o4 w0 f' Y
  76.         UNS8                ret=0;; B& T* J2 L' f' D
  77.         
    * w7 X+ d- z8 Z8 M
  78.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )6 `- e- ]# J/ x1 `$ r' ]( d
  79.         {$ t8 Y# {  }8 m2 ]4 M
  80.                 return ret;9 p' k, p5 \1 ^3 a  L
  81.         }! A9 c/ Y; ?  n6 a% o( K
  82.         - P5 p. L$ W8 j. r$ R4 |2 C0 `
  83.         StmL0xxEpromUnlock();
    8 P) m* i' d) o' B0 }" S
  84.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Program((UNS32)type, addr, data); //// 库函数
    3 T0 r$ Z$ N& P( r- d/ q$ f
  85.         StmL0xxEpromLock();
    % J% I  q/ s6 `, w$ ^
  86.         
    " ?6 l0 w/ z/ U9 o( w' ]* L
  87.         return ret;  V5 _) r7 U0 T5 i% c$ w  |
  88. }
    ! v# x. k" t9 V, A7 W: e" R

  89. 9 B1 {. Y9 N( l( h, Y
  90. //// read a byte at a specified address
    ( Y  |5 o5 h% h9 |
  91. //// addr -- specifies the address to be erased.- v3 a' I& q; K5 B* A
  92. //// ret :
    0 B) z2 S: T7 G! ^
  93. ////   OK       = 0x00U,
    ' T" W2 l: n8 h% B
  94. ////   ERROR    = 0x01U,- I$ }: N7 v1 ?7 P8 H2 K( h
  95. ////   BUSY     = 0x02U,
    6 k4 Y: L1 ]3 S2 Z
  96. ////   TIMEOUT  = 0x03U
    $ I+ S, p% _  e2 B$ z3 q. O5 l8 t
  97. void StmL0xxEpromSingleByteRead(UNS32 addr, UNS8 *data)
    3 k. y" b4 B4 @; Q" y
  98. {
    5 S) {; z4 j- U  I* i
  99.         # y% ?$ a" j6 f! Q& c  f
  100.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    3 w" q5 P: Q6 {
  101.         {1 ^7 g. B( O9 d0 B9 u" e" R2 v7 J6 [
  102.                 return ;2 z) k  h  \4 s  h" J1 i
  103.         }+ K. n. t+ u. ^+ S7 {7 y5 J" o: d* P
  104.         % |5 |" }$ b& \$ E& x1 K% u
  105.         StmL0xxEpromUnlock();. _2 A- \  \8 j" ^: G
  106.         *data = *(volatile uint8_t *)(addr);
    & d( F6 v* n6 F
  107.         StmL0xxEpromLock();
    ! y$ U# A! D3 t, K7 @
  108. }
复制代码
    测试代码如下:. t7 z) U5 G  j
  1. void EpromTest(void)
    1 X5 \% @! r. x3 ^
  2. {! {1 X& C; y; {/ W# F3 O: u
  3.         UNS8        tmp[8] = {1, 2, 3, 4, 5, 6, 7, 8};( d0 L9 u9 Y% Y. z" e$ b
  4.         UNS8        read[8] = {0}, num=0, time=1;
    * m9 y* a  r& t- k' {
  5.         * K% e  h+ T/ o* J
  6.         while(5>time)6 f6 m) Q& o0 x  h. H, k
  7.         {
    ' P* A5 ]/ X" u; E2 ]" S: r
  8.                 for (num=0; num<8; num++)
    : k: c; E5 A4 P! T7 a
  9.                 {
    + T! x& x' |8 I0 H! z, l) U" m+ ~
  10.                         tmp[num] *= time;# D, d2 M2 I6 @/ r7 p0 {1 q
  11.                         StmL0xxEpromSingleWrite(EPROM_WR_TYPE_BYTE, EPROM_TEST_ADDR+num, (uint32_t)tmp[num]);
    / N1 Q4 q* R. C& [7 ]4 C
  12.                 }
    5 W# n5 O9 m5 Y! d7 X
  13.                 3 v& z4 v2 ~( S( X1 l4 ~4 Q7 i" H& Z
  14.                 for (num=0; num<8; num++)  n: o& \+ i  Z. V3 Y' t  t
  15.                 {( g4 s; b+ H1 t% Y# J4 Y7 p  q( H3 |% E
  16.                         StmL0xxEpromSingleByteRead(EPROM_TEST_ADDR+num, &read[num]);8 s! T% E3 K! |; t5 r0 d" f
  17.                         if (tmp[num]!=read[num])
    8 \0 i& i/ e7 a, R" Y$ {9 ?: }" c
  18.                         {2 a4 ^% ?& F" g$ S! d
  19.                                 time = 10;
    1 e) Y" g! P( P% B  l  ?1 o0 e
  20.                         }1 C' s. }1 t: z, z* S) g! l
  21.                 }
    : ]  W; M. s8 N7 u0 j" v
  22.         - b* O( v' {* y, `* }2 ^; ~+ e3 @; V& R3 ^
  23. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_HALF_WORD, EPROM_TESTEE_ADDR, *(uint16_t *)(&tmp[0])); //// 进入异常中断
    $ x9 L# Q6 A) B+ |$ G. R
  24. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTEE_ADDR, *(uint32_t *)(&tmp[0]));//// 进入异常中断
    9 r( u; c- J9 [) V& O6 P" b
  25.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR, *(uint32_t *)(&tmp[0]));
    " Y9 [5 A5 A8 ?8 `( T/ L
  26.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR+4, *(uint32_t *)(&tmp[4]));
    / d5 |( |1 N2 ]/ L
  27.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+0, (UNS32*)(&read[0]));
    * M% b! p0 `# M& p: p
  28.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+4, (UNS32*)(&read[4]));
    ' J; |/ Z: \) n- h2 H; s5 N0 x# d) }) J
  29.                
      d' ?8 D" S7 R; D
  30.                 time ++;/ W" X/ }$ p$ K2 ]2 q7 h
  31.         }
    . m( W9 M" y+ d: y5 F; z9 X: o
  32. }
复制代码
  
    2 z% R0 L# O- L0 f1 y: C4 b; O

    $ t1 |8 }6 E1 Y% l/ ^: u( `$ g1 U! }

    6 `, D( p* _; w1 t4 f7 u* {7 ?; F2 G  H* A

; V7 N2 A8 y. M, p' H4 X
总结:
# _  x3 d: f3 u" i9 N     1. 字节操作时,传入任何地址参数都可以,读写操作正常;
" p7 ~0 f. j  I6 H     2. 但是当半字操作时,如果地址不是2对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
/ G3 `8 _! w6 U; O+ L     3. 但是当字操作时,如果地址不是4对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
7 I7 z% [. P9 n! z: v1 _                 
) c! }1 |  X) S     调试发现调用HAL_FLASHEx_DATAEEPROM_Program函数时进入异常中断。: s" V0 D3 U- m" f- }$ P" e) ?: x
     原因是EEPROM在内存结构上实际是以字为单位的:
! `7 \4 Y9 h  v  o
( {! I) g  U5 U8 j; T0 W      Eprom.png      虽然可以进行字节、半字的参数,但是必须保证地址的对其方式——半字操作以2对齐,字操作以4对齐,否则会出错。
' @3 ]) H7 p2 r' k9 S& ]" Z% R
7 Y7 S/ N8 H. J3 v& y# z     !!!!这个代码的对其方式怎么跟贴代码之前不一样呢,完全左对齐了!!!7 m9 b4 X4 N0 I0 V2 F

' q7 Z! l3 y# h- M& b3 }8 {: Y) ^  G* Z3 t; w" C& V
赞 收藏 2 评论1 发布时间:2018-1-9 15:24

举报

1个回答
zero99 回答时间:2018-2-1 09:30:02
来晚了,感谢支持,已汇总到1月技术原创3 u& x6 `' T' l
https://www.stmcu.org.cn/module/forum/thread-614550-1-1.html

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版