总结操作步骤
- 先写ISP_CONTR寄存器,允许读写功能
- 写ISP_CMD寄存器,确定是无/读/写/擦除操作
- 写ISP_ADDRH与ISP_ADLDRL确定要操作的地址高位与低位
- 如果是写数据,现在需向ISP_DATA寄存器写数据
- 先对ISP_TRIG写0x46,再写入0xb9 ISP命令才生效
- 如果是读数据,现在需从ISP_DATA寄存器读出
- 写ISP_CONTR寄存器,关闭读写功能
示例代码
#include <STC89C5xRC.H>
#include "intrins.h" //_nop_();
//操作EEPROM命令
#define CMD_IDLE 0
#define CMD_READ 1
#define CMD_PROGRAM 2
#define CMD_ERASE 3
#define EEPROM_ADDRESS 0x08000 //起始地址
void EEPROM_Idle(void);
u8 EEPROM_ReadByte(u16 addr);
void EEPROM_ProgramByte(u16 addr, u8 dat);
void EraseSector(u16 addr);
void Delay500ms() //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
u16 i;
P2 = 0xfe; //1111,1110 系统初始化完毕
//擦除一个扇区
Delay500ms(); //延时500ms
EraseSector(EEPROM_ADDRESS);
for (i=0; i<512; i++) //确认擦除成功,即每个单元等于0XFF
{
if(EEPROM_ReadByte(EEPROM_ADDRESS+i) != 0xff)
goto Error;
}
P2 = 0xfc; //擦除成功
//写入一byte数据
Delay500ms(); //延时500ms
EEPROM_ProgramByte(EEPROM_ADDRESS+87,0xfe);
P2 = 0xf8; //写入成功
//读出一byte数据
Delay500ms(); //延时500ms
if (EEPROM_ReadByte(EEPROM_ADDRESS+87) !=0xfe)
goto Error;
P2 = 0xf0; //读出内容正确!
while (1);
Error:
P2=0x00;
while (1);
}
//关闭EEPROM功能
void EEPROM_Idle()
{
ISP_CONTR = 0; //关闭EEPROM功能
ISP_CMD = 0;
ISP_TRIG = 0;
ISP_ADDRH = 0x80; //恢复到起始地址
ISP_ADDRL = 0;
}
//读出一个beye
u8 EEPROM_ReadByte(u16 addr)
{
u8 dat;
ISP_CONTR = 0x81; //打开EEPROM功能
ISP_CMD = CMD_READ; //读命令
ISP_ADDRL = addr; //读地址
ISP_ADDRH = addr >> 8;
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
dat = ISP_DATA; //读出数据
EEPROM_Idle(); //关闭EEPROM功能
return dat;
}
//写入一个byte
void EEPROM_ProgramByte(u16 addr, u8 dat)
{
ISP_CONTR = 0x81;
ISP_CMD = CMD_PROGRAM; //写命令
ISP_ADDRL = addr;
ISP_ADDRH = addr >> 8;
ISP_DATA = dat;//写入数据
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
EEPROM_Idle();
}
//擦除一个扇区(512byte)
void EraseSector(u16 addr)
{
ISP_CONTR = 0x81;
ISP_CMD = CMD_ERASE; //擦除命令
ISP_ADDRL = addr;
ISP_ADDRH = addr >> 8;
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
EEPROM_Idle();
}