⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom.c

📁 关于24CXX的驱动程序,你可以很方便的加入到自己的应用程序
💻 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 + -