/**********************************************
STC12c5a60单片机EEPROM的测试程序
web:www.STCMCU.COM
Time:2011.5.5
**********************************************/
#include"reg51.h"
#include"intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD ;
/*define SFR associated with the IAP*/
sfr IAP_DATA = 0Xe2; //Flash data register
sfr IAP_ADDRH = 0Xe3; //Flash address HIGH
sfr IAP_ADDRL = 0Xe4; //Flash address LOW
sfr IAP_CMD = 0Xe5; //Flash command register
sfr IAP_TRIG = 0Xe6; //Flash command trigger
sfr IAP_CONTR = 0xe7; //Flash control register
/*define ISP/iap/eeprom command*/
#define CMD_IDLE 0 //Stand_by
#define CMD_READ 1 //BYTE-READ
#define CMD_PROGRAM 2 //BYTE_PROGRAM
#define CMD_ERASE 3 //SECTOR-ERASE
/*define ISP/IAP/EEPROM operation const for IAP_CONTR*/
#define ENABLE_IAP 0X82 //IF SYSCLK<20MHZ
#define IAP_ADDRESS 0X2000 //start address for stc12c5a60s2 eeprom
void Delay(BYTE n);
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr,BYTE dat);
void IapEraseSector(WORD addr);
/****************************************************************************************************************
函 数: StartUART( void )
功 能: 232串口初始化
输 入: ---------------
输 出:
描 述:
****************************************************************************************************************/
void StartUART( void )
{ //波特率1200
SCON = 0x50;
TMOD = 0x20;
TH1 = 0xe6;
TL1 = 0xe6;
PCON = 0x00;
TR1 = 1;
}
/****************************************************************************************************************
函 数: R_S_Byte(uchar R_Byte)
功 能: 数据发送
输 入: ---------------
输 出:
描 述:
****************************************************************************************************************/
void R_S_Byte(BYTE R_Byte)
{
SBUF = R_Byte;
while( TI == 0 ); //查询法
TI = 0;
}
void main()
{
WORD i;
StartUART();
R_S_Byte('1');
P1=0xfe; //1111,1110 system reset ok
Delay(10);
IapEraseSector(IAP_ADDRESS); //erase current sector 从开始地址进行擦除
for(i=0;i<512;i++)
{
if(IapReadByte(IAP_ADDRESS+i)!=0xff) //判断擦除干净没有
goto Error; //如果没有跳出
}
P1=0xfc; //1111,1100erase successful
Delay(10);
for(i=0;i<512;i++) //写数据
{
IapProgramByte(IAP_ADDRESS+i,(BYTE)i);
}
P1=0xf8; //1111,1000 program successful
Delay(10);
for(i=0;i<512;i++)
{
R_S_Byte (IapReadByte(IAP_ADDRESS+i));
if(IapReadByte(IAP_ADDRESS+i)!=(BYTE)i)
goto Error;
}
P1=0xf0; //1111,0000 verify successful
while(1);
Error:
P1&=0X7f;
while(1);
}
/********延时程序*********************/
void Delay(BYTE n)
{
WORD x;
while(n--)
{
x=0;
while(++x);
}
}
/*************disable ISP/IAP/EEPROM funtion************
******************make MCU in a safe state***************/
void IapIdle()
{
IAP_CONTR=0; //close IAP funtion
IAP_CMD =0; //clear command to standby
IAP_TRIG=0; //clear trigger register
IAP_ADDRH=0X80; //data ptr point to non_eeprom area
IAP_ADDRL=0x00; //clear iap address to prevent misuse
}
/***************** 读数据的程序*****************/
BYTE IapReadByte(WORD addr)
{
BYTE dat;
IAP_CONTR=ENABLE_IAP; //使能IAP功能
IAP_CMD=CMD_READ; //设置为读
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x46; //send triger command1
IAP_TRIG=0xb9; //send triger command2
_nop_();
dat=IAP_DATA; //复位所有功能
IapIdle(); //
return dat;
}
/*****************写数据*********************/
void IapProgramByte(WORD addr,BYTE dat)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_PROGRAM;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG=0X46;
IAP_TRIG=0xb9;
_nop_();
IapIdle();
}
/***********擦除功能*****************************/
void IapEraseSector(WORD addr)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_ERASE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x46;
IAP_TRIG=0xb9;
_nop_();
IapIdle();
}