找回密码
 注册
关于网站域名变更的通知
查看: 1179|回复: 3
打印 上一主题 下一主题

关于单片机EEPROM数据保存的若干经验总结 附带stc单片机程序

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-1-14 10:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
关于单片机EEPROM数据保存的若干经验总结 附带stc单片机程序0 ?9 }/ z. W6 w- |
2 t; f  D+ {9 L5 K/ M1 h
  @+ o' y: y4 o- H
因为要保存的数据可能是千变万化的,字长可能从8位到32位,其中包括char(8)、short int(16)、 int(32)、float(32),而不同数据类型在不同体系架构上字长各不相同,复杂点的甚至包括结构体Struct,5 d2 S) [3 s  Q7 `( r
因为结构体包含数据大小未知,完成由用户定义,如果保存数据时要考虑到这么多的变化,那能把人都搞晕,因此设计一个以不变应万变的数据保存机制就很好了,好比是复杂平台中的数据串行化保存。
) t$ M1 W4 m; ^' c6 C, ~在单片机里面不可能实现这么高级的技术,但是也可以通过一个小小的技巧实现类似功能,方式就是通过联合体来保存,比如下面所示
4 ?' e, E* V" t/ `5 t5 J
2 C' t7 t5 L/ Z# t        struct         e2prom_data
' N' ~: ]0 o; t) B2 D/ \        {, D& c/ L6 T4 l; \2 v& D) L! V& w
        char TEM_compensate;
( ]4 X7 A0 X; z5 ~, q        unsigned int sterilization_temperature[10];//0.1/ Q( I" R9 g& `4 ?& Y' T9 _0 u
        unsigned char sterilization_time_min[10];2 s9 }+ M* _* O4 B
        unsigned char exhaust_times;4 k/ O1 \' B1 c* ]- G# s
        unsigned char prebalance_time_min;# x8 }( m, v, f+ g% M! r
        };0 h$ m& @9 h# e, I: P- U4 u1 _

5 j3 H# J' K/ p# |6 Ounion sector/ |" h/ T2 S3 c! p
{
3 I3 E% C# @. C; K/ q# N0 F        struct e2prom_data sterlization_data;
4 t) H! w+ D( q( i$ [$ q        unsigned char storage[ sizeof(struct e2prom_data) ];. q) k# }9 T. W# w5 [" P
} e2prom;
( t$ c0 k3 o9 D4 }* `- a0 Z0 H5 N# N1 _
$ l+ a- ?; A: `( [2 y' B
   联合sector代表实际的扇区,大小不能超过扇区大小,而上面的结构体就用来保存真正要用到的变量,然后通过联合体sector里面的unsigned char storage,统一转换成1个字节来保存实际数据,极其方便。6 C  ^0 }$ ~; M+ E, k! s2 j6 |
而要读取数据的时候可以通过下面的  void read_sector(char secn)函数来统一操作,把数据统一读取到内存中,确认保存后再通过void write_sector(char secn)统一保存。  J, ?; d! ^% X' \( M
效率很高,用内存来缓存数据,可以减小EEPROM擦写次数,提高寿命。
2 T, v  k6 p+ `8 {: e4 e
! T# M" I5 _' t* d( s. B4 v8 z
0 C- q6 M' u( I' {% u2 f& J( g) ~
void read_sector(char secn)
; c9 b3 B- l; q7 {0 I  l{
, E/ O, r. ?3 b  E! C          int i;
, L! R' B% h  i; g        int E2prom_sector_start_addr=(secn-1)*512;6 |1 l! E4 O: C
        for(i=0;i< sizeof(struct        e2prom_data);i++)- n  u3 i7 y8 M$ K7 U5 Q6 k
        {: k/ b+ }  X- L2 [
        e2prom.storage=Byte_Read( i+ E2prom_sector_start_addr);
% z. H' u/ f8 m$ h        }
( ]5 N* b& m7 B" F: o- X          IAP_Disable();
  ]- Y2 `1 V8 r  x}
, o7 P9 ?2 p; k
: {8 a7 A' A8 e
, k$ Q" ?7 {! W
void write_sector(char secn)1 j; F8 G* b) v$ t# e3 r
{$ x. M- C& W4 I6 S; B' n- i
        3 F/ Z  b) j1 T0 ?% O0 F
        int i;  _' t7 j, S1 L& Y# }
        int E2prom_sector_start_addr=(secn-1)*512;, }' I2 D6 `/ q* J( u$ |
% z  O; o! S! ]% Z
( q+ B9 M: j# \2 v5 F
        Sector_Erase(E2prom_sector_start_addr);2 W0 u3 j* ~, s6 M& D
        for(i=0;i< sizeof( struct         e2prom_data );i++)
/ ~6 x! p$ }5 j! V- ?        {
" V+ [' H: b8 o0 \9 W" \        Byte_Program(i + E2prom_sector_start_addr, e2prom.storage);0 Y) q+ I6 m( H
        }* A9 b3 |' H1 p
           IAP_Disable();: A  ?% Q! l( a! _% s& d' a& Y2 f
}
2 h+ R, z6 n8 M7 r! @& J8 E0 k3 \4 G3 m" ?
+ B/ N" {% s2 |8 ^3 H
唯一不足的地方是实际数据地址是固定的,如果常年累月读写次数多了的话,EEPROM还是有可能出问题的,下一步改进的地方就是通过实际一个虚拟存储空间来延长EEPROM寿命,
5 A- h) A9 |: \# R( P实际方案是比如一个扇区是1K字节,那么把1k分成256个单元,每个单元4个字节,扇区首单元保存扇区状态,剩余255个单元作为实际存储单元,而每个存储单元又分成2+2布局,前两字节保存实际数据,后两字节保存虚拟地址,1.写入时写入数据紧跟后面写入虚地址VirtAddVarTab(0<=i<NumbOfVar)2 Q: C; v; d2 g5 j; V
2.每个Page第一个地址写入该页状态(Earse,Reveice,Vild)
3 t3 e1 z  }  `( x) Q$ v" x- ^) B7 U
+ f; U7 y6 H' b7 k相同地址再次写入时不会把上次写的擦掉,而是在模拟EEPROM区尾部未写过的地方再次写入数据、虚地址,
0 g6 E7 \( l9 J9 Q3、 读的时候是从尾部开始匹配地址,也就是读取最后一次写的内容。
" f* w+ @: d6 C, X. m4、模拟EEPROM区分为2页,如果一页满了把这一页内地址不重复的数据复制到另一页后擦除,2页交替使用。8 x% t" D2 [4 [) I9 P2 w- [  m' l+ U

% {, d: C5 l& I5 t一个代码:
8 p+ X% b, r# [9 s7 {! H" j8 x
游客,如果您要查看本帖隐藏内容请回复

& i, ?$ l; y7 F! C* j! [
2 q+ f6 A0 V& S. l! F: y+ W. T7 Q* r

, {% O) t  T9 t1 u+ |

该用户从未签到

4#
发表于 2022-5-14 16:09 | 只看该作者
很想学习学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-7-18 15:34 , Processed in 0.140625 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表