文章目录
前言
-
关于此文一些名词术语不太理解的,可以去看我这篇博文
→ 《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!!
- 码字不易,记得点小心心 ( •̀ ω •́ )✧