📄 eeprom.c
字号:
/*
*CopyRight Reserved? 凯拓科技版权所有 http://www.ktopcn.com
*文件名:eeprom.c
*描述:提供EEPROM的底层驱动,本模块以I2C为驱动。
*
*版本:v1.0
*作者:ktop
*日期:2004/11/11
*/
#define EEPROM_C
#include "eeprom.h"
#if BUF_ENABLE == true
static uint suiEEPROMSAddr = 0; //缓冲所对应的EEPROM起始地址。
static uint suiEEPROMDAddr = 0; //缓冲所对应的EEPROM结束地址,当起始地址与结束地址相等时,无数据
static uchar sucEEPROMBuf[EEPROM_BUF_SIZE]; //EEPROM BUFFER
#endif
/*
*函数性质:私有
*入口:无
*出口:无
*功能:实现延时功能。
*/
static void Delay10ms(void)
{
uint i = DELAY_VAL;
while(i--)
{
NOP();
}
}
/*
*函数性质:私有
*入口:待操作的地址uiAddr
*出口:无
*功能:写入待操作的存储器地址。
*/
static void WriteI2cAddr(uint uiAddr)
{
#if I2C_MEM >= I2C_24C32 //容量大于24C32的芯片写地址操作
I2cStart();
I2cSend(DEVICE_ADDR_W);
WaitAck();
I2cSend((uchar)(uiAddr>>8));
WaitAck();
I2cSend((uchar)(uiAddr));
WaitAck();
#elif I2C_MEM >= I2C_24C04 //针对24C04到24C16之间的芯片
uchar i;
i = ( ((uchar)(uiAddr>>7))& 0x0e);
I2cStart();
I2cSend(DEVICE_ADDR_W | i);
WaitAck();
I2cSend((uchar)(uiAddr));
WaitAck();
#elif I2C_MEM < I2C_24C04 //针对24C01及24C02
I2cStart();
I2cSend(DEVICE_ADDR_W);
WaitAck();
I2cSend((uchar)(uiAddr));
WaitAck();
#endif
}
/*
*函数性质:私有
*入口:存储器地址uiAddr,读入数据缓冲地址pData,读入长度uiLen
*出口:无
*功能:从I2C存储器中读给定个数的数据入缓冲。
*/
static void ReadI2C(uint uiAddr,uchar *pData, uint uiLen)
{
#if (I2C_MEM >= I2C_24C04) && (I2C_MEM <= I2C_24C16)
uchar i = ( ((uchar)(uiAddr>>7))& 0x0e);
#endif
WriteI2cAddr(uiAddr);
I2cStart();
#if (I2C_MEM >= I2C_24C04) && (I2C_MEM <= I2C_24C16)
I2cSend(DEVICE_ADDR_R | i);
#else
I2cSend(DEVICE_ADDR_R);
#endif
WaitAck();
for (; uiLen > 1; uiLen--)
{
CLRWATCHDOG();
*pData++ = I2cReceive();
SendAck();
}
*pData++ = I2cReceive();
SendNotAck();
I2cStop();
}
/*
*函数性质:私有
*入口:存储器地址uiAddr, 待写缓冲pData, 待写入长度uiLen
*出口:无
*功能:将缓冲中给定长度的数据写入到存储器给定的地址空间。
*/
static void WriteI2C(uint uiAddr, uchar *pData, uint uiLen)
{
WRITE_EN();
while(uiLen)
{
CLRWATCHDOG();
WriteI2cAddr(uiAddr);
for (; uiLen > 0;)
{
I2cSend(*pData++);
WaitAck();
uiAddr++;
uiLen--; //由于存在break语句,uiLen必须在break之前递减。
if ( (uiAddr % EEPROM_PAGE_SIZE) == 0)
{
break; //已写满一页
}
}
I2cStop();
Delay10ms();
}
WRITE_DS();
}
#if BUF_ENABLE == true
/*
*函数性质:私有
*入口:存储器地址uiAddr, 与EEPROM地址相对应的缓冲地址pData, 缓冲的数据长度。
*出口:无
*功能:刷新EEPROM的CACHE
*/
void RefurbishBuf(uint uiAddr, uchar *pData, uint uiLen)
{
uchar i;
uchar *pAdim = sucEEPROMBuf + EEPROM_BUF_SIZE - 1;
if (uiLen >= EEPROM_BUF_SIZE) //仅在读写的数据长度超过规缓冲长度时更新缓冲
{
pData += uiLen-1;
for (i = 0; i < EEPROM_BUF_SIZE; i++)
{
*pAdim-- = *pData--;
}
suiEEPROMSAddr = uiAddr + uiLen - EEPROM_BUF_SIZE;
suiEEPROMDAddr = uiAddr + uiLen;
}
}
#endif
/*
*函数性质:公共
*入口:无
*出口:无
*功能:存储器模块初始化。
*/
void MemoryIni(void)
{
#if BUF_ENABLE == true
suiEEPROMSAddr = 0;
ReadMemory(0, sucEEPROMBuf, EEPROM_BUF_SIZE);
suiEEPROMDAddr = EEPROM_BUF_SIZE;
#endif
}
/*
*函数性质:公共
*入口:存储器地址uiAddr,读入数据缓冲地址pData,读入长度uiLen
*出口:无
*功能:从存储器中读出给定长度的数据,注意:pData所指向的缓冲大小应确保能存入uiLen
*长度的数据。
*/
void ReadMemory(uint uiAddr,uchar *pData, uint uiLen)
{
#if BUF_ENABLE == true
uint i;
if ( (uiAddr >= suiEEPROMSAddr) && ( (uiAddr+uiLen) <=suiEEPROMDAddr) )
{ //被访问的数据位于缓冲中
i = uiAddr - suiEEPROMSAddr;
for (; uiLen > 0; uiLen--)
{
*pData++ = sucEEPROMBuf[i++];
}
}
else
{
ReadI2C(uiAddr, pData, uiLen); //从存储器中读给定个数据入缓冲。
RefurbishBuf(uiAddr, pData, uiLen); //刷新缓冲中的数据。
}
#else //无缓冲模式读数
ReadI2C(uiAddr, pData, uiLen); //直接读数。
#endif
}
/*
*函数性质:公共
*入口;存储器地址uiAddr,待写入的数据地址pData, 待写入的数据长度uiLen。
*出口:写入成功标志, true:写入成功 false:写入失败
*功能:将给定长度的数据写入到存储器中,并返回写入成功标志。
*/
bool WriteMemory(uint uiAddr, uchar *pData, uint uiLen)
{
#if BUF_ENABLE == true
uint i;
if ( (uiAddr >= suiEEPROMSAddr) && ( (uiAddr+uiLen) <=suiEEPROMDAddr) )
{ //被访问的数据位于缓冲中
i = uiAddr - suiEEPROMSAddr;
for (; uiLen > 0; uiLen--)
{
sucEEPROMBuf[i++] = *pData++;
}
return true; //写入内部RAM的数据不用检查。
}
WriteI2C(uiAddr, pData, uiLen); //写给定个数据入缓冲。
RefurbishBuf(uiAddr, pData, uiLen); //刷新缓冲中的数据。
#else
WriteI2C(uiAddr, pData, uiLen);
#endif
return true; //先不作数据检查。
}
#if BUF_ENABLE == true
/*
*函数性质:公共
*入口:无
*出口:无
*功能:刷新BUffer中的数据,使buffer中的数据存入到EEPROMK中。
*/
void Flush(void)
{
WriteI2C(suiEEPROMSAddr, sucEEPROMBuf, EEPROM_BUF_SIZE);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -