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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
关于单片机EEPROM数据保存的若干经验总结 附带stc单片机程序
0 o* I* I- z. H3 T" U" W- [3 s* O' h1 m( h7 |

; `1 X5 }- `& |/ n7 @2 X! b因为要保存的数据可能是千变万化的,字长可能从8位到32位,其中包括char(8)、short int(16)、 int(32)、float(32),而不同数据类型在不同体系架构上字长各不相同,复杂点的甚至包括结构体Struct,' V7 h/ S( R+ k5 ^
因为结构体包含数据大小未知,完成由用户定义,如果保存数据时要考虑到这么多的变化,那能把人都搞晕,因此设计一个以不变应万变的数据保存机制就很好了,好比是复杂平台中的数据串行化保存。
' K, Z$ c! V/ A在单片机里面不可能实现这么高级的技术,但是也可以通过一个小小的技巧实现类似功能,方式就是通过联合体来保存,比如下面所示
, Q$ j  o1 W" o  Q  N4 T, Q0 ~. z  A6 k9 }, W  o
        struct         e2prom_data
0 O2 a* h5 K5 u! y, `        {: l0 ]( m0 I% A  E
        char TEM_compensate;6 F( c  T, i8 y& h: s/ I
        unsigned int sterilization_temperature[10];//0.1
9 c' Y( s! F8 ?7 m        unsigned char sterilization_time_min[10];
; f& `  o: ?) t0 l        unsigned char exhaust_times;
5 R6 t9 R! ^% a7 \  G        unsigned char prebalance_time_min;
: h2 F) j' J$ k7 W        };$ l: p. B& ~4 c; c& {0 ^# G

" M) T( L) L& b) r% Xunion sector/ L4 Q& {8 p/ a$ [( K  x
{5 H# F! z( F* `% i" ^+ E/ _
        struct e2prom_data sterlization_data;2 n" ^, Y  I. i. g
        unsigned char storage[ sizeof(struct e2prom_data) ];  }. c' s/ s/ @2 J1 o: \
} e2prom;
! |  R7 E) D( k* w, g; G9 _: I9 m' U2 j1 c2 O2 b5 p
3 h0 T) S7 g' N% n. ~1 e+ u) Z' _
   联合sector代表实际的扇区,大小不能超过扇区大小,而上面的结构体就用来保存真正要用到的变量,然后通过联合体sector里面的unsigned char storage,统一转换成1个字节来保存实际数据,极其方便。
, Q9 B' R( G% o) u) _而要读取数据的时候可以通过下面的  void read_sector(char secn)函数来统一操作,把数据统一读取到内存中,确认保存后再通过void write_sector(char secn)统一保存。/ @" F% U4 y( [& C  J
效率很高,用内存来缓存数据,可以减小EEPROM擦写次数,提高寿命。
+ }" [; v; }+ N; [
  g1 [# A8 G/ C- ^5 R# {

8 c8 b! P2 L) A( G void read_sector(char secn)  E8 n. a1 t! X+ [/ ^
{7 ?3 v6 g4 t, r1 K
          int i;& \$ m  d" S; e7 C. X: C5 d
        int E2prom_sector_start_addr=(secn-1)*512;
- s6 J% l& r$ K! M        for(i=0;i< sizeof(struct        e2prom_data);i++)9 o- F0 M( G2 _' h' K$ _- \
        {8 }/ s* d; r! l/ S, R% ?/ \$ l
        e2prom.storage=Byte_Read( i+ E2prom_sector_start_addr);
6 K# G; X6 L. k5 y1 U# U        }
4 p" H: q! w$ J          IAP_Disable();7 d: G% B9 }0 d/ C
}3 ?" z# j& i7 V$ f* d
( t9 D3 v# x; R4 z7 r% t7 x

- o7 ]/ U& W& r! Gvoid write_sector(char secn)
! G8 }' A2 X% h/ l{
4 E+ `/ m" s9 ?/ c        
0 a: F* d- b3 d" g, K5 L1 H4 A/ g        int i;
2 W6 [0 l5 t& J* U        int E2prom_sector_start_addr=(secn-1)*512;
# I( _8 u  O, E' k
" M* q9 _% d, X  W& g  W, L8 V
' X7 d1 i7 S* J2 |# S! F
        Sector_Erase(E2prom_sector_start_addr);
, E* t0 \. K8 g        for(i=0;i< sizeof( struct         e2prom_data );i++)
7 t) _8 C5 B! B" ~. H7 V6 X        {
2 g" J6 Z$ z6 _+ z$ u6 M+ M( B        Byte_Program(i + E2prom_sector_start_addr, e2prom.storage);. a4 X. D5 c* |
        }
* N7 X: k3 g# {: o! A7 q           IAP_Disable();& s/ @7 n( U* M5 F" i2 `
}2 ?; T# W  z% o

1 c3 u' m$ R" n+ j" D

- O1 `8 Z" G. K1 k- W* K/ A/ @唯一不足的地方是实际数据地址是固定的,如果常年累月读写次数多了的话,EEPROM还是有可能出问题的,下一步改进的地方就是通过实际一个虚拟存储空间来延长EEPROM寿命,
+ t) ]- P5 D$ y* V实际方案是比如一个扇区是1K字节,那么把1k分成256个单元,每个单元4个字节,扇区首单元保存扇区状态,剩余255个单元作为实际存储单元,而每个存储单元又分成2+2布局,前两字节保存实际数据,后两字节保存虚拟地址,1.写入时写入数据紧跟后面写入虚地址VirtAddVarTab(0<=i<NumbOfVar): t3 g; I( `/ x$ ]0 Q  v
2.每个Page第一个地址写入该页状态(Earse,Reveice,Vild)
* Y& M3 w' T% `, E, C0 h% O% M+ Q: J3 c
相同地址再次写入时不会把上次写的擦掉,而是在模拟EEPROM区尾部未写过的地方再次写入数据、虚地址, 5 L! g$ t7 G% t- F0 F
3、 读的时候是从尾部开始匹配地址,也就是读取最后一次写的内容。
  U2 F; _! p, y- D$ X/ r4、模拟EEPROM区分为2页,如果一页满了把这一页内地址不重复的数据复制到另一页后擦除,2页交替使用。
6 Y' w; g, S% v6 j6 e3 `' _, W& d- v; {, l6 H
一个代码:
5 p1 C: k6 P& u
游客,如果您要查看本帖隐藏内容请回复
) a7 j" f3 q+ \

: b2 E# }# e5 x: q) R6 G9 x, j1 L" h
" A1 u1 a* v' E) ~

3 u8 D! Z' Q; l! @( N9 B/ ]

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-12 08:19 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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