STM32F10x_模拟I2C读写EEPROM(3)(读写E2备份区 + 校验位 + 完整代码 + 应用实例)

该博客详细介绍了STM32F10x微控制器通过模拟I2C接口读写AT24C512 EEPROM的过程,包括宏定义、读写函数实现,特别是涉及了数据的备份区存储和校验码的计算与验证,确保数据的可靠性和安全性。还提供了读写E2的示例代码,帮助开发者理解和应用。
摘要由CSDN通过智能技术生成


前言

一、宏定义


// 此文的E2型号 - AT24C512

#define EEPROM_Page			 0x80u    				//EEPROM一页长度 128
#define Len_MaxVariable		 126u    				//参数的最大长度

#define EEPROM_BackUp		(x * EEPROM_Page)      	//备份地址 从第x页开始
#define EEAddr_Page(n)   	(n * EEPROM_Page)    	//第n页地址


二、读 E2 函数 (备份区+校验判断)

  • 1.校验和计算及检测函数

     /*******************************************************************************
    功能描述:检查若干字节累加和校验码正确性
    输入参数:*pData: 源数据指针
    				len: 数据字节数
    返回参数:检查结果:
    			   TRUE, 累加和校验正确
    			  FALSE, 累加和校验错误
    函数说明:计算所得累加和校验SumCheck
    *******************************************************************************/
    bool Check_Sum(const uint8_t *pData, uint8_t len)
    {
    	uint16_t Sum = 0;
    	uint16_t SumCheck = 0;
    	
    	while(len--)
    	{
    	   Sum += *pData;
    	   pData++;
    	}
    	
    	SumCheck = ((uint16_t)(*pData) << 8);
    	pData++;
    	SumCheck |= ((uint16_t)(*pData));
    	
    	if(Sum == SumCheck)
    	{
    		return TRUE;		//返回校验正确
    	}
    	else
    	{
    		return FALSE;		//返回校验错误
    	}
    }
    

  • 2.读 E2 函数(备份区 + 校验判断)

    
    /********************************************************************
    * 函数名:EEPROM_ReadVariable
    * 参数:  Addr  : 变量在EEPROM中地址 
    * 		 *pData:读出的缓存 
    * 		 Length:长度
    * 用途: 带校验位读取变量
    ********************************************************************/
    bool EEPROM_ReadVariable(uint16_t Addr, uint8_t *pData, uint8_t Length)
    {
    	uint8_t temp[Len_MaxVariable + 2];            		//最大数据长度 + 2校验位
    	
    	// 关闭外部中断 并 清除外部中断标志位
    	EXTI->IMR &= ~(EXTI_Line1);
    	EXTI_ClearFlag(EXTI_Line1);
    	
    	EEPROM_ReadSequential(Addr, temp, Length + 2);     	//包括校验位将主区数据读取出来
    	if(TRUE != Check_Sum(temp, Length)) 				//若主区校验不正确
    	{
    		delay_ms(5);  
    		EEPROM_ReadSequential(Addr + EEPROM_BackUp, temp, Length + 2);      //读取备份区数据
    		if(TRUE != Check_Sum(temp, Length))									//若备份区校验也不正确
    		{
    			return FALSE;                         		//返回读失败
    		}
    	}
    	
    	// 打开外部中断
    	EXTI->IMR |= EXTI_Line1;
    	
    	CopyBuff(pData, temp, Length);	//将数据复制到接收缓存中
    	return TRUE;					//返回读成功
    }
    	
    


三、写 E2 函数(备份区+校验)

  • 1.校验和生成函数

    /*******************************************************************************
    功能描述:	根据若干字节获得累加和校验码
    输入参数:	*pData:	源数据指针
    			len:	数据字节数
    函数说明:	计算所得累加和校验Sum
    *******************************************************************************/
    void Fetch_Sum(uint8_t *pData, uint8_t len)
    {
    	uint16_t Sum = 0;
    	while(len--)
    	{
    		Sum += *pData;
    		pData++;
    	}
    	*pData	= (uint8_t)(Sum >> 8);
    	pData++;
    	*pData	= (uint8_t)Sum;
    }
    

  • 2.写 E2 函数(备份区 + 生成校验和)

    
    /********************************************************************
    * 函数名:EEPROM_WriteVariable
    * 参数:  Addr  : 变量在EEPROM中地址 
    * 		 *pData:要写的缓存 
    * 		 Length:长度
    * 用途: 带校验写变量
    ********************************************************************/
    void EEPROM_WriteVariable(uint16_t Addr, uint8_t *pData, uint8_t Length)
    {
    	uint16_t addr_temp[2] = {0};
    	uint8_t temp[Len_MaxVariable + 2];			//最大长度数据 + 2校验位
    	addr_temp[0] = Addr;						//E2主区数据地址
    	addr_temp[1] = Addr + EEPROM_BackUp;		//E2备份区数据地址
    	
    	// 关闭外部中断 并 清除外部中断标志位
    	EXTI->IMR &= ~(EXTI_Line1);
    	EXTI_ClearFlag(EXTI_Line1);
    	
    	CopyBuff(temp, pData, Length);                 //将要写的缓存复制到temp临时缓存中
    	Fetch_Sum(temp, Length);                       //累加获得校验码
    	
    	delay_ms(5);
    	EEPROM_WritePage(addr_temp[0], temp, Length + 2);   //将数据写入E2主区
    	delay_ms(5);  
    	EEPROM_WritePage(addr_temp[1], temp, Length + 2);   //将数据写入E2备份区
    	
    	// 打开外部中断
    	EXTI->IMR |= EXTI_Line1;
    }
    

四、读写 E2 应用实例

uint8_t	temp1[4] = {0x12, 0x34, 0x56, 0x78};
uint8_t	temp2[4] = {0};

// 写E2
EEPROM_WriteVariable(EEAddr_Page(100), temp1, 4);

delay_ms(10);		//进行连续操作读写E2时,中间需要增加时间间隔5 ~ 10ms

// 读E2
EEPROM_ReadVariable(EEAddr_Page(100), temp2, 4);

printf("\n\r %02x", temp2);

五、小结

  • 欢迎纠正
  • ☆⌒(*^-゜)v THX!!
  • 码字不易,记得点小心心 ( •̀ ω •́ )✧
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小肥丸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值