程序如下:
#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
/*---------------------------------------------------------------------*/
/*-- 端口定義 ---------------------------------------*/
/*---------------------------------------------------------------------*/
sbit SWITCH = P3^2;
sbit LED = P3^4;
/*---------------------------------------------------------------------*/
/*-- 變量定義 ---------------------------------------*/
/*---------------------------------------------------------------------*/
bit flag,BUTTON_TEMP;
//-----------------------------------------------
sfr IAP_DATA = 0xC2; //IAP數(shù)據(jù)寄存器
sfr IAP_ADDRH = 0xC3; //IAP地址寄存器高字節(jié)
sfr IAP_ADDRL = 0xC4; //IAP地址寄存器低字節(jié)
sfr IAP_CMD = 0xC5; //IAP命令寄存器
sfr IAP_TRIG = 0xC6; //IAP命令觸發(fā)寄存器
sfr IAP_CONTR = 0xC7; //IAP控制寄存器
sfr WDT_CONTR = 0xC1; //0000,0000 看門(mén)狗控制寄存器
#define CMD_IDLE 0 //空閑模式
#define CMD_READ 1 //IAP字節(jié)讀命令
#define CMD_PROGRAM 2 //IAP字節(jié)編程命令
#define CMD_ERASE 3 //IAP扇區(qū)擦除命令
#define ENABLE_IAP 0x83 //if SYSCLK<12MHz
#define BUTTON_ADDRESS 0x0100 //測(cè)試地址
/*----------------------------
關(guān)閉IAP
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //關(guān)閉IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除觸發(fā)寄存器
IAP_ADDRH = 0x80; //將地址設(shè)置到非IAP區(qū)域
IAP_ADDRL = 0;
}
/*----------------------------
從ISP/IAP/EEPROM區(qū)域讀取一字節(jié)
----------------------------*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //數(shù)據(jù)緩沖區(qū)
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫(xiě)觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫(xiě)觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //讀ISP/IAP/EEPROM數(shù)據(jù)
IapIdle(); //關(guān)閉IAP功能
return dat; //返回
}
/*----------------------------
寫(xiě)一字節(jié)數(shù)據(jù)到ISP/IAP/EEPROM區(qū)域
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_DATA = dat; //寫(xiě)ISP/IAP/EEPROM數(shù)據(jù)
IAP_TRIG = 0x5a; //寫(xiě)觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫(xiě)觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*----------------------------
扇區(qū)擦除
----------------------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_ERASE; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫(xiě)觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫(xiě)觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*---------------------------------------------------------------------*/
/*-- 延時(shí)子程序 ---------------------------------------*/
/*---------------------------------------------------------------------*/
void DELAY_1MS(unsigned int z)
{
unsigned char i, j,k;
for(k=z;k>0;k--)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
/*---------------------------------------------------------------------*/
/*-- 主程序 ---------------------------------------*/
/*---------------------------------------------------------------------*/
void main()
{
flag=0;
WDT_CONTR = 0x35; //啟動(dòng)看門(mén)狗
while (1)
{
WDT_CONTR = 0x35; //啟動(dòng)看門(mén)狗
if(flag==0)
{
if(IapReadByte(BUTTON_ADDRESS)==0)
{
LED=1;
}
else if(IapReadByte(BUTTON_ADDRESS)==1)
LED=0;
else
{
IapEraseSector(BUTTON_ADDRESS);
IapProgramByte(BUTTON_ADDRESS,BUTTON_TEMP);
}
flag=1;
}
if(SWITCH==0)
{
DELAY_1MS(20);
if(SWITCH==0)
{
while(!SWITCH);
flag=0;
BUTTON_TEMP=!BUTTON_TEMP;
IapEraseSector(BUTTON_ADDRESS);
IapProgramByte(BUTTON_ADDRESS,BUTTON_TEMP);
}
}
}
}