SEI();
}
unsigned char EEPROM_read(unsigned int uiAddress)
{
while(EECR&(1 //判断读写忙标志
CLI();
EEAR = uiAddress; //送入地址
EECR |=(1 //读位置位
SEI();
return EEDR;//返回数据
}
读和写的操作如下面所示 读写数据时要从0x01开始 ,00地址有bug(数据手册上讲的)
temp=EEPROM_read(0x01);
EEPROM_write(0x01,temp);
二、提升篇-使用缓冲机构的操作
思路是这样的:首先建立读写缓冲区,把需要写的数据放入到写缓冲区中,由于在AVR单片机中,写一个数据时比较慢的大概要8ms吧,这么长的时间肯定不能一直while等下去,因此我们用中断在处理,等单片机EEPROM程序写好了就有ready中断,这时就能读写操作了,写的时候从写缓冲区中取出数据,写的时候要注意不允许读,经过一段时间后就完成了,而且我们发现写的时候只是把数据送入到单片机中的一个寄存器中,至于EEPROM什么时候来读这个寄存器直至写完,我们也没有必要管他,因为他操作好了会中断告诉我们,从而这8ms还可以用来执行其它的程序了,就这样直到所有的数据都写完了。
#pragma interrupt_handler vIvEeReady:iv_EE_READY
void vIvEeReady(void)
{
if(!fgEepromBufEmpty()) //缓冲区数据还没完全写到EPPROM中
{
CLI(); //写的时候不希望有别的中断
EEAR = _sEepromBuf[_bEepromBufRdPtr].wAddress;
EEDR = _sEepromBuf[_bEepromBufRdPtr].bVal; //数据写入
EECR |= BIT(EEMWE);
EECR |= BIT(EEWE);
SEI(); //写好这个就打开,尽可能满足实时性
_bEepromBufRdPtr++; //指向下一个缓冲数据
if(_bEepromBufRdPtr >= EEPROM_WRITE_BUF_SIZE) //到了缓冲区顶了
{
_bEepromBufRdPtr = 0; //从头部开始计数
}
_bEepromBufNs--; //当前还没有写入EEPROM的数
}
else
{
EECR &= ~BIT(EERIE); //都写好了就把中断关闭掉
}
}
uchar bWriteData2Eeprom(uint wAddress, uchar bVal)
{
if(fgEepromBufFull()) //是否达到缓冲定义的最大值
{
return RET_BUSY;
}
CLI(); //关中断?这里应该放在中断函数里面的
_sEepromBuf[_bEepromBufWrPtr].wAddress = wAddress;
_sEepromBuf[_bEepromBufWrPtr].bVal = bVal;
_bEepromBufWrPtr++;
if(_bEepromBufWrPtr >= EEPROM_WRITE_BUF_SIZE) //写满了就从头开始写
{ //需要保证数据不丢失
_bEepromBufWrPtr = 0;
}
_bEepromBufNs++; //写一个计数就加一下
EECR |= BIT(EERIE); //写一个数据后这里打开了中断
SEI();
return RET_SUCCESS;
}
// Notice! The programer must ensure the EEPROM is NOT in writing state.
uchar bReadDataFromEeprom(uint wAddress, uchar *pbVal)
{
if(EECR & BIT(EEWE)) //没有在写时才能读取,一般放在程序开始时
{
return RET_BUSY;
}
EEAR = wAddress; //送入地址
EECR |= BIT(EERE); //读锁存
*pbVal = EEDR; //取出数据
return RET_SUCCESS; //读取成功
}
BYTE bGetEepromWrBuf(void)
{
return _bEepromBufNs; //读取当前剩余的没写入的数据
}
void bClrEepromBuf(void)
{
CLI();
_bEepromBufNs = 0;
_bEepromBufRdPtr = _bEepromBufWrPtr;
EECR &= ~BIT(EERIE);
SEI();
}
BOOL fgEepromWizard(void)
{
BOOL fgRet = FALSE;
return fgRet;
}
void vInitEeprom(void)
{
EECR = 0x00; //EEPROM控制寄存器清零
_bEepromBufWrPtr = 0; //读写指针和数据计数清零
_bEepromBufRdPtr = 0;
_bEepromBufNs = 0;
}