代码改变世界

【转载】 EEPROM读写

2018-05-11 19:10  Lyp_02  阅读(486)  评论(0)    收藏  举报

来自 https://blog.csdn.net/fuyunyouziyi/article/details/51614338

define EEP_MAX_PAGE_SIZE 32 // 最大页写字节数

define EEP_MAX_ROM_SIZE 8192 // EEROM容量

define EEP_ADDR_SIZE 2 // EEROM地址字节数

define EEP_WRITE_DELAY_TIME (OS_TICKS_PER_SEC/10)

define SYS_HEAD_LEN 7 // 参数版本号,如果EEPROM中的参数版本号和程序中不同则更新参数

// EEPROM各地址分配

define SYS_HEAD_ADDR 0 // 是否第一次运行标志地址

define SYS_INFO_ADDR 7 // 系统信息保存地址

//#define PHONE_VOLUME_ADDR 199 // 电话音量保存地址

define CENTER_NUM_ADDR 200 // 中心号码保存地址

define PHONE_BOOK_NUM 392 // 呼入呼出电话条数,前四位保存呼入条数,后四位保存呼出条数

define RING_IN_ADDR 393 // 呼入限制电话保存地址

define RING_OUT_ADDR 852 // 呼出限制电话保存地址

define VIRTUAL_PHONE_ADDR 1281 // 虚拟号码保存地址

define AREA_ALARM_ADDR 1292 // 区域报警信息地址

/*********************************************************************************************************
** 函数名称: EepromRead
** 功能描述: 读EEPROM处理函数,在使用前,必须定义最大页写字节数,并且定义EEPROM的容量
** 输 入:
** buf:读取数据存放地址
** len:要读取的数据长度
** ptr:EEPROM存储位置
** 输 出: 实际读取的数据数目
********************************************************************************************************/
uint16 EepromRead(uint8 *buf , uint16 len , uint16 ptr)
{
uint8 EeromAddr[2];
EeromAddr[0] = ptr >> 8;
EeromAddr[1] = ptr & 0xff;
return(I2cRead(AT24CXX , buf , EeromAddr , EEP_ADDR_SIZE , len));
}

/*********************************************************************************************************
** 函数名称: EepromWrite
** 功能描述: 写EEPROM处理函数,在使用前,必须定义最大页写字节数,并且定义EEPROM的容量
** 输 入:
** buf:所要发的数据
** len:要发的数据长度
** ptr:EEPROM存储位置
** 输 出: 实际所发的数据数目
********************************************************************************************************/
uint16 EepromWrite(uint8 *buf , uint16 len , uint16 ptr)
{
uint8 bufTemp[EEP_MAX_PAGE_SIZE + EEP_ADDR_SIZE] , i , j = 0;
uint8 flowSize , flowLen;
uint16 sizeTemp , lenTemp = 0;

if((ptr + len) > (EEP_MAX_ROM_SIZE - 1))	// EEPROM溢出保护
	return 0;
    
flowSize = ptr % EEP_MAX_PAGE_SIZE;
if(flowSize)								// 如果不是在页的起点
{
	flowLen = EEP_MAX_PAGE_SIZE - flowSize; // 当前页可写长度
	if(flowLen < len)						// 所要写的数据将跨页
	{
		bufTemp[0] = ptr >> 8;				// 地址高位
		bufTemp[1] = ptr;					// 地址低位
		for(i = 0;i < flowLen;i++)
			bufTemp[i + EEP_ADDR_SIZE] = buf[i];
		ptr += flowLen;                     // 下次将写入的地址
		len -= flowLen;                     // 剩余未写数据的长度
		sizeTemp = I2cWrite(AT24CXX , bufTemp , flowLen + EEP_ADDR_SIZE);//本次写入的长度
		OSTimeDly(EEP_WRITE_DELAY_TIME);    // 写入延时
		lenTemp = lenTemp + sizeTemp - EEP_ADDR_SIZE;
	}
	else//所要写的数据未能跨页
	{
		bufTemp[0] = ptr >> 8;				// 地址高位
		bufTemp[1] = ptr;					// 地址低位
		for(i = 0;i < len;i++)
			bufTemp[i + EEP_ADDR_SIZE] = buf[i];
		sizeTemp = I2cWrite(AT24CXX , bufTemp , len + EEP_ADDR_SIZE);
		OSTimeDly(EEP_WRITE_DELAY_TIME);
		return (sizeTemp - EEP_ADDR_SIZE);  // 完毕返回
	}
}
while(len / EEP_MAX_PAGE_SIZE)              //剩余未写数据长度仍大于整页长度
{
	bufTemp[0] = ptr >> 8;					// 地址高位
	bufTemp[1] = ptr;						// 地址低位
	j = lenTemp;							
	for(i = 0;i < EEP_MAX_PAGE_SIZE;i++)
		bufTemp[i + EEP_ADDR_SIZE] = buf[j + i];
	ptr += EEP_MAX_PAGE_SIZE;
	j += EEP_MAX_PAGE_SIZE;                 // 
	len -= EEP_MAX_PAGE_SIZE;
	sizeTemp = I2cWrite(AT24CXX , bufTemp , EEP_MAX_PAGE_SIZE + EEP_ADDR_SIZE);
	OSTimeDly(EEP_WRITE_DELAY_TIME);
	lenTemp = lenTemp + sizeTemp - EEP_ADDR_SIZE;
}
if(len)                                 // 剩余未写数据长度不足整页长度 
{
	bufTemp[0] = ptr >> 8;				// 地址高位
	bufTemp[1] = ptr;					// 地址低位
	j = lenTemp;							
	for(i = 0;i < len;i++)
		bufTemp[i + EEP_ADDR_SIZE] = buf[j + i];
	sizeTemp = I2cWrite(AT24CXX , bufTemp , len + EEP_ADDR_SIZE);
	OSTimeDly(EEP_WRITE_DELAY_TIME);
	lenTemp = lenTemp + sizeTemp - EEP_ADDR_SIZE;
}
return lenTemp;                         // 返回写入的数据数目

}