当前位置:文档之家› EEPROM读写程序

EEPROM读写程序

AUXR1 EQU 0A2H;双指针
ISP_DATA EQU 0E2H ;写入读出数据寄存器
ISP_ADDRH EQU 0E3H ;地址寄存器高8位
ISP_ADDRL EQU 0E4H ;地址寄存器低8位
ISP_CMD EQU 0E5H ;命令模式寄存器
ISP_TRIG EQU 0E6H ;命令触发寄存器
ISP_CONTR EQU 0E7H ;ISP/IAP控制寄存器

ORG 0000H
AJMP MAIN
ORG 0030H

MAIN:
MOV AUXR1,#0;指针0
INC AUXR1 ;指针1
MOV DPTR,#2000H
ACALL ERASE;擦除
MOV A,#0FEH
ACALL EEPROMW;写
ACALL EEPROMR;读
INC AUXR1 ;指针0
AJMP MAIN
;----------------------
ERASE:;擦除
MOV ISP_CONTR,#1;设置等待时间,40M以下0 20M以下1,10MHz以下2 ,5M 以下3
ORL ISP_CONTR,#80h;允许ISP/IAP操作
MOV ISP_CMD,#03H ;扇区擦除
MOV ISP_ADDRH,DPH ;送高地址
MOV ISP_ADDRL,DPL ;送低地址

ACALL ISPXX ;触发
RET
;----------------------
EEPROMW:;写
MOV ISP_CONTR,#1;设置等等待时间
ORL ISP_CONTR,#80h;允许ISP/IAP操作
MOV ISP_CMD,#02H ;送写命令
MOV ISP_ADDRH,DPH ;送高地址
MOV ISP_ADDRL,DPL ;送低地址
MOV ISP_DATA,A ;A是要写入的数据

ACALL ISPXX ;触发
RET
;----------------------
EEPROMR:;读
MOV ISP_CONTR,#1;设置等等待时间
ORL ISP_CONTR,#80h;允许ISP/IAP操作
MOV ISP_CMD,#01H ;送读命令
MOV ISP_ADDRH,DPH ;送高地址
MOV ISP_ADDRL,DPL ;送低地址

ACALL ISPXX ;触发

MOV A,ISP_DATA ;读出的数据放到A

RET
;----------------------
ISPXX:;触发
CLR EA ;关中断在触发之前
MOV ISP_TRIG,#46H ;触发
MOV ISP_TRIG,#0B9H;触发启动
NOP
NOP
MOV ISP_CONTR,#0 ;禁止ISP/IAP操作
MOV ISP_CMD,#0 ;去除ISP/IAP命令
MOV ISP_TRIG,#0 ;防止ISP/IAP命令误触发

MOV ISP_ADDRH,#0FFH;送地址高字节单元为FF,防止误操作
MOV ISP_ADDRL,#0FFH;送地址低字节单元为FF,防止误操作
SETB EA ;开中断
RET


END



/****************************************************************************/
/* IAP驱动 */
/****************************************************************************/


/************************************************************************************************************************/
/*ISP/IAP相关寄存器列表*/
/*名称地址功能描述D7D6D5D4D3D2D1D0复位值*/
/*ISP_DATAE2hFlash数据寄存器1111 1111*/
/*ISP_ADDRHE3hFlash高字节地址寄存器0000 0000*/
/*ISP_ADDRLE4hFlash低字节地址寄存器0000 0000*/
/*ISP_CMDE5hFlash命令模式寄存器----------MS2MS1MS0xxxx x000*/
/*ISP_TRIGE6hFlash命令触发寄存器xxxx xxxx*/
/*ISP_CONTRE7hISP/IAP 控制寄存器ISPENSWBSSWRST----WT2WT1WT0000x x000*/
/************************************************************************************************************************/


/************************************************************************************/
/* ISP_CMD寄存器模式设置*/
/* D7D6D5D4D3D2D1D0模式选择*/
/* 保留命令选择*/

/* ----------000待机模式,无ISP操作*/
/* ----------001对用户的应用程序flash区及数据flash区字节读*/
/* ----------010对用户的应用程序flash区及数据flash区字节编程*/
/* ----------011对用户的应用程序flash区及数据flash区扇区擦除*/
/************************************************************************************/

/*在ISPEN(ISP_CONTR.7) =1时,对ISP_TRIG 先写入46h,再写入B9h,ISP/IAP命令才会生效。*/


/* 定义常量 */
#define ERROR 0
#define OK 1

/* 定义Flash 操作等待时间 */
//#define WAIT_TIME 0x00 //mcu clock 40mhz
//#define WAIT_TIME 0x01 //mcu clock 20mhz
//#define WAIT_TIME 0x02 //mcu clock 10mhz
#define WAIT_TIME 0x03 //mcu clock 5mhz

sfr ISP_DATA= 0xe2; // Flash数据寄存器
sfr ISP_ADDRH= 0xe3;// Flash高字节地址寄存器
sfr ISP_ADDRL= 0xe4;// Flash低字节地址寄存器
sfr ISP_CMD= 0xe5;// Flash命令模式寄存器
sfr ISP_TRIG= 0xe6;// Flash命令触发寄存器
sfr ISP_CONTR= 0xe7;// ISP/IAP 控制寄存器

#define CMD_READ 0x01 // 定义IAP的读字节操作
#define CMD_PRGM 0x02// 定义IAP的写字节操作
#define CMD_ERASE 0x03 // 定义IAP的擦除扇区操作

/*********************** 打开 ISP,IAP 功能 ***********************/
static void ISPIAPEnable(void)
{
//EA = 0; // 关中断
ISP_CONTR = ISP_CONTR & 0x18; // 0001,1000
ISP_CONTR = ISP_CONTR | WAIT_TIME; // 写入硬件延时
ISP_CONTR = ISP_CONTR | 0x80; // ISPEN = 1
}


/*********************** 关闭 ISP,IAP 功能 ***********************/
static void ISPIAPDisable(void)
{
ISP_CONTR = ISP_CONTR & 0x7f; // ISPEN = 0
ISP_TRIG = 0x00;
//EA = 1; // 开中断
}

/************************* 触发Flash操作 *************************/
static ActiveOperate(void)
{
bit eacpy;
eacpy = EA;
EA = 0;
ISPIAPEnable();
ISP_TRIG = 0x46; // 触发ISP_IAP命令字节1
ISP_TRIG = 0xb9; // 触发ISP_IAP命令字节2
{UINT8 i=2; while(i--);}
ISPIAPDisable();
EA = eacpy;
}


/**************************** 读一字节 ****************************/
static UINT8 IAPReadByte(const UINT16 uiAddr)
{
ISP_ADDRH = (UINT8)(uiAddr >> 8);// 写地址
ISP_ADDRL = (UINT8)(uiAddr&0xFF);
ISP_CMD = ISP_CMD & 0xf8;// 清低三位
ISP_CMD = ISP_CMD | CMD_READ; // 写入读命令

ActiveOperate();// 触发执行
return (ISP_DATA); // 返回读到的数据
}

/**************************** 写一字节 ****************************/
static void IAPWriteByte(const UINT16 uiAddr, const UINT8 ucData)
{
ISP_ADDRH = (UINT8)(uiAddr >> 8);// 写地址
ISP_ADDRL = (UINT8)(uiAddr&0xFF);
ISP_CMD = ISP_CMD & 0xf8;// 清低三位
ISP_CMD = ISP_CMD | CMD_PRGM; // 写入写命令
ISP_DATA = ucData; // 写入数

据准备

ActiveOperate();// 触发执行
}

/**************************** 擦除一扇区 ****************************/
static void IAPEarseSection(const UINT16 uiAddr)
{
UINT16uiSecAddr;

uiSecAddr = (uiAddr & 0xfe00); // 取扇区地址
ISP_ADDRH = (UINT8)(uiSecAddr >> 8);// 写地址
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD & 0xf8; // 清低三位
ISP_CMD = ISP_CMD | CMD_ERASE; // 写入擦除命令

ActiveOperate();// 触发执行
}


------------------------------------------------------------------------------------------------------------------------


#include//到宏晶网站下载头文件或自己在现有的头文件上加上相应的寄存器定义即可。
#include
#define uchar unsigned char
#define uint unsigned int

/****************uart init***********/
void UART_inti(void)
{
AUXR=0x40;//定时器1速度是普通8051的12倍,不分频
TMOD=0x20;//定时器1工作在方式2,用来产生波特率
SCON=0x50;//串口工作在方式1,允许接收
TL1=0xF7;//波特率为38400;FB为115200
TH1=0xF7;
PCON=0x00;//SMOD=0
TR1=1; //产生波特率
}

void ISP_write(uint ISP_addr,uchar ISP_data)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除
{
ISP_DATA=ISP_data; //送数据
ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=2;//写字节模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//触发启动ISP
_nop_();//等待写入
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
}

uchar ISP_read(uint ISP_addr)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除
{uchar recivedata;
ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=1;//写字节模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//触发启动ISP
_nop_();//等待读
recivedata=ISP_DATA;
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
return recivedata;
}

void ISP_erase(uint ISP_addr)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除
{ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=3;//写字节模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//触发启动ISP
_nop_();//等待擦除
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
}


//主程序只为测试时随意编写的,可以根据需要做相应的修改即可。
void main(void)
{
uchar returndata;
uint textdata=0x2660;
UART_inti();
while(1)
{SBUF=5;
while(!TI);
TI=0;
while(!RI);
RI=0;
ISP_erase(0x2800);
ISP_write(0x2800,textdata%256);
ISP_write(0x2801,textdata/256);
returndata=ISP_read(0x2800);
SBUF=returndata;
while(!TI);
TI=0;
returndata=ISP_read(0x2801);
SBUF=returndata;
while(!TI);
TI=0;
}

}

//声明下这是应用在STC的单片机中的。不同的型号地址

不一样,改下IAP的地址即可。新出的产品像STC12C5A60S2等,触发的命令也不一样ISP_TRIG=0x46;ISP_TRIG=0xB9;也就是这两条要根据手册修改下即可。。

相关主题
文本预览
相关文档 最新文档