STC单片机EEPROM读写程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/* STC89C54RD+的flash空间从0x4000~0xf3ff 共90个扇区,每扇区512字节*/ // #define BaseAddr 0x1000 /* 51rc */
// #define EndSectoraddr 0x3d00 /* 51rc */
// #define EndAddr 0x3fff /* 51rc 12K eeprom */
#define BaseAddr 0x4000
#define EndSectoraddr 0xf200
#define EndAddr 0xf3ff
#define UseAddr 0x1000
/* ------------- 定义扇区大小------------- */
#define PerSector 512
/* 用户程序需要记忆的数组, 用户实际使用了n-1个数据,数组长度规整到
2 4 8 16 32 64 上*/
uchar Ttotal[16] =
{
0x55, /* 作为判别引导头使用,用户程序请不要修改它*/
/* 用户保存记忆的数据*/
0x01, /* 用途说明....*/
0x02,
0x03,
0x04,
0x05,
0x06,
0x07,
0x08,
0x09,
0x0a,
0x0b,
0x0c,
0x0d,
0x0e,
0x0f,
};
uint timerForDelay, /* 专供延时用的变量*/
i, /* 循环变量*/
EepromPtr; /* eeprom读写指针*/
/* --------------- 命令定义--------------- */
#define RdCommand 0x01 /* 字节读*/
#define PrgCommand 0x02 /* 字节写*/
#define EraseCommand 0x03 /* 扇区擦除*/
/* 定义常量*/
#define Error 1
#define Ok 0
/* 定义Flash对应于20MHz晶振系统的操作等待时间*/
/* 时钟倍频时WaitTime用0x00*/
#define WaitTime 0x01
/* ================ 打开ISP,IAP 功能================= */ void ISP_IAP_enable(void){
EA = 0; /* 关中断*/
ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
ISP_CONTR = ISP_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_TRIG = 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,IAP功能*/
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 */
ISPgoon(); /* 触发执行*/
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 = original_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 | PrgCommand; /* 写命令2 */
ISP_DATA = original_data;
ISPgoon(); /* 触发执行*/
/* 开始读,没有在此重复给地址,地址不会被自动改变*/