于stc自帶EEPROM來(lái)說(shuō),用起來(lái)唯一不太方便的地方就是每次修改任何一個(gè)字節(jié)需要將整個(gè)扇區(qū)都擦除才能修改,所以每次修改都要講整個(gè)扇區(qū)內(nèi)容用數(shù)組全部讀出緩存起來(lái),進(jìn)行擦除操作,講需要修改的內(nèi)容在相應(yīng)的數(shù)組位置修改好,再講整個(gè)數(shù)組內(nèi)容重新寫入到EEPROM里,頭文件中我已經(jīng)將接口函數(shù)都寫好啦。直接調(diào)用就行,不用考慮任何問(wèn)題,而且地址也直接從0開(kāi)始到 USING_CHAR_NUM-1(USING_CHAR_NUM最大可到512)
#ifndef __EEPROM_H__
#define __EEPROM_H__
unsigned char EepromReadByte(unsigned char addr);
void EepromWriteByte(unsigned char addr, unsigned char dat);
#endif#include “intrins.h”
typedef unsigned char BYTE;
typedef unsigned int WORD;
sfr IAP_DATA = 0xC2; //Flash data register
sfr IAP_ADDRH = 0xC3; //Flash address HIGH
sfr IAP_ADDRL = 0xC4; //Flash address LOW
sfr IAP_CMD = 0xC5; //Flash command register
sfr IAP_TRIG = 0xC6; //Flash command trigger
sfr IAP_CONTR = 0xC7; //Flash control register
#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 ENABLE_IAP 0x82 //if SYSCLK《20MHz
//Start address for STC12C5A60S2 series EEPROM
#define IAP_ADDRESS 0x0000
#define USING_CHAR_NUM 11
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);
unsigned char EepromReadByte(unsigned char addr)
{
return(IapReadByte(addr));
}
void EepromWriteByte(unsigned char addr, unsigned char dat)
{
unsigned char eepromBUF[USING_CHAR_NUM];
unsigned char i;
for(i=0; i《 USING_CHAR_NUM; i++)
{
eepromBUF[IAP_ADDRESS+i] = IapReadByte(IAP_ADDRESS+i);
}
if(addr 《 USING_CHAR_NUM)
{
eepromBUF[IAP_ADDRESS+addr] = dat;
IapEraseSector(IAP_ADDRESS);
for(i=0; i《 USING_CHAR_NUM; i++)
{
IapProgramByte(IAP_ADDRESS+i, eepromBUF[IAP_ADDRESS+i]);
}
}
}
//void EepromInit(void)
//{
// unsigned int tmp = 0;
// _nop_();
// _nop_();
// _nop_();
// tmp = IapReadByte(IAP_ADDRESS+1);
// tmp = (tmp 《《 8) + IapReadByte(IAP_ADDRESS);
// if(0xffff == tmp)
// {
// IapProgramByte(IAP_ADDRESS,(BYTE)0);
// IapProgramByte(IAP_ADDRESS+1,(BYTE)0);
// tmp = 0;
// }
// tmp++;
// IapEraseSector(IAP_ADDRESS);
// IapProgramByte(IAP_ADDRESS,(BYTE)tmp );
// IapProgramByte(IAP_ADDRESS+1,(BYTE)(tmp》》8) );
//
//}
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
}
BYTE IapReadByte(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 = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); _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
}
void IapProgramByte(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 = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); _nop_(); //MCU will hold here until ISP/IAP/EEPROM
//operation complete
IapIdle();
}
void IapEraseSector(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 = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); _nop_(); //MCU will hold here until ISP/IAP/EEPROM
//operation complete
IapIdle();
}
評(píng)論
查看更多