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

文章目录

  • 前言
  • 一、宏定义
  • 二、读 E2 函数 (备份区+校验判断)
    • 1.校验和计算及检测函数
    • 2.读 E2 函数(备份区 + 校验判断)
  • 三、写 E2 函数(备份区+校验)
    • 1.校验和生成函数
    • 2.写 E2 函数(备份区 + 生成校验和)
  • 四、读写 E2 应用实例
  • 五、小结


前言

  • 关于此文一些名词术语不太理解的,可以去看我这篇博文
    《STM32F10x_模拟I2C读写EEPROM(1)》

  • 模拟I2C读写函数,可以去看我这篇博文
    《STM32F10x_模拟I2C读写EEPROM(2)
    (切换SDA方向 + 读ACK位 + 完整代码)》

  • E2的中文资料可以到我博客资源里下载,没有积分下载的,可以评论Ding我o( ̄▽ ̄)ブ

一、宏定义


// 此文的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!!
  • 码字不易,记得点小心心 ( •̀ ω •́ )✧

你可能感兴趣的:(#,模拟I2C读写EEPROM,-,笔记,stm32,嵌入式硬件,eeprom,单片机)