📄 eepdemo.lst
字号:
C51 COMPILER V8.02 EEPDEMO 02/28/2007 15:40:35 PAGE 1
C51 COMPILER V8.02, COMPILATION OF MODULE EEPDEMO
OBJECT MODULE PLACED IN E:\TEMP\eepDemo.obj
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE eepDemo.c BROWSE DEBUG OBJECTEXTEND OBJECT(E:\TEMP\eepDemo.obj)
line level source
1 /*========================================================================
2 IAP操作使用片内flash作为eeprom使用的驱动程序。参考来源:www.mcu-memory.com
3
4 本演示代码通过对用户数据的读写操作,具体实现数据存储的组织方法,最大限度的
5 利用eeprom的空间。这只是对eeprom进行分配轮换使用的一种方法。
6 实现分配的思路:用户数组(需要记忆的部分)应该在4,8,16,32,64等字节以内,将第
7 一字节留作索引头:如果读到该字节为0x55(也可以定义为其他数),则认为已经找到
8 了有效的最后纪录,将本小区域数据读出。如果不是则继续跳到下一个小区域继续上
9 述操作,直到找到上一次的纪录为止,如果超出了eeprom的有效范围还没有找到,则
10 认为这是一块新的芯片,将默认的数据写入。
11 保存的时候,首先将刚才读到的那个数组的对应eeprom中的第一字节清零,以便下次
12 跳过,然后再推后一个小区域(记录长度),将数据写入。如果出现写入失败,接着到
13 再下一个区域,直到写入正确为止。
14 这里有一个问题就是,写到下一个小区域的时候会遇到跨扇区,只要判断出跨区,就
15 将上一个扇区擦除,以备下一轮循环再使用。
16 程序利用stc提供的下载板上的LED显示当前读或者写的地址,你可以看到led的"递减"
17 过程,演示读写256次,从第一次的全亮,到演示完毕也全亮,刚好256次。如果中途
18 断电,即会出现不同的结果,但再进行完演示的话,会发现结束时的led状态与开始
19 时的一样,否则就说明你的芯片内部eeprom有损坏。
20
21 演示代码仅针对stc89c54rd+/51rc进行了调试,但可以给其他芯片编程时作为参考。
22 晓奇工作室 http://www.xiao-qi.com/
23 ---- xiaoqi 2005.12
24 ======================================================================= */
25 #include "src51rd.h"
26 #include <intrins.h>
27
28 #define uchar unsigned char
29 #define uint unsigned int
30
31 /* STC89C52RC的flash空间从0x2000~0x2fff 共8个扇区,每扇区512字节*/
32
33 #define BaseAddr 0x2000
34 #define EndSectoraddr 0x2e00
35 #define EndAddr 0x2fff
36
37 /* ------------- 定义扇区大小 ------------- */
38 #define PerSector 512
39
40 /* 用户程序需要记忆的数组, 用户实际使用了n-1个数据,数组长度规整到
41 2 4 8 16 32 64 上 */
42 uchar Ttotal[16] =
43 {
44 0x55, /* 作为判别引导头使用,用户程序请不要修改它 */
45 /* 用户保存记忆的数据 */
46 0x01, /* 用途说明....*/
47 0x02,
48 0x03,
49 0x04,
50 0x05,
51 0x06,
52 0x07,
53 0x08,
54 0x09,
55 0x0a,
C51 COMPILER V8.02 EEPDEMO 02/28/2007 15:40:35 PAGE 2
56 0x0b,
57 0x0c,
58 0x0d,
59 0x0e,
60 0x0f,
61 };
62
63 uint timerForDelay, /* 专供延时用的变量 */
64 i, /* 循环变量 */
65 EepromPtr; /* eeprom读写指针 */
66
67 /* ======================= IAP外部函数列表 =======================*/
68 /* 扇区擦除 */
69 extern void SectorErase(uint sector_addr);
70 /* byte 读 */
71 extern uchar byte_read(uint byte_addr);
72 /* byte 写 */
73 extern void byte_write(uint byte_addr, uchar original_data);
74 /* byte写并校验 */
75 extern uchar byte_write_verify(uint byte_addr, uchar original_data);
76 /* byte数组写并校验 */
77 extern uchar ArrayWrite(uint begin_addr, uint len, uchar *array);
78 /* byte数组读, 存在Ttotal[] */
79 extern void ArrayRead(uint begin_addr, uchar len);
80
81 /* ============================ 延时 ========================= */
82 void delay(uint counter)
83 {
84 1 timerForDelay = counter;
85 1 while(timerForDelay);
86 1 }
87
88 /* ==============================================================
89 初始化开启定时器2,定时周期设定为10mS(下载板上 18.432M 晶振)
90 ============================================================== */
91 void initCT2()
92 {
93 1 /* 时钟倍频时用 0x8800*/
94 1 RCAP2H = 0xc4;
95 1 RCAP2L = 0x00;
96 1 TH2 = 0xc4; // 定时器初值
97 1 TL2 = 0x00;
98 1 ET2 = 1; // 允许T2中断
99 1 T2CON = 4; // 自动重装的定时器
100 1 TR2 = 1; // 启动
101 1 EA = 1;
102 1 }
103
104 /* ==============================================================
105 定时器CT2中断服务程序
106 ============================================================== */
107 void timer2Int(void) interrupt 5
108 {
109 1 TF2 = 0; /* 溢出标志必须由软件清零*/
110 1 EXF2 = 0; /* 捕获标志必须由软件清零*/
111 1 if(timerForDelay)timerForDelay--; /* 定时变量处理 */
112 1 }
113
114 /* ==============================================================
115 从eeprom中读取数据
116 ============================================================== */
117 void DataRestore()
C51 COMPILER V8.02 EEPDEMO 02/28/2007 15:40:35 PAGE 3
118 {
119 1 EepromPtr = BaseAddr; /* 指向eeprom的起始点 */
120 1 while(EepromPtr < EndAddr) /* 在eeprom的可用区域内 */
121 1 {
122 2 if(byte_read(EepromPtr) == 0x55)/* 找到了上一次有效纪录 */
123 2 {
124 3 break; /* 寻找完成 */
125 3 }
126 2 EepromPtr += 0x10; /* 指向下一个小区 */
127 2 }
128 1 if(EepromPtr >= EndAddr) /* 如果照遍都没有,是新片*/
129 1 {
130 2 EepromPtr = BaseAddr; /* 指向eeprom的起始点 */
131 2 for(i=0;i<90;i++)
132 2 {
133 3 SectorErase(EepromPtr+0x200*i); /* 全部扇区擦除 */
134 3 }
135 2 while(ArrayWrite(EepromPtr, 0x10, Ttotal)) /* 写默认值 */
136 2 { /* 写入失败才运行的部分 */
137 3 byte_write(EepromPtr, 0); /* 该单元已经失效 */
138 3 if(EepromPtr < EndAddr)
139 3 {
140 4 EepromPtr += 0x10; /* 换一块新的小区 */
141 4 }
142 3 else
143 3 {
144 4 P1=0; /* 指示芯片内eeprom全坏 */
145 4 EA= 0; /* 不再做任何事 */
146 4 while(1); /* 死机 */
147 4 }
148 3 }
149 2 }
150 1 ArrayRead(EepromPtr, 16);
151 1 }
152
153 /* ==============================================================
154 将需要记忆的数据保存到eeprom
155 ============================================================== */
156 void DataSave()
157 {
158 1 uint wrPtr; /* 临时指针 */
159 1
160 1 NextArea:
161 1 byte_write_verify(EepromPtr, 0); /* 将原来的标记清除 */
162 1 wrPtr = EepromPtr & 0xfe00; /* 上一个扇区的起始地址 */
163 1 EepromPtr += 0x10; /* 目标存入地址 */
164 1
165 1 /* ------------------ 判断是否启用新的扇区 ---------------- */
166 1 if((EepromPtr & 0x1ff)==0)
167 1 {
168 2 SectorErase(wrPtr); /* 将上一个扇区擦除,备用 */
169 2 if(EepromPtr>=EndAddr) /* 已经用完了最后一个区域 */
170 2 {
171 3 EepromPtr = BaseAddr; /* 从头开始 */
172 3 }
173 2 }
174 1 /* -------------------- 数据存入前的准备 ------------------ */
175 1 /* 。。。。。。。。。。。。。。转移、处理 */
176 1 Ttotal[0] = 0x55; /* 重申启用标记 */
177 1 if(ArrayWrite(EepromPtr, 0x10, Ttotal))
178 1 { /* 数据写入,如果有错换一块 */
179 2 goto NextArea;
C51 COMPILER V8.02 EEPDEMO 02/28/2007 15:40:35 PAGE 4
180 2 }
181 1 }
182
183 /* ================================================================
184 储存于读取的反复测试,每个小区域16字节,每个扇区512字节,即每个
185 扇区分成32个小块,每次写入顺序往后移动一个小区域,进行256次读写操作
186 实际上跨越了8个扇区。
187 按照51rc 12K eeprom计算,可以反复纪录7680万次
188 按照52rc 8K eeprom计算,可以反复纪录3840万次
189 按照54rd+45K eeprom计算,可以反复纪录2.88亿次
190 足够系统对记忆体的要求。
191 ====================================================== ======= */
192 void main()
193 {
194 1 //byte_write(0x2e00,0x55);
195 1 //SectorErase(0x2000);
196 1 P1 = byte_read(0x2e00);
197 1
198 1 while(1);
199 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 311 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 22 ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -