STC 的 EEPROM 存储程序,为什么有的数据可以读出来,有的读不出来
我想用89C58存储50个测量结果,打算从第三扇区到第53扇区,每个扇区存一个,并且可供查询,程序如下uint xdata START_ADDR2=0x8400; //第三扇区首地址,此扇区开始存放测量结果
/***********************************************
-----------------保存测量结果----------------
//程序功能:把测量结果存到EEPROM中
************************************************/
void result_save(void)
{
for(save_flag=0;save_flag<50;)
{
save_flag=sector_read(START_ADDR1); //读取存储的个数
sector_ep(START_ADDR2+save_flag*200,sum,1);//将测量值保存到数据单元 当y为1时,每次写之前都要擦除扇区
++save_flag; //测量值的个数
sector_ep(START_ADDR1,save_flag,1); //保存测量值个数的标志
}
}
//*************************查询功能按键************************************
void key_scan() //键盘
{
if(S1==0) //数据查询按键S1被按下
{
delay(50); //延时50m秒
if(S1==0) //松开按键,便于检测多次按键
{
save_flag=sector_read(START_ADDR1); //读取存储的个数
sum2=sector_read(START_ADDR2+(save_flag-1)*200-k*200); //读取,从最近存储的开始读
++k; //按键次数
if(k==save_flag) //当按键次数超过存储个数时
{
k=0; //当查询次数超过存储数值时,从开始从新查询
}
lcdfill(0); //清屏
string_display3(); //显示查询数值
}
}
}
//---------------------------------擦除,存储,读取功能函数------------------------------ 注:此后的函数是在STC的论坛上摘抄的
/*----------------------------
关闭 ISP/IAP/EEPROM 功能
Make MCU in a safe state
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //Close IAP function
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 = 0; //Clear IAP address to prevent misuse
}
/*----------------------------
Program one byte to ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
dat (ISP/IAP/EEPROM data)
Output:-
----------------------------*/
void Byte_Program(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_DATA = dat; //Write ISP/IAP/EEPROM data
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
IapIdle();
}
/**********************************************
//函数名:void sector_Erase()
//函数功能:擦除扇区
//
**********************************************/
void Sector_Erase(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
IapIdle();
}
/**********************************************
//函数名: void sector_ep()
//函数功能: 擦除扇区并向扇区写入一个字(两个字节)
//入口参数:首地址,写入的字
//出口参数:
//程序说明:当y为1时,每次写之前都要擦除扇区
保存S0和vel时可用这种方式
当y为0时,保存数据不擦除扇区,应用于
厚度值的保存
**********************************************/
void sector_ep(uint address,uint dat,uchar y)
{
uchar datah,datal;
datal=dat; //低字节赋予datal
datah=dat>>=8; //高字节赋予datah
if(y==1)
{
Sector_Erase(address); //擦除扇区
}
Byte_Program(address,datal);
Byte_Program(address+1,datah); //高字节存放在高地址
}
/*----------------------------
Read one byte from ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
Output:Flash data
----------------------------*/
BYTE Byte_Read(WORD addr)
{
BYTE dat; //Data buffer
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
dat = IAP_DATA; //Read ISP/IAP/EEPROM data
IapIdle(); //Close ISP/IAP/EEPROM function
return dat; //Return Flash data
}
/**********************************************
//函数名: sector_read()
//函数功能: 从扇区中读一个字(两个字节)
//入口参数:首地址
//出口参数:
//程序说明:
***********************************************/
uint sector_read(uint address)
{
uint result,datah;
uchar datal;
datal=Byte_Read(address); //读入低字节的数据
datah=Byte_Read(address+1); //读入高字节的数据
result=datah<<=8;
result|=datal;
return(result);
}
目前的问题是:假如测得的结果分别为5,6,7,8,9,查询时可能会是5,(显示为空白),7,(显示为空白),(显示为空白),9