最近用STC89C51做一个东西,实现的功能是:使用外部中断计数,即触发中断,计数值+1;并把总的计数值保存在单片机的eeprom中,以便断电后再次使用时,能保留总的计数值。并通过液晶显示屏显示。
具体程序如下:
//============eeprom的操作程序===========
//声明ISP/IAP/EEPROM寄存器地址
sfr ISP_DATA=0XE2;
sfr ISP_ADDRH=0XE3;
sfr ISP_ADDRL=0XE4;
sfr ISP_CMD=0XE5;
sfr ISP_TRIG=0XE6;
sfr ISP_CONTR=0XE7;
//定义ISP/IAP/EEPROOM命令,等待时间及起始地址
#define CMD_READ 1
#define CMD_WRITE 2
#define CMD_ERASE 3
#define DTIME 0x81
#define JISHU_ADDRESS 0X2000 //总计数保存地址
//关闭ISP/IAP/EEPROOM函数
void ISPCLOSE()
{
ISP_CONTR=0;
ISP_CMD=0;
ISP_TRIG=0;
// ISP_ADDRH=0XFF;
// ISP_ADDRL=0XFF;
ISP_ADDRH=0X80;
ISP_ADDRL=0;
}
//EEPROM读字节函数
uchar eepread(uint ADDR)
{
ISP_CONTR=DTIME;
ISP_CMD=CMD_READ;
ISP_ADDRL=ADDR&0x00ff;
ISP_ADDRH=ADDR>>8;
// EA=0;
ISP_TRIG=0X46;
ISP_TRIG=0XB9;
_nop_();
// EA=1;
ISPCLOSE();
return (ISP_DATA);
}
//EEPROM写字节函数
void eepwrite(uint ADDR,uchar DAT)
{
ISP_DATA=DAT;
ISP_ADDRL=ADDR&0x00ff;
ISP_ADDRH=ADDR>>8;
ISP_CONTR=DTIME;
ISP_CMD=CMD_WRITE;
// EA=0;
ISP_TRIG=0X46;
ISP_TRIG=0XB9;
_nop_();
// EA=1;
ISPCLOSE();
}
//擦除扇区函数
void isperase(uint ADDR)
{
ISP_CONTR=DTIME;
ISP_CMD=CMD_ERASE;
ISP_ADDRL=ADDR&0x00ff;
ISP_ADDRH=ADDR>>8;
// EA=0;
ISP_TRIG=0X46;
ISP_TRIG=0XB9;
_nop_();
// EA=1;
ISPCLOSE();
}
//==============中断程序==============
void int0() interrupt 0
{
if(s_on==0)
{
delay1(10);
if(s_on==0)
{
num=eepread(JISHU_ADDRESS); //
num++; //
isperase(JISHU_ADDRESS); //
eepwrite(JISHU_ADDRESS,num); //
}
}
}
//=============delay time 1 ms =====================
void delay1(int i)
{
int j,k;
for(j=0;j<i;j++)
for(k=0;k<125;k++);
}
//============主函数==============
void main()
{
int num;
EA=1;
EX0=1;
IT0=1;
while(1)
{
}
}
现在程序实现的功能是:每次中断,num值+1,并且存入eeprom中。
现在有如下问题:1、单片机第一次烧写程序时,num=eepread(JISHU_ADDRESS);num值不能确定,我想法是单片机第一次使用时num的值为0,其余时候,不管再次关机开机,num的值都从eeprom中读取,这个num的第一次的初值该怎么赋?怎么判断它是第一次用?
2、num值要存入eeprom中,单片机是8位的,stc89c52中eeprom的空间为4K,分8个扇区,每个扇区512个字。起始地址为0x2000;问:num的值最大能计数到多少?如果num=12345678时,即转化二进制有24位,该怎么存储?
|