[中学教育]STC单片机内部EEPROM测试程序
STC单片机内部EEPROM测试程序
/*stc单片机内部EEPROM测试程序*/ #include
#include
typedef unsigned char uchar;
typedef unsigned int uint;
/*Declare SFR associated with the IAP*/ sfr IAP_DATA =0xC2;
sfr IAP_ADDRH=0xc3;
sfr IAP_ADDRL=0xc4;
sfr IAP_CMD =0XC5;
sfr IAP_TRIG =0xc6;
sfr IAP_CONTR=0xc7;
sbit DS=P1^2;
sbit LAD=P1^3;
sbit DCK=P1^4;
/*define eeprom command*/
#define CMD_IDLE 0 // Standby #define CMD_READ 1 // Byte read #define CMD_PROGRAM 2 // Byte program #define CMD_ERASE 3 // Sector erase /* define eeprom operation const for IAP_CONTR */
#define ENABLE_IAP 0X81 //SYSCLK<24MHZ //起始地址
uint IAP_DAT_ADDRESS=0; //数据存储地址
uint IAP_ADD_ADDRESS=0x0200; //数据存储地址指针
uchar eeprom_flag=0; //第一区数据存储地址标号
uchar a1=0;
uchar a2=0;
uint code
table_dula[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0
xfc,0xb9,0xde,0xf9,0xf1};
void Delay(uchar n);
void IapIdle();
uchar IapReadByte(uint addr);
void IapProgramByte(uint addr,uchar dat); void IapEraseSector(uint addr); //void IapEraseSector();
void jxi5020(uchar led1,uchar led2); void IapRead_Add(void);
void main()
{
while(1){
IapRead_Add();
// Delay(10); //将存数据扇区地址设为上次掉电时的地址
IapProgramByte(IAP_DAT_ADDRESS,table_dula[a1]);
//Delay(10);
if(IapReadByte(IAP_DAT_ADDRESS)!=table_dula[a1])
//存入第一位数据
goto Error;
IAP_DAT_ADDRESS++;
a1++;
if(a1==30)
a1=0;
IapProgramByte(IAP_DAT_ADDRESS,table_dula[a2]);
//存入第二位数据
// Delay(1);
if(IapReadByte(IAP_DAT_ADDRESS)!=table_dula[a2])
goto Error;
IAP_DAT_ADDRESS++;
a2++;
if(a2==30)
a2=0;
// if(IAP_DAT_ADDRESS==0x01f4) // goto IapRead_Add();
eeprom_flag++;
IapProgramByte(IAP_ADD_ADDRESS,eeprom_flag); //存入当前数据地址低8位
// Delay(1);
if(IapReadByte(IAP_ADD_ADDRESS)!=eeprom_flag)
goto Error;
IAP_ADD_ADDRESS++;
// Delay(1);
jxi5020(IapReadByte(IAP_DAT_ADDRESS-2),IapReadByte(IAP_D
AT_ADDRESS-1));
Delay(10); } // jxi5020(IapReadByte(0x03ff),0x5b);
// while(1);
Error:
jxi5020(0x40,0x40);
while(1);
}
void Delay(uchar n) {
uint x;
while(n--)
{
x=0;
while(++x);
}
}
void IapIdle() {
IAP_CONTR=0;
IAP_CMD =0;
IAP_TRIG =0;
IAP_ADDRH=0X80;
IAP_ADDRL=0; }
uchar IapReadByte(uint addr)
{
uchar dat;
IAP_CONTR=ENABLE_IAP;
IAP_CMD =CMD_READ;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG =0x5a;
IAP_TRIG =0xa5;
_nop_();
dat=IAP_DATA;
IapIdle();
return dat;
}
void IapProgramByte(uint addr,uchar dat)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD =CMD_PROGRAM;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG =0x5a;
IAP_TRIG =0xa5;
_nop_();
IapIdle();
}
void IapEraseSector(uint addr) //void IapEraseSector() {
IAP_CONTR=ENABLE_IAP;
IAP_CMD =CMD_ERASE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG =0x5a;
IAP_TRIG =0xa5;
_nop_();
IapIdle();
}
void IapRead_Add(void)
{
uint add,add_num;
uchar dat1,dat2;
if(IapReadByte(0x03ff)==0x55) //判断是否有标志位,如果无,则为第一次上电,全部擦除后写入标志位,数码管全显
{
if(IapReadByte(0x0200)==0xff) //如果有标志位,判断第二扇区第一个地址是否有地址信息,如果无,则
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
示已经初始化完成但未写数据,地址初始化,数码管全显
{
// jxi5020(0xff,0xff);
IAP_DAT_ADDRESS=0;
IAP_ADD_ADDRESS=0x0200;
eeprom_flag=0;
}
else
{
for(add=0x0200;(IapReadByte(add)+1==IapReadByte(add+1))&
&(add<0x02f8);add++)
{
;
}
if(add==0x02f8) //如果已经写满500个数据,EEPROM擦除,并在最后一位写入0x55标志位,将最后一位数转存到地址0和地址1
{
dat1=IapReadByte(0x01f2);
dat2=IapReadByte(0x01f3);
IapEraseSector(0);
IapEraseSector(0x0200);
for(add_num=0;add_num<1024;add_num++)
{
// IapEraseSector(add_num);
if(IapReadByte(add_num)!=0xff)
goto Error1;
}
IapProgramByte(0x03ff,0x55); //写入标志位
// Delay(1);
if(IapReadByte(0x03ff)!=0x55)
goto Error;
IapProgramByte(0,dat1); //将原来最后两位数转存到初始位
// Delay(1);
if(IapReadByte(0)!=dat1)
goto Error;
IapProgramByte(0x0001,dat2);
// Delay(1);
if(IapReadByte(0x0001)!=dat2)
goto Error;
IapProgramByte(0x0200,0x01); //将初始位的两个数据地址标志号写入 0x0002
// Delay(1);
if(IapReadByte(0x0200)!=0x01)
goto Error;
IAP_DAT_ADDRESS=0x0002;
IAP_ADD_ADDRESS=0x0201;
eeprom_flag=0x01;
}
else
{
IAP_DAT_ADDRESS=add-0x0200+add-0x0200+2; //如果未写满,地址指到当前地址,数码管显示当前值
IAP_ADD_ADDRESS=add+1;
eeprom_flag=add-0x0200+1;
//
jxi5020(IAP_DAT_ADDRESS-2,IAP_DAT_ADDRESS-1);
}
}
}
else
{
// IapEraseSector();
IapEraseSector(0);
IapEraseSector(0x0200);
for(add_num=0;add_num<1024;add_num++)
{
// IapEraseSector(add_num);
if(IapReadByte(add_num)!=0xff)
goto Error;
}
IapProgramByte(0x03ff,0x55);
// Delay(1);
if(IapReadByte(0x03ff)!=0x55) //存入第一位数据
goto Error;
IAP_DAT_ADDRESS=0;
IAP_ADD_ADDRESS=0x0200;
eeprom_flag=0;
jxi5020(0xff,0xff);
}
Error:
jxi5020(0xff,0xff);
Error1:
jxi5020(0x3f,0x3f);
Error3:
jxi5020(0x5b,0x5b);
Error2:
jxi5020(0x06,0x06); }
/************************************
功能:jxi5020
描述:数码管显示子程序 参数:led1,led2
返回:无
*************************************/
void jxi5020(uchar led1,uchar led2)
{
uchar i;
uchar j;
uchar k;
j=led1;
k=led2;
LAD=0;
for(i=8;i>0;i--)
{
DCK=0;
if(j&0x80)
DS=1;
else
DS=0;
j<<=1;
DCK=1;
}
for(i=8;i>0;i--)
{
DCK=0;
if(k&0x80)
DS=1;
else
DS=0;
k<<=1;
DCK=1;
}
LAD=1; }