ZHCAEX4 January   2025 F29H850DM , F29H850TU , F29H859TU-Q1 , F29P589DM-Q1 , F29P589DU-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 1 简介
  5. 2 EEPROM 与片上闪存的区别
  6. 3 概述
    1. 3.1 基本概念
    2. 3.2 单存储单元方法
    3. 3.3 乒乓方法
    4. 3.4 创建 EEPROM 节(页)和页标识
  7. 4 软件说明
    1. 4.1 软件功能和流程
  8. 5 单存储单元仿真
    1. 5.1 用户配置
      1. 5.1.1 EEPROM_Config.h
      2. 5.1.2 F29H85x_EEPROM.c
    2. 5.2 EEPROM 函数
      1. 5.2.1 初始化和设置函数
        1. 5.2.1.1 Configure_Device
        2. 5.2.1.2 EEPROM_Config_Check
      2. 5.2.2 页面模式函数
        1. 5.2.2.1 EEPROM_GetValidBank
        2. 5.2.2.2 EEPROM_UpdateBankStatus
        3. 5.2.2.3 EEPROM_UpdatePageStatus
        4. 5.2.2.4 EEPROM_UpdatePageData
        5. 5.2.2.5 EEPROM_Write_Page
      3. 5.2.3 64 位模式函数
        1. 5.2.3.1 EEPROM_64_Bit_Mode_Check_EOS
        2. 5.2.3.2 EEPROM_Write_64_Bits
      4. 5.2.4 两种模式下使用的函数
        1. 5.2.4.1 EEPROM_Erase
        2. 5.2.4.2 EEPROM_Read
      5. 5.2.5 实用功能
        1. 5.2.5.1 EEPROM_Write_Buffer
        2. 5.2.5.2 Erase_Bank
        3. 5.2.5.3 Set_Protection_Masks
        4. 5.2.5.4 Configure_Protection_Masks
        5. 5.2.5.5 Fill_Buffer
        6. 5.2.5.6 ClearFSMStatus
    3. 5.3 测试示例
  9. 6 乒乓仿真
    1. 6.1 用户配置
      1. 6.1.1 EEPROM_PingPong_Config.h
      2. 6.1.2 F29H85x_EEPROM_PingPong.c
    2. 6.2 EEPROM 函数
      1. 6.2.1 初始化和设置函数
        1. 6.2.1.1 Configure_Device
        2. 6.2.1.2 EEPROM_Config_Check
      2. 6.2.2 页面模式函数
        1. 6.2.2.1 EEPROM_GetValidBank
        2. 6.2.2.2 EEPROM_UpdateBankStatus
        3. 6.2.2.3 EEPROM_UpdatePageStatus
        4. 6.2.2.4 EEPROM_UpdatePageData
        5. 6.2.2.5 EEPROM_Write_Page
      3. 6.2.3 64 位模式函数
        1. 6.2.3.1 EEPROM_64_Bit_Mode_Check_EOS
        2. 6.2.3.2 EEPROM_Write_64_Bits
      4. 6.2.4 两种模式下使用的函数
        1. 6.2.4.1 EEPROM_Erase_Inactive_Unit
        2. 6.2.4.2 EEPROM_Read
        3. 6.2.4.3 EEPROM_Erase_All
      5. 6.2.5 实用功能
        1. 6.2.5.1 EEPROM_Write_Buffer
        2. 6.2.5.2 Erase_Bank
        3. 6.2.5.3 Configure_Protection_Masks
        4. 6.2.5.4 Set_Protection_Masks
        5. 6.2.5.5 Fill_Buffer
        6. 6.2.5.6 ClearFSMStatus
    3. 6.3 测试示例
  10. 7 应用集成
  11. 8 闪存 API
    1. 8.1 闪存 API 检查清单
      1. 8.1.1 使用闪存 API 时的注意事项
  12. 9 源文件清单
  13. 10故障排除
    1. 10.1 一般
  14. 11结语
  15. 12参考资料

EEPROM_GetValidBank

EEPROM_GetValidBank() 函数的功能是查找当前 EEPROM 组和页面。EEPROM_Write_Page() 和 EEPROM_Read() 函数都会调用此函数。GetValidBank 流程展示了搜索当前 EEPROM 组和页面所需的总体流程。

 GetValidBank 流程图 6-1 GetValidBank 流程

进入此函数时,EEPROM 组指针和页面指针被设置为 FIRST_AND_LAST_SECTOR 中指定的第一个扇区的开头:

RESET_BANK_POINTER;
RESET_PAGE_POINTER;     

这些指针的地址在 EEPROM_Config.h 文件中针对所使用的特定器件和 EEPROM 配置进行定义。

接下来,会找到当前 EEPROM 组。如 GetValidBank 流程所示,EEPROM 组可以具有三种不同的状态:空、当前和已使用。

空 EEPROM 组由 128 个状态位全部为 1 (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) 表示。当前 EEPROM 组由最高有效 64 位被设置为 0x5A5A5A5A5A5A5A5A、其余 64 位被设置为 1 (0x5A5A5A5A5A5A5A5AFFFFFFFFFFFFFFFF) 表示。已使用的 EERPOM 组由全部 128 位被设置为 0x5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A 表示。可以根据需要更改这些值。

首先,程序会检查是否有空的 EEPROM 组。如果遇到此状态,则表示该 EEPROM 组尚未使用,无需进一步搜索。

if (Bank_in_Use == EMPTY_BANK)
{
    Bank_Counter = i;
    return;
}

如果未遇到空的 EEPROM 组,则接下来会检查当前状态。如果存在,则会相应地更新 EEPROM 组计数器,并且页面指针被设置为 EEPROM 组的第一页,以启用对当前页面的测试。然后退出该循环,因为不需要进一步的搜索。

if (Bank_in_Use == CURRENT_BANK && Bank_Full != CURRENT_BANK)
{
    Bank_Counter = i;
    Page_Pointer = Bank_Pointer + WRITE_SIZE_BYTES*2;
    break;
}

最后,检查是否有“已使用”状态。在这种情况下,EEPROM 组已使用,EEPROM 组指针更新到下一个 EEPROM 组,以测试其状态。

if (Bank_in_Use == CURRENT_BANK && Bank_Full == CURRENT_BANK)
{
    Bank_Pointer += Bank_Size;
}        

找到当前 EEPROM 组后,需要找到当前页面。一个页面可以具有三种不同的状态:空、当前和已使用。

空页面由 128 个状态位全为 1 (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) 表示。当前页面由最高有效 64 位被设置为 0xA5A5A5A5A5A5A5A5、其余 64 位被设置为 1 (0xA5A5A5A5A5A5A5A5FFFFFFFFFFFFFFFFF) 表示。已使用的页面由全部 128 位被设置为 0xA5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5 表示。可以根据需要更改这些值。

首先查找“空”和“当前”状态。如果页面的当前状态为这两种状态之一,则表示找到了正确的页面,并退出该循环,因为不需要进一步的搜索。

if (Page_in_Use == BLANK_PAGE)
{
    Page_Counter = i;
    break;
}

if (Page_in_Use == CURRENT_PAGE && Page_Full != CURRENT_PAGE)
{
    Page_Counter = i + 1;
    break;
}

如果页面状态不是这两种状态中的任何一种,则唯一的其他可能性是“已使用的页面”。在这种情况下,页面指针会更新到下一个页面,以测试其状态。

Page_Pointer += WRITE_SIZE_BYTES*2 + EEPROM_PAGE_DATA_SIZE;

此时,当前 EEPROM 组和页面已找到,调用函数可以继续运行。最后,此函数将会检查是否所有 EEPROM 组和页面均已使用。这种情况下,需要擦除该扇区。将完整单元中的最后一个组和页面标记为用于完整性,切换活动单元,重新配置写入/擦除保护掩码、并设置 Erase_Inactive_Unit 标志。

if (!ReadFlag && Bank_Counter == NUM_EEPROM_BANKS - 1 && Page_Counter == NUM_EEPROM_PAGES)
{
    EEPROM_UpdatePageStatus();
    EEPROM_UpdateBankStatus();

    EEPROM_ACTIVE_UNIT ^= 1;
    Set_Protection_Masks();
    Erase_Inactive_Unit = 1;

   RESET_BANK_POINTER;
   RESET_PAGE_POINTER;
}

可以通过测试 EEPROM 组和页面计数器来执行该检查。表示已满 EEPROM 的 EEPROM 组和页面的数量取决于应用。如上述代码片段中所示针对当前 EEPROM 组和页面执行测试时,会设置这些计数器。然而,当设置了 Read_Flag 时,不会进行此检查。这是为了防止在从已满 EEPROM 单元读取时过早擦除非活动 EEPROM 单元。