FLASH仿真EEPROM---基于智芯Z20K11XM

news2024/11/18 3:41:00

一、介绍

        电可擦和可编程只读存储器(EEPROM)可以对字节或字编程和擦除。EEPROM中的数据即使断电也能保持,但Z20K1xx芯片不含EEPROM。然而,闪存可以通过EEPROM仿真软件来模拟EEPROM。Z20K1xx包含两个flash阵列。编程和擦除操作可以在一个数组上进行,同时在另一个数组上执行代码。     

二、存储原理

        EEPROM仿真包含两个或多个扇区,每个扇区都包含一组闪存扇区。只有一个扇区被选为活动块。存储在活动扇区中的记录列表用于访问数据。每条记录都有一个ID,用来区别于其他记录。记录是一组变量。数据记录的长度是可变的。

        记录按顺序编入活动扇区。为了更新记录,软件将新版本的记录写入活动扇区中下一个可用的位置。当读取记录时,软件检索具有匹配ID的最近写入的记录。当活动扇区没有足够的空间容纳新记录时,软件将活动扇区内的所有有效记录复制到其他EE扇区之一。这个新扇区成为活动扇区,之前的活动扇区失效。由于旧记录在交换期间被清除,新的活动扇区应该有空间用于记录更新。交换后,新记录将被写入新的活动扇区。 后续会详细描述,这一交换原理。

三、内存组成

下图为扇区的内存组成列表图包含扇区+记录+数据存储区。

1.扇区

每个扇区包含一个扇区报头,它包括以下部分

sectorlD:扇区标识。每当有一个新的扇区,这个数字就增加1变得活跃。它从1开始。sectorlD最大的部门是活跃的部门。
sectorstart address:扇区起始地址扇区大小:扇区的大小,以字节为单位。

checksum:扇区id、扇区起始地址和扇区大小字段之和。

sector valid flag:扇区的有效标志,如果等于一个特殊的值,则表示该扇区有效

sector invalid flag:扇区的无效标志,如果等于特殊值,则表示该扇区为失效。

2.记录

每条记录包含一个记录头,它包括以下部分:

recordlD:记录的标识。
data address:记录的数据地址
record size:记录大小(以字节为单位)。
check sum:recordID、数据地址和记录大小字段之和。
record valid flag:记录的有效标志,如果它等于一个特殊值,则该记录是有效的。

record invalid flag:记录的无效标志,如果它等于一个特殊值,则该记录无效。

 四、扇区交换

        前面提到过存储的原理实际就是活动扇区的交换,实际上扇区的交换就是在活动扇区满足以下这三点时:

①当活动扇区没有足够的空间来写入新记录时

②当在EE初始化期间检测到无效记录头时(可选)。

③当最后一个记录头无效时。

把所有的有效记录从一个活动扇区复制到另一个扇区,下图举例了三个扇区的交换: 

初始时,Sector0是活动扇区,

第一次交换后,Sector0变为“invalid”,Sector1变为活动扇区。

第二次交换后,Sector1变为“invalid”,Sector2变为活动扇区。

再了解了存储结构和交换原理后我们就可以理解代码并写一段demo例子了。 

五、代码编程

1.结构体初始化

static uint32_t cacheTable[EE_CACHE_RECORD_NUM];
static EE_cache_t cacheConf =
{
    cacheTable,               /* cache 起始地址 */
    EE_CACHE_RECORD_NUM       /* cache 缓存大小 */
};

/* 扇区0配置 */
static const EE_SectorConfig_t sectorConf0 =
{
    EE_SECTOR_0_ADDR,          /* 起始地址 */
    EE_SECTOR_SIZE,            /* 大小 */
};

/* 扇区1配置 */
static const EE_SectorConfig_t sectorConf1 =
{
    EE_SECTOR_1_ADDR,          /* 起始地址 */
    EE_SECTOR_SIZE,            /* 大小 */
};

/* 扇区2配置 */
static const EE_SectorConfig_t sectorConf2 =
{
    EE_SECTOR_2_ADDR,          /* 起始地址 */
    EE_SECTOR_SIZE,            /* 大小 */
};

/* 扇区配置数组 */
static const EE_SectorConfig_t* sectorConfig[EE_SECTOR_NUM] =
{
    &sectorConf0,
    &sectorConf1, 
    &sectorConf2, 
};

/* EEPROM配置 */
EE_Config_t eeConf =
{
    .sectorNum = EE_SECTOR_NUM,  /* 扇区数量 */
    .sectors = sectorConfig,     /* 扇区配置 */
    .cacheEn = ENABLE,           /* cache 使能 */
    .cTable = &cacheConf,        /* cache 结构体 */
    .busyFlag = RESET,
    .maxRecordId = EE_MAX_RECORD_ID,         /* 最大记录ID */
};

2.系统初始化

static void system_init(void)
{  
    WDOG_Config_t wdogCfg = 
    {
        .winEnable = DISABLE,
        .wait = DISABLE,
        .stop = DISABLE,
        .debug = DISABLE,
        .windowValue = 0,
        .timeoutValue = 9600,
        .clkSource = WDOG_LPO_CLOCK,
        .testMode = WDOG_TST_NORMAL,        
    };
    
    CLK_SetClkDivider(CLK_CORE, CLK_DIV_1);
    CLK_SetClkDivider(CLK_BUS, CLK_DIV_1);
    CLK_SetClkDivider(CLK_SLOW, CLK_DIV_8);
    
    if(ERR == WDOG_Init(&wdogCfg))
    {
        ErrorTrap();
    }
    
    if(ERR == WDOG_Enable())
    {
        ErrorTrap();
    }
}

3.初始化EEPROM

EEPROM仿真初始化,最多尝试三次,错误处理判断

while ((i < 3U) && (ret != EE_OK))
{
    ret = EE_Init(&eeConf, ENABLE, &CallBack);
    i++;
}
if(ret != EE_OK)
{
   ErrorTrap();
}

4.写入数据到EEPROM

        写入数据到EEPROM,每个记录的ID从0到最大记录ID(EE_MAX_RECORD_ID),数据大小从1字节到缓冲区大小(BUFFER_SIZE),验证写入的数据,确保读取的数据与写入的数据一致。 

    for(id = 0U; id <= eeConf.maxRecordId; id++)
    {
        size = id + 1U;
        if(size > BUFFER_SIZE)
        {
            size = BUFFER_SIZE;
        }
        /* Init buffer*/
        for (i = 0; i < size; i++)
        {
            buffer[i] = (uint8_t)(i + id);
        }

        ret = EE_WriteRecord(&eeConf,id, size, buffer,0, CallBack);
        if(ret != EE_OK)
        {
            /* if writing fails, re-initialize and try again */
            ret = EE_Init(&eeConf, ENABLE, &CallBack);
            if(ret != EE_OK)
            {
                ErrorTrap();
            }
            else
            {
                ret = EE_WriteRecord(&eeConf,id, size, buffer, 0, CallBack);
                if(ret != EE_OK)
                {
                    /* still error after reinitialization */
                    ErrorTrap();
                }
            } 
        }
        
        for (i = 0; i < BUFFER_SIZE; i++)
        {
            buffer[i] = 0U;
        }

        ret = EE_ReadRecord(&eeConf,id,size,buffer,&readOutSize,CallBack);
        if(ret != EE_OK)
        {
            ErrorTrap();
        }
        else
        {
            if(size != readOutSize)
            {
                ErrorTrap();
            }
                    
            for(i = 0; i < readOutSize; i++)
            {
                if(buffer[i] != i + id)
                {
                    ErrorTrap();
                }
            }
        }
    }

5.验证写入的数据

验证写入的数据,确保读取的数据与写入的数据一致。

    ret = EE_DeleteRecord(&eeConf,EE_TEST_RECORD_ID,CallBack);
    if(ret != EE_OK)
    {
        ErrorTrap();
    }

    for(i = 0; i < BUFFER_SIZE; i++)
    {
        buffer[i] = 0;
    }
    size = BUFFER_SIZE;
    ret = EE_ReadRecord(&eeConf,EE_TEST_RECORD_ID,size,buffer,&readOutSize,

6.验证删除操作

    if(ret != EE_ERROR_DATA_NOT_FOUND)
    {
        ErrorTrap();
    }
    while(true)
    {
        CallBack();
    }

7.回调函数与错误处理函数

void CallBack(void);
static void ErrorTrap(void);

void CallBack(void)
{
    WDOG_Refresh();
}


static void ErrorTrap(void)
{
    while(true)
    {
        CallBack();
    }
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring注解源码解析

一、Spring IOC常用注解 1、用于Bean申明的注解 2、用于定义Bean配置的注解 3、其他用途的注解 二、基于注解容器AnnotationConfigApplicationContext AnnotationConfigApplicationContext的其中一个构造方法&#xff0c;传入Java config类&#xff0c;refresh过程实例化Bean…

大模型时代下的技术变革:训练、负载、部署、效率、安全……都遇到了新挑战?

随着互联网的快速发展&#xff0c;AI 大模型算的上是当前行业里最“炽手可热”的技术&#xff0c;大模型是 AI 领域的重要发展趋势。大模型需要大量的数据和计算资源&#xff0c;同时也需要强大的应用场景支持&#xff0c;对各行各业都有深远的影响&#xff0c;各厂商开始了“千…

Excel 宏录制与VBA编程 —— 11、工作表及工作簿操作(附:Worksheets与Sheets区别)

代码1 - Worksheets与Sheets区别 Worksheets表示普通工作表;Sheets即可表示普通工作表也可表示图标工作表。 下面模块中代码结果是一样的,大家理解时可结合上面区别说明进行了解 Sub Test()Worksheets("Sheet1").Range("A1").Value 100Sheets("Sheet…

农业四情监测设备——提高农业生产的效率和质量

TH-Q1农业四情监测设备是用于实时监测农业领域的四大关键监测内容的设备&#xff0c;这些内容包括土壤墒情、苗情、病虫情和灾情。以下是关于农业四情监测设备的详细介绍&#xff1a; 主要用于实时测量农田土壤的水分状况。包含土壤湿度传感器、土壤温度传感器等&#xff0c;安…

如何处理优化这个慢查询——Java全栈知识(27)

2 、如何处理优化这个慢查询 如何定位慢查询&#xff1a;1、如何定位慢查询 explain 计划 面试官&#xff1a; 那这个 SQL 语句执行很慢, 如何分析呢&#xff1f; 候选人&#xff1a; 如果一条 sql 执行很慢的话&#xff0c;我们通常会使用 mysql 自动的执行计划 explain 来…

电磁场与电磁波作业题及解析

目录 第一章 1.5 1.8 1.11 1.21 第二章 2.4 2.13 2.27 第三章 3.7 3.8 3.17 3.18 第四章 4.2 4.16 第五章 5.2 第六章 6.9 6.30 第七章 7.3 第一章 1.5 1.8 1.11 1.21 第二章 2.4 2.13 2.27 第三章 3.7 3.8 3.17 3.18 第四章 4.2 4.16 第五章 5.2…

【Python新手入门指南】Linux-conda环境安装与使用参考

文章目录 前言一、conda是什么&#xff1f;二、安装步骤三、使用Conda来管理Python环境1. 创建环境2. 激活环境3. 安装软件包4. 查看环境5. 删除环境&#xff1a;如果您不再需要某个环境&#xff0c;可以使用以下命令将其删除&#xff1a; 前言 如果你是一位经验丰富的Python开…

Windwos +vs 2022 编译openssl 1.0.2 库

一 前言 先说 结论&#xff0c;编译64位报错&#xff0c;查了一圈没找到解决方案&#xff0c;最后换了32位的。 使用qt访问web接口&#xff0c;因为是https&#xff0c;没有openssl库会报错 QNetworkReply* reply qobject_cast<QNetworkReply*>(sender());if (reply){…

开放式耳机哪种好用又实用?开放式耳机必入品牌推荐,内行人分享

随着数码技术的不断推出各种各样的新产品&#xff0c;开放式耳机已经逐渐成为有份音乐发烧友的选择&#xff0c;这类耳机从早期的简单音质发展至今日的高解析度&#xff0c;其技术进步&#xff0c;也吸引了一大批开放式耳机的爱好者&#xff0c;开放式耳机以其开放式的设计&…

分布式光纤测温DTS如何与第三方数据对接?

分布式光纤测温DTS与第三方数据对接可以采用多种方式和接口。常见的接口包括RS485、RJ45网口、继电器接口和RS232接口等&#xff0c;而协议种类更是多达几十种之多。主流的协议包括modbusRTU、modbusTCP、点表协议、南网协议、电力json协议、IEC104和61850协议等。根据不同的需…

巧用SOLIDWORKS进行复杂曲面模型的实体建模

SOLIDWORKS正版软件有实体建模、曲面建模、钣金建模、焊件建模、模具建模等多种建模方式&#xff0c;每种建模方式都有独特的使用环境和场景&#xff0c;如果能灵活使用这些建模命令&#xff0c;就可以起到事半功倍的效果。 如上图所示的模型&#xff0c;通过观察和分析&#x…

【单调栈】1130. 叶值的最小代价生成树

1130. 叶值的最小代价生成树 难度&#xff1a;中等 力扣地址&#xff1a;https://leetcode.cn/problems/minimum-cost-tree-from-leaf-values/description/ 题目内容 给你一个正整数数组 arr&#xff0c;考虑所有满足以下条件的二叉树&#xff1a; 每个节点都有 0 个或是 2 个…

机器视觉光源丨CCS高显色LED光源方案实现精准色彩成像

机器视觉系统中&#xff0c;光源设计作为图像成像效果的关键&#xff0c;今天我们一起来看看自然光领域的光源方案&#xff0c;以CCS光源来说&#xff0c;高显色(自然光)LED光源&#xff0c;使用了实现接近基准光源(太阳光和白炽灯)的自然发光颜色。它主要用于辨色检测、测色检…

如何免费的去使用connectedpapers?

免费使用connectedpapers 1. 打开谷歌浏览器2. 按住ctrlshiftN,进入无痕模式3. 不需要登录&#xff08;也就是访客模式&#xff09;4. 两次用完&#xff0c;关闭无痕模式&#xff08;继续重复步骤 2 - 4&#xff09; 1. 打开谷歌浏览器 2. 按住ctrlshiftN,进入无痕模式 输入网…

软件工程全套学习培训资料,实际优质项目编制及各类建设方案,信息安全,运维资料

目的&#xff1a;规范系统开发流程&#xff0c;提高系统开发效率。 立项申请需求分析方案设计方案评审开发调整测试阶段系统培训试运行测试验收投入使用 所有文档过去进主页获取。 获取方式&#xff1a;本文末个人名片直接获取。 软件资料清单列表部分文档清单&#xff1a;工作…

centOS7网络配置_NAT模式设置

第一步&#xff1a;查看电脑网卡 nat模式对应本地网卡的VMnet 8 &#xff0c;查看对应的IP地址。 第二步&#xff1a;虚拟网络编辑器 打开VMWare&#xff0c;编辑--虚拟网络编辑器&#xff0c;整个都默认设置好了&#xff0c;只需要查看对应的DHCP设置中对应的IP的起始&#…

MySQL数据库(五):事务

MySQL数据库中的事务是一种用来保证一系列操作要么全部成功&#xff0c;要么全部取消的机制。想象一下你去超市购物&#xff0c;拿了很多商品&#xff0c;如果中途发现没带钱包&#xff0c;你可以放弃这次购买&#xff0c;所有商品会回到原位。通过事务&#xff0c;可以确保数据…

智能化改造助力企业高质量发展

引言 背景介绍 在当今全球经济环境中&#xff0c;变化和不确定性已成为常态。企业面临的竞争压力不断增加&#xff0c;市场竞争日益激烈。新兴市场的崛起、技术进步和消费者需求的快速变化&#xff0c;使得传统的商业模式和生产方式面临巨大挑战。为了在这样的环境中保持竞争力…

yarn:终极包管理器指南 - 提高您的项目效率和性能

Yarn使用教程大纲 一、介绍1.1 什么是Yarn1.2 Yarn的优势1.3 Yarn与npm的比较 二、安装Yarn2.1 Windows安装Yarn2.2 macOS安装Yarn2.3 Linux安装Yarn2.4 注意事项 三、初始化项目3.1 在项目中使用Yarn3.2 创建新项目3.3 在已有项目中使用Yarn 四、添加依赖4.1 添加依赖4.1.1 安…

【STM32+FPGA】先进算力+强安全+边缘AI,64位STM32MP2聚焦工业4.0应用

工业应用数字化和智能化程度&#xff0c;是衡量新质生产力的重要标准。STM32最新一代64位微处理器STM32MP2凭借先进算力、丰富接口和高安全性&#xff0c;为高性能和高度互联的工业4.0应用赋能。 STM32MP2四大关键特性&#xff0c;为工业4.0应用赋能 STM32MP2系列的第一颗产品S…