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

STM32L0x2自带EEPROM读写分享

[复制链接]
power568 发布时间:2018-1-9 15:24
本帖最后由 creep 于 2018-1-9 16:18 编辑
8 E" s# h6 J/ `; v3 n! ~: u7 l& z
       STM32L的EEPROM支持字、半字和字节的读写操作。写操作之前自动擦除,如果写的数据为0,则只执行擦除操作。
0 R& a, O3 }# p% I% C1 S: {
+ ?& P( ?3 K+ {" d  v" d       使用STM32Cube库对自带的EEPROM进行操作,代码如下:
# p9 r! k8 J$ }4 ]2 V
  1. 3 B  [; i* ~( `. ~2 @' P
  2. #define                EPROM_WR_TYPE_BYTE                                ((UNS8)0x00)
    9 _( ]! ?5 v7 Z+ j/ p9 [7 G
  3. #define                EPROM_WR_TYPE_HALF_WORD                ((UNS8)0x01)+ L) ]7 V+ w: g3 z2 T/ I% [
  4. #define                EPROM_WR_TYPE_WORD                                ((UNS8)0x02)
    9 l) v; F0 x* Z6 K. e
  5. 7 s! C! Q: r  R( Q; `
  6. #define                EPROM_TEST_ADDR                                (STM_EPROM_ADDR_BASE + 12)) p. f  X- x  p
  7. #define                EPROM_TESTE_ADDR                                (STM_EPROM_ADDR_BASE + 32)
    * S# i$ s& \8 J5 g
  8. #define                EPROM_TESTEE_ADDR                                (STM_EPROM_ADDR_BASE + 61)
    * P1 g2 P& K- o- a  i

  9. : n; L0 I' q" E, c4 a6 q
  10. //// Unlocks the data memory and FLASH_PECR register access1 |4 Q: L) P/ F+ L" J4 ]
  11. //// ret :& y3 L2 f6 _+ ~4 N4 X
  12. ////   OK       = 0x00U,
    & f/ ?  z0 T( r3 }4 }, ^
  13. ////   ERROR    = 0x01U,
    " b3 w" Y6 W0 @+ Y7 R
  14. ////   BUSY     = 0x02U,- D7 k0 T$ @1 N) s) T+ e
  15. ////   TIMEOUT  = 0x03U
    % L2 o6 Z% V0 y" [9 A
  16. UNS8 StmL0xxEpromUnlock(void)
    0 C3 }' R" J7 M
  17. {2 V: S  G9 ?! {* r
  18.         UNS8                ret=0;
    ; V- p- ?* s- K3 k5 K
  19.         3 E$ [; s& H/ F5 @! n% z
  20.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Unlock();5 I8 t8 O$ O3 J/ I1 P5 }$ D$ p
  21.         . u8 a' k, C" R; R5 x2 F4 o  I: q
  22.         return ret;7 I4 V8 s4 ~, o$ y% a9 @6 U; P+ u9 w
  23. }
    ) X2 V  G6 [4 P* ~

  24. 4 ?! \/ Z4 w4 V4 N) V$ g  R
  25. //// Locks the Data memory and FLASH_PECR register access! ^/ Z9 j9 u; ]7 _: O. Z# S. Z( f
  26. //// ret :. p: _$ A3 s( _! M
  27. ////   OK       = 0x00U,+ d7 y  M" r0 p5 q5 K# ]
  28. ////   ERROR    = 0x01U,' u& l+ G9 M8 W8 A6 G2 e
  29. ////   BUSY     = 0x02U,/ K# p' }" K6 H/ m
  30. ////   TIMEOUT  = 0x03U5 r+ H5 q% Q6 j  ]' B
  31. UNS8 StmL0xxEpromLock(void)
    % f7 O" W/ \% C: v, y1 C% Q
  32. {
    # L) Q5 R: V0 j  N' q2 ~3 q
  33.         UNS8                ret=0;
    ; t7 J6 c; l8 u# k
  34.         
    $ m% A/ B, i$ i4 _4 I
  35.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Lock();! b( m! M; D7 X) Q- H2 j
  36.         
    % x0 \; r# I) t
  37.         return ret;6 ?: h$ I' }& u7 Q: |$ p+ _
  38. }
    6 W" y7 F" r6 b1 B, k" D4 T* q5 W
  39. 3 N. M  _" {/ `1 H# E, D3 p
  40. //// Erase a word in data memory.
    & n0 \# j5 o4 I. z' E" g# l
  41. //// To correctly run this function, the @ref StmL0xxEpromUnlock() function* C2 t- B% f  V: @
  42. //// must be called before.
    " T2 s% d: n3 B' W' P
  43. //// addr -- specifies the address to be erased.
    - ~# R4 j# Y' S  q5 g
  44. //// ret :
    1 O- D+ A5 P" f
  45. ////   OK       = 0x00U,# a9 g, A& L/ m7 p3 v# J
  46. ////   ERROR    = 0x01U,
    . n& @0 D2 t! Y+ N' v* L1 v
  47. ////   BUSY     = 0x02U,
    4 Y0 F  w0 X! S1 C
  48. ////   TIMEOUT  = 0x03U7 w3 G$ j# {, a  [/ C" y
  49. UNS8 StmL0xxEpromWordErase(UNS32 addr)
    : J% i0 @+ Z% i4 ?
  50. {! W, w8 F% u5 w' ^1 j
  51.         UNS8                ret=0;
    3 {( Q  i) V9 k% |9 C4 [" N  {7 v
  52.         
    0 K2 z4 D$ n& z4 H
  53.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
    9 F& K' a; F7 ~+ f) g9 u
  54.         {: ?( B. {+ x; Z9 Q
  55.                 return ret;# F9 `1 b5 w% h) B  s
  56.         }. p, l! w) U4 c  m
  57.         , f8 D1 P: }. V; s* q, w
  58.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Erase(addr);: M, h9 Q/ W# M# Y" Z8 E
  59.         
    ; n4 n2 X! r/ D& o8 W
  60.         return ret;
    3 `- v/ W$ ^) O7 D
  61. }
    , O  ]" O; \: z" C+ u
  62. $ a- ^! O5 n# n, M4 W: n! l
  63. //// Program data at a specified address# H2 d' Y9 B8 [+ Z' V" T, I
  64. //// type :
    + u8 G: G& x! W% |- ]- H0 k
  65. ////   Byte -- 0x00
    4 U7 \* K8 u! q- m( I4 b
  66. ////   HalfWord -- 0x010 n9 U$ ^+ q! F$ G0 {% ]
  67. ////   Word -- 0x020 T1 x. z! U7 a7 H8 M. C
  68. //// addr -- specifies the address to be erased.
    " S; V& M5 t- m& `2 |1 N! W5 `
  69. //// ret :
    2 R* k6 |0 ~! H6 |9 H* _
  70. ////   OK       = 0x00U,; D1 R! S! a$ ?, x- f0 s8 G
  71. ////   ERROR    = 0x01U,0 M. f% ~- `" c' T3 v
  72. ////   BUSY     = 0x02U,7 h5 Y% w8 l# l% _
  73. ////   TIMEOUT  = 0x03U
    - o( Q. `# m! ?  C2 M
  74. UNS8 StmL0xxEpromSingleWrite(UNS8 type, UNS32 addr, UNS32 data)1 E' ~" N' R! l4 G( B( V9 o0 F0 [
  75. {/ W2 _- B, m; t& K0 S
  76.         UNS8                ret=0;
    2 ?0 ?( Q4 {- Z% {. @9 x5 V+ ?1 W& t
  77.         ! P. v& E6 k% r
  78.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )" ]! y5 s) E  O
  79.         {* n5 i3 v! [0 g
  80.                 return ret;
      h( Y; T9 ]$ H6 @5 C2 j
  81.         }
    3 j3 [6 N: e( L% R' d4 ]
  82.         6 d- l$ \$ t6 K3 h3 _
  83.         StmL0xxEpromUnlock();! ?$ `& o7 W/ b
  84.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Program((UNS32)type, addr, data); //// 库函数
    - W% z/ k* Z7 [4 `
  85.         StmL0xxEpromLock();3 U& I0 b9 R# e# C: E& S. j  t
  86.         % y+ w. j/ R; B) y3 c. Y
  87.         return ret;' e7 `& U1 O* @# E( |
  88. }
    + F8 I/ s+ V! @* ?1 X, ?

  89. 3 P9 Q1 b  v% w/ Z# W) Q
  90. //// read a byte at a specified address
    6 C  x" p' j  R" z' l% a0 l0 g
  91. //// addr -- specifies the address to be erased.6 _" H6 ^" E% W- Y2 g' u
  92. //// ret :
    9 c, u. O, Z% a. c! o
  93. ////   OK       = 0x00U,4 S: F3 |9 m) T' _- X
  94. ////   ERROR    = 0x01U,
    7 z  s+ Z' S) }' W+ c+ i
  95. ////   BUSY     = 0x02U,2 Z+ T- j. A/ g$ Y% T0 ~
  96. ////   TIMEOUT  = 0x03U
    / r% i% A9 |& L+ l( ^; O% N
  97. void StmL0xxEpromSingleByteRead(UNS32 addr, UNS8 *data)
    8 {# l2 g/ {. R- A+ B/ r
  98. {
    * h" M6 [- ]' d, P' q7 Q* F0 p( |
  99.         . P) `6 {5 P/ R, _$ V
  100.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )4 l$ _: I: ?# u3 T1 W! R* e
  101.         {- S: Y$ T% U  H
  102.                 return ;/ o, o9 r+ A) ~. L
  103.         }' I6 J' g; @0 j5 X5 L7 Z; O
  104.         2 R' ?, l; J( x; A7 q2 T5 q; Z2 N
  105.         StmL0xxEpromUnlock();
      D, t! Q2 i6 S# @
  106.         *data = *(volatile uint8_t *)(addr);1 E4 Y: y! ?4 A& g: N! ?" V- m
  107.         StmL0xxEpromLock();
    8 g- D1 ~* z! l3 H$ S- G5 Y
  108. }
复制代码
    测试代码如下:
3 A  L. ]+ y* ]
  1. void EpromTest(void)
    + x4 S: l. z1 e: R
  2. {
    : g  \+ @% J* ?) v  p" c
  3.         UNS8        tmp[8] = {1, 2, 3, 4, 5, 6, 7, 8};
    3 y8 O0 o; v' X* q! i- l1 D+ p
  4.         UNS8        read[8] = {0}, num=0, time=1;' A$ Y0 g, W1 F8 v" Z7 D
  5.         
    " h9 k! l# N" P. k
  6.         while(5>time)
    4 |5 k1 `2 G" L9 d. }9 ^: Y
  7.         {
    1 R- J5 X3 e/ ?( r# _* L4 B
  8.                 for (num=0; num<8; num++)# c; N" `0 C" I% B2 I
  9.                 {/ l& e, N. |& a. j) \7 G) b
  10.                         tmp[num] *= time;
    4 G1 ^! Y: s, I. N; A3 B/ {
  11.                         StmL0xxEpromSingleWrite(EPROM_WR_TYPE_BYTE, EPROM_TEST_ADDR+num, (uint32_t)tmp[num]);. H- \/ W5 k# W% w6 l
  12.                 }. A4 d) Z7 x" v, B3 T/ l
  13.                
    6 c4 i2 Y, V* x3 Q. p$ `
  14.                 for (num=0; num<8; num++)3 X1 L3 g! ~: C+ O9 T* O
  15.                 {2 o' C. |- u; y, N- |
  16.                         StmL0xxEpromSingleByteRead(EPROM_TEST_ADDR+num, &read[num]);  A6 |- q. ?! v
  17.                         if (tmp[num]!=read[num])+ _$ Z8 ^3 F. a3 b
  18.                         {
    9 P' Z1 z, p3 z# d6 q( A
  19.                                 time = 10;
    9 D) o+ ~! G3 Q3 S* ^5 v. Q
  20.                         }8 \5 ?4 S5 u  J% ^! l
  21.                 }, c! o' R9 H/ R% K. l0 K
  22.         - ^1 M6 C# u5 Z, Q! r8 ~5 G
  23. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_HALF_WORD, EPROM_TESTEE_ADDR, *(uint16_t *)(&tmp[0])); //// 进入异常中断1 {" d2 T0 l+ ~5 p9 U
  24. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTEE_ADDR, *(uint32_t *)(&tmp[0]));//// 进入异常中断
    / Q& ~7 f& i3 B9 H
  25.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR, *(uint32_t *)(&tmp[0]));
    / o- P# u+ o  W. C  N# H
  26.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR+4, *(uint32_t *)(&tmp[4]));) ~8 L( |) Q/ v/ {
  27.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+0, (UNS32*)(&read[0]));
    - ~3 N! s% B- I8 ]6 H9 [, M* C
  28.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+4, (UNS32*)(&read[4]));" P3 Y  v% [5 g& X7 R8 U! a6 S0 }
  29.                 6 b' `" R! v# h3 u' R. [
  30.                 time ++;7 O0 o6 z: G) X3 E8 Q4 Y' @
  31.         }
    " F# L. v/ I& f) z9 q9 O- I0 K7 Z
  32. }
复制代码
  

    , i+ h& v& B3 P4 |* ~
    ( C* b, ^6 c* \8 I# p3 A
    4 L7 i& m2 l3 }% u; d/ e+ x# ]  k/ B, c

    7 k9 a3 e% i- J2 v7 R) F1 V
  d% x, O( @0 W" T% [
总结:% i1 ?: J' Z- N* z3 n
     1. 字节操作时,传入任何地址参数都可以,读写操作正常;2 u$ ~; W' L: ?; x. V3 Q
     2. 但是当半字操作时,如果地址不是2对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
/ p+ A# B' q5 c: V     3. 但是当字操作时,如果地址不是4对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
* Z+ }* S$ C( n) J                 : k- A  M5 X/ v$ t
     调试发现调用HAL_FLASHEx_DATAEEPROM_Program函数时进入异常中断。5 ?: A0 D8 X* a* s1 R! q
     原因是EEPROM在内存结构上实际是以字为单位的:
# S" k, s4 B- v  i0 E$ Z
  w9 @" G( E/ j4 d      Eprom.png      虽然可以进行字节、半字的参数,但是必须保证地址的对其方式——半字操作以2对齐,字操作以4对齐,否则会出错。0 [7 {5 R, I9 D, n3 c( U

# L! Z# e& [7 w+ o: U. w0 }0 c+ m     !!!!这个代码的对其方式怎么跟贴代码之前不一样呢,完全左对齐了!!!
+ v; N2 W/ Z) S* Y) L
; c: C7 F! M: f% K. ~3 C  N1 y
赞 收藏 2 评论1 发布时间:2018-1-9 15:24

举报

1个回答
zero99 回答时间:2018-2-1 09:30:02
来晚了,感谢支持,已汇总到1月技术原创
* u# X, ]) j' o. ~2 @https://www.stmcu.org.cn/module/forum/thread-614550-1-1.html

所属标签

相似技术帖

官网相关资源

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