一种eeprom保存参数的方案

eeprom容量分成2份,一份作为常用区,一份作为备份区。

参数保存函数,先写入常用区,再写入备份区。

参数读取函数,先读常用区,成功则退出,不成功则读取备份区,成功则刷新常用区。

系统有多个参数,各个参数分开保存。这种方式的好处是方便扩展,新增参数不会影响到旧参数,缺点是开机加载参数时读取参数的次数多。


#define AT24C256

#ifdef AT24C256
	#define EE_MODEL_NAME		"AT24C256"
	#define EE_DEV_ADDR			0xA0		/* 设备地址 */
	#define EE_PAGE_SIZE		64			/* 页面大小(字节) */
	#define EE_SIZE				(32*1024)	/* 总容量(字节) */
	#define EE_ADDR_BYTES		2			/* 地址字节个数 */
    #define EEP_ADDR_BACKUP_BASE		(16*1024)			/* 备份区起始地址 */
#endif

#define EEPROM_OP_TIME          3

int EEP_Save_Data( uint16_t addr, uint8_t* pdata, uint32_t len )
{
    uint16_t            l_u16WrCRC = 0;
    uint16_t            l_u16DataAddr   = addr;
    uint8_t             l_u8aWrBuff[1024];
    uint8_t             ret,ret1;
    uint8_t             errcnt;

    if(l_u16DataAddr > EE_SIZE) return -1;

    memset(l_u8aWrBuff,0x00,sizeof(l_u8aWrBuff));
    memcpy(l_u8aWrBuff,pdata,len);
    l_u16WrCRC = GetCRC16(l_u8aWrBuff,len);
    l_u8aWrBuff[ len  ] = l_u16WrCRC & 0xff;
    l_u8aWrBuff[ len + 1 ] = l_u16WrCRC >> 8;

    errcnt = 0;
    do
    {
        ret = WriteMultiByteToEEPROM( l_u8aWrBuff, l_u16DataAddr, len+2 );
    }
    while ( ret && ( ++errcnt < EEPROM_OP_TIME ) );

    errcnt = 0;
    do
    {
        ret1 = WriteMultiByteToEEPROM( l_u8aWrBuff, l_u16DataAddr + EEP_ADDR_BACKUP_BASE, len+2 );
    }
    while ( ret1 && ( ++errcnt < EEPROM_OP_TIME ) );

    if( ret != 0 && ret1 != 0 )
    {
        return -2;
    }
    else
    {
        return 0;
    }
}


int EEP_Read_Data( uint16_t addr, uint8_t* pdata, uint32_t len )
{
    uint16_t            l_u16Result = SUCCESS;
    uint16_t            calCRC = 0;
    uint16_t            l_u16RdCRC = 0;
    uint16_t            l_u16DataAddr   = addr;
    uint8_t             l_u8aRdBuff[1024];
    uint8_t             ret,ret1;
    uint8_t             errcnt;
    uint8_t             flag;

    if(l_u16DataAddr > EE_SIZE) return -1;

    memset(l_u8aRdBuff,0x00,sizeof(l_u8aRdBuff));
    errcnt = 0;
    do
    {
        ret = ReadMultiByteFromEEPROM( l_u8aRdBuff, l_u16DataAddr, len+2 );
    }
    while ( ret && ( ++errcnt < EEPROM_OP_TIME ) );

    if( ret == 0 )
    {
        memcpy(pdata,l_u8aRdBuff,len);
        return 0;
    }
    else
    {
        errcnt = 0;
        do
        {
            ret1 = ReadMultiByteFromEEPROM( l_u8aRdBuff, l_u16DataAddr + EEP_ADDR_BACKUP_BASE, len+2 );
        }
        while ( ret1 && ( ++errcnt < EEPROM_OP_TIME ) );
        if(ret1 == 0) 
        {
            memcpy(pdata,l_u8aRdBuff,len);
            errcnt = 0;
            do
            {
                ret = WriteMultiByteToEEPROM( l_u8aRdBuff, l_u16DataAddr, len+2 );
            }
            while ( ret && ( ++errcnt < EEPROM_OP_TIME ) );
            return 0;
        }    
        else
            return -1;
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910659.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL实战训练之,力扣:2020. 无流量的帐户数(递归)

目录 一、力扣原题链接 二、题目描述 三、建表语句 四、题目分析 五、SQL解答 六、最终答案 七、验证 八、知识点 一、力扣原题链接 2020. 无流量的帐户数 二、题目描述 表: Subscriptions ------------------- | Column Name | Type | ------------------- | accoun…

ARM base instruction -- ccmp (immediate)

Conditional Compare (immediate) sets the value of the condition flags to the result of the comparison of a register value and an immediate value if the condition is TRUE, and an immediate value otherwise. 此指令一般出现在 cmp 指令之后&#xff0c;表示双重比…

【支付行业-支付系统架构及总结】

记得第一次看埃隆马斯克&#xff08;Elon Musk&#xff09;讲第一性原理的视频时&#xff0c;深受震撼&#xff0c;原来还可以这样处理复杂的事务。这篇文章也尝试化繁为简&#xff0c;探寻支付系统的本质&#xff0c;讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付…

【系统面试篇】进程和线程类(1)(笔记)——区别、通讯方式、同步、互斥、锁分类

目录 一、问题综述 1. 进程和线程的区别&#xff1f; 2. 进程的状态有哪些&#xff1f; 3. 进程之间的通信方式? &#xff08;1&#xff09;管道 &#xff08;2&#xff09;消息队列 &#xff08;3&#xff09;共享内存 &#xff08;4&#xff09;信号量 &#xff08…

Java算法OJ(6)归并分治

目录 1.前言 2.正文 2.1归并分治的概念 2.2计算数组的小和 2.2.1题目 2.2.2示例 2.2.3代码 2.3翻转对 2.3.1题目 2.3.2示例 2.3.3代码 3.小结 1.前言 哈喽大家好吖&#xff0c;今天继续来给大家带来Java算法——归并分治的讲解&#xff0c;学习这篇的前提可以先把…

【网络】自定义协议——序列化和反序列化

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是序列化和分序列&#xff0c;并且自己能手撕网络版的计算器。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不…

Abaqus随机骨料过渡区孔隙三维网格插件:Random Agg ITZ Pore 3D (Mesh)

插件介绍 Random Agg ITZ Pore 3D (Mesh) V1.0 - AbyssFish 插件可在Abaqus内参数化建立包含水泥浆基体、粗细骨料、界面过渡区&#xff08;ITZ&#xff09;、孔隙在内的多相材料混凝土细观背景网格模型。 模型说明 插件采用材料映射单元的方式&#xff0c;将不同相材料赋值…

【含开题报告+文档+源码】基于SpringBoot+Vue智能居民健康检测系统设计与实现

开题报告 随着社会发展和人民生活水平的提高&#xff0c;人们对健康生活的要求越来越高。而广大居民由于条件限制&#xff0c;存在着健康管理服务不足的问题。本文基于JavaWeb技术&#xff0c;设计并实现了一种居民健康检测系统。首先&#xff0c;本文对该平台的需求进行了分析…

基于Multisim8路抢答器电路仿真电路(含仿真和报告)

【全套资料.zip】8路抢答器电路仿真电路Multisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 1.设计数字式抢答器&#xff0c;每组选手具有一个抢答按钮。 2.电路具有第一抢答信号的鉴别和锁存…

Java 网络编程(一)—— UDP数据报套接字编程

概念 在网络编程中主要的对象有两个&#xff1a;客户端和服务器。客户端是提供请求的&#xff0c;归用户使用&#xff0c;发送的请求会被服务器接收&#xff0c;服务器根据请求做出响应&#xff0c;然后再将响应的数据包返回给客户端。 作为程序员&#xff0c;我们主要关心应…

人工智能学习--归一化(Normalization)

概念 归一化是数据预处理中将不同量纲的特征数据缩放至同一尺度的过程&#xff0c;使特征值落在同一范围&#xff08;如[0, 1]或[-1, 1]&#xff09;。归一化有助于消除量纲影响&#xff0c;提升算法的收敛速度和模型稳定性&#xff0c;尤其在梯度下降和距离计算等算法中尤为重…

高校实验室安全巡检系统设计与实现(源码+定制+开发)高校实验室巡检系统、实验室安全管理平台、实验室安全监控系统、智能实验室巡查系统、高校实验室风险管理

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

解决程序因缺少xinput1_3.dll无法运行的有效方法,有效修复丢失xinput1_3.dll

如果你的电脑在运行某些应用程序或游戏时提示“xinput1_3.dll丢失”或“找不到xinput1_3.dll”的错误消息&#xff0c;那么很可能是因为你的系统中缺少这个重要的DLL文件而导致的问题。那么电脑出现xinput1_3.dll丢失的问题时有哪些方法进行修复呢&#xff1f; 如何确定电脑是否…

论文笔记(五十四)pi0: A Vision-Language-Action Flow Model for General Robot Control

π0: A Vision-Language-Action Flow Model for General Robot Control 文章概括摘要I. INTRODUCTIONII. RELATED WORKIII. OVERVIEWIV. π 0 \pi_0 π0​模型V. 数据收集和培训配方A. 预训练和后训练B. 语言和高级策略C. 机器人系统细节 VI. 实验评估A. 基础模型评估B. 遵循语…

Redis 基础数据改造

优质博文&#xff1a;IT-BLOG-CN 一、服务背景 基础数据查询服务&#xff1a;提供航司&#xff08;5000家&#xff09;、机场&#xff08;4000&#xff09;、票台&#xff08;40000&#xff09;、城市&#xff08;4000&#xff09;等基础数据信息。 痛点一&#xff1a;因为基…

C# String系列(3):StringBuilder有诸多优势,它能代替String吗?

前言 嗨&#xff0c;大家好&#xff01; 之前我们在文章《C# String 类型&#xff1a;那些你可能不知道的秘密》分享了 C# String 类型的一些小秘密和小技巧&#xff0c;其中提到一个性能提升的小贴士&#xff1a;在拼接字符串时&#xff0c;使用 StringBuilder 替代 String。…

6.1、实验一:静态路由

源文件获取&#xff1a;6.1_实验一&#xff1a;静态路由.pkt: https://url02.ctfile.com/f/61945102-1420248902-c5a99e?p2707 (访问密码: 2707) 一、目的 理解路由表的概念 会使用基础命令 根据需求正确配置静态路由 二、准备实验 1.实验要求 让PC0、PC1、PC2三台电脑…

嵌入式linux中设备树控制硬件的方法

大家好,今天主要给大家分享一下,如何使用linux系统下的设备树进行硬件控制方法。 第一:linux系统中设备树驱动LED原理 在linux系统中可以使用设备树向Linux内核传递相关的寄存器地址,linux驱动中使用OF函数从设备树中获取所需的属性值,然后使用获取到的属性值来初始化相关…

一文解秘Rust如何与Java互操作

本博客所有文章除特别声明外&#xff0c;均采用CC BY-NC-SA 4.0许可协议。转载请注明来自 唯你 使用场景 JAVA 与 Rust 互操作让 Rust 可以背靠 Java 大生态来做更多事情&#xff0c;而 Java 也可以享受 Rust 语言特性的内存安全&#xff0c;所有权机制&#xff0c;无畏并发。…

【贪心算法】No.1---贪心算法(1)

文章目录 前言一、贪心算法&#xff1a;二、贪心算法示例&#xff1a;1.1 柠檬⽔找零1.2 将数组和减半的最少操作次数1.3 最⼤数1.4 摆动序列1.5 最⻓递增⼦序列1.6 递增的三元⼦序列 前言 &#x1f467;个人主页&#xff1a;小沈YO. &#x1f61a;小编介绍&#xff1a;欢迎来到…