STC单片机EEPROM读写程序_第1页
STC单片机EEPROM读写程序_第2页
STC单片机EEPROM读写程序_第3页
STC单片机EEPROM读写程序_第4页
STC单片机EEPROM读写程序_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、/* STC89C54RD+的flash空间从0x40000xf3ff 共90个扇区,每扇区512字节*/#define BaseAddr0x1000/*51rc*/#define EndSectoraddr0x3d00/*51rc*/#define EndAddr0x3fff/*51rc 12K eeprom*/#define BaseAddr0x4000#define EndSectoraddr0xf200#define EndAddr 0xf3ff#define UseAddr 0x1000/* - 定义扇区大小 - */#define PerSector512/* 用户程序需要记忆的数

2、组, 用户实际使用了n-1个数据,数组长度规整到2 4 8 16 32 64 上 */uchar Ttotal16=0x55,/* 作为判别引导头使用,用户程序请不要修改它 */* 用户保存记忆的数据 */0x01,/* 用途说明.*/0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,;uint timerForDelay,/* 专供延时用的变量 */i,/* 循环变量*/EepromPtr;/* eeprom读写指针*/* - 命令定义 - */#define RdCommand0x01/* 字节读 *

3、/#define PrgCommand0x02/* 字节写 */#define EraseCommand0x03/* 扇区擦除 */* 定义常量 */#define Error 1#define Ok 0/* 定义Flash对应于20MHz晶振系统的操作等待时间 */* 时钟倍频时WaitTime用 0x00*/#define WaitTime0x01/* = 打开 ISP,IAP 功能 = */void ISP_IAP_enable(void)EA=0;/* 关中断 */ISP_CONTR =ISP_CONTR & 0x18; /* 0001,1000*/ISP_CONTR =ISP

4、_CONTR | WaitTime;/* 写入硬件延时*/ISP_CONTR =ISP_CONTR | 0x80; /* ISPEN=1*/* = 关闭 ISP,IAP 功能 = */void ISP_IAP_disable(void)ISP_CONTR=ISP_CONTR & 0x7f;/* ISPEN = 0 */ISP_TRIG=0x00;EA= 1;/* 开中断 */* = 公用的触发代码 = */void ISPgoon(void)ISP_IAP_enable();/* 打开 ISP,IAP 功能*/ISP_TRIG=0x46;/* 触发ISP_IAP命令字节1*/ISP_T

5、RIG=0xb9;/* 触发ISP_IAP命令字节2*/_nop_();/* = 字节读 = */uchar byte_read(uint byte_addr)ISP_ADDRH = (uchar)(byte_addr >> 8);/* 地址赋值*/ISP_ADDRL = (uchar)(byte_addr & 0x00ff);ISP_CMD = ISP_CMD& 0xf8;/* 清除低3位 */ISP_CMD = ISP_CMD| RdCommand;/* 写入读命令*/ISPgoon();/* 触发执行*/ISP_IAP_disable();/* 关闭ISP,I

6、AP功能*/return (ISP_DATA);/* 返回读到的数据*/* = 扇区擦除 = */void SectorErase(uint sector_addr)uint iSectorAddr;iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */ISP_ADDRH = (uchar)(iSectorAddr >> 8);ISP_ADDRL = 0x00;ISP_CMD= ISP_CMD & 0xf8;/* 清空低3位 */ISP_CMD= ISP_CMD | EraseCommand;/* 擦除命令3 */ISPg

7、oon();/* 触发执行*/ISP_IAP_disable();/* 关闭ISP,IAP功能*/* = 字节写 = */void byte_write(uint byte_addr, uchar original_data)ISP_ADDRH =(uchar)(byte_addr >> 8); /* 取地址 */ISP_ADDRL =(uchar)(byte_addr & 0x00ff);ISP_CMD = ISP_CMD & 0xf8;/* 清低3位*/ISP_CMD = ISP_CMD | PrgCommand;/* 写命令2*/ISP_DATA = orig

8、inal_data;/* 写入数据准备*/ISPgoon();/* 触发执行*/ISP_IAP_disable();/* 关闭IAP功能*/* = 字节写并校验 = */uchar byte_write_verify(uint byte_addr, uchar original_data)ISP_ADDRH = (uchar)(byte_addr >> 8); /* 取地址 */ISP_ADDRL = (uchar)(byte_addr & 0xff);ISP_CMD = ISP_CMD & 0xf8;/* 清低3位*/ISP_CMD = ISP_CMD | Prg

9、Command;/* 写命令2*/ISP_DATA = original_data;ISPgoon();/* 触发执行*/* 开始读,没有在此重复给地址,地址不会被自动改变 */ISP_DATA = 0x00;/* 清数据传递寄存器*/ISP_CMD = ISP_CMD & 0xf8;/* 清低3位*/ISP_CMD = ISP_CMD | RdCommand;/* 读命令1*/ISP_TRIG=0x46;/* 触发ISP_IAP命令字节1*/ISP_TRIG=0xb9;/* 触发ISP_IAP命令字节2 */_nop_();/* 延时*/ISP_IAP_disable();/* 关闭

10、IAP功能*/if(ISP_DATA= original_data)/* 读写数据校验*/returnOk;/* 返回校验结果*/elsereturnError;/* = 数组写入 = */uchar ArrayWrite(uint begin_addr, uint len, uchar *array)uinti;uintin_addr;/* 判是否是有效范围,此函数不允许跨扇区操作 */if(len > PerSector)return Error;in_addr = begin_addr & 0x01ff; /* 扇区内偏移量 */if(in_addr + len) >

11、 PerSector)return Error;in_addr = begin_addr;/* 逐个写入并校对 */ISP_IAP_enable();/* 打开IAP功能*/for(i = 0; i< len; i+)/* 写一个字节 */ISP_ADDRH = (uchar)(in_addr >> 8);ISP_ADDRL = (uchar)(in_addr & 0x00ff);ISP_DATA = arrayi;/* 取数据*/ISP_CMD = ISP_CMD & 0xf8;/* 清低3位 */ISP_CMD = ISP_CMD | PrgCommand

12、;/* 写命令2 */ISP_TRIG = 0x46;/* 触发ISP_IAP命令字节1 */ISP_TRIG = 0xb9;/* 触发ISP_IAP命令字节2 */_nop_();/* 读回来 */ISP_DATA=0x00;ISP_CMD = ISP_CMD & 0xf8;/* 清低3位 */ISP_CMD = ISP_CMD | RdCommand;/* 读命令1 */ISP_TRIG = 0x46;/* 触发ISP_IAP命令字节1 */ISP_TRIG = 0xb9;/* 触发ISP_IAP命令字节2 */_nop_();/* 比较对错 */if(ISP_DATA != ar

13、rayi)ISP_IAP_disable();return Error;in_addr+;/* 指向下一个字节*/ISP_IAP_disable();returnOk;/* = 扇区读出 = */* 程序对地址没有作有效性判断,请调用方事先保证他在规定范围内*/void ArrayRead(uint begin_addr, uchar len)/uchar xdatadata_buffer;/* 整个扇区读取缓存区*/uint iSectorAddr;uint i;iSectorAddr = begin_addr;/ & 0xfe00; /* 取扇区地址 */ISP_IAP_enabl

14、e();for(i = 0; i < len; i+)ISP_ADDRH =(uchar)(iSectorAddr >> 8);ISP_ADDRL =(uchar)(iSectorAddr & 0x00ff);ISP_CMD =ISP_CMD& 0xf8;/* 清低3位 */ISP_CMD =ISP_CMD| RdCommand;/* 读命令1 */ISP_DATA = 0;ISP_TRIG = 0x46;/* 触发ISP_IAP命令字节1 */ISP_TRIG = 0xb9;/* 触发ISP_IAP命令字节2 */_nop_();Ttotali=ISP_DA

15、TA;iSectorAddr+;ISP_IAP_disable();/* 关闭IAP功能*/* = 从eeprom中读取数据 = */void DataRestore()EepromPtr = BaseAddr;/* 指向eeprom的起始点*/while(EepromPtr < EndAddr)/* 在eeprom的可用区域内*/if(byte_read(EepromPtr) = 0x55)/* 找到了上一次有效纪录*/break;/*寻找完成*/EepromPtr += 0x10;/* 指向下一个小区*/if(EepromPtr >= EndAddr)/* 如果照遍都没有,是新

16、片*/EepromPtr = BaseAddr;/* 指向eeprom的起始点*/for(i=0;i<90;i+)SectorErase(EepromPtr+0x200*i);/* 全部扇区擦除*/while(ArrayWrite(EepromPtr, 0x10, Ttotal)/* 写默认值*/* 写入失败才运行的部分*/byte_write(EepromPtr, 0);/* 该单元已经失效*/if(EepromPtr < EndAddr)EepromPtr += 0x10;/* 换一块新的小区*/elseP1=0;/* 指示芯片内eeprom全坏*/EA= 0;/* 不再做任何事*/while(1);/* 死机*/ArrayRead(EepromPtr, 16);/* = 将需要记忆的数据保存到eeprom = */void DataSave()uintwrPtr;/* 临时指针*/NextArea:byte_write_verify(EepromPtr, 0);/* 将原来的标记清除*/wrPtr = EepromPtr & 0xfe00;/* 上一个扇区的起始地址*/EepromPtr += 0x10;/* 目标存入地址*/* - 判断是否启用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论