ZHCADD5A November 2023 – April 2024 TMS320F28P650DH , TMS320F28P650DK , TMS320F28P650SH , TMS320F28P650SK , TMS320F28P659DH-Q1 , TMS320F28P659DK-Q1 , TMS320F28P659SH-Q1
EEPROM_GetValidBank() 函数的功能是查找当前 EEPROM 组和页面。EEPROM_Write() 和 EEPROM_Read() 函数都会调用此函数。GetValidBank 流程展示了搜索当前 EEPROM 组和页面所需的总体流程。
进入此函数时,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 表示。已使用的 EEPROM 组由全部 128 位被设置为 0x5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A 表示。可以根据需要更改这些值。
首先测试空 EEPROM 组。如果遇到此状态,则表示该 EEPROM 组尚未使用,无需进一步搜索。
if(Bank_Status[0] == EMPTY_BANK) // Check for Unused Bank
{
Bank_Counter = i; // Set Bank Counter to number of current page
return; // If Bank is Unused, return as EEPROM is empty
}
如果未遇到空 EEPROM 组,则接下来测试当前 EEPROM 组。如果组是当前 EEPROM 组,则会更新 EEPROM 组计数器,并且页面指针被设置为 EEPROM 组的第一页,以启用对当前页面的测试。然后退出该循环,因为不需要进一步的 EEPROM 组搜索。
if(Bank_Status[0] == CURRENT_BANK && Bank_Status[4] != CURRENT_BANK) // Check for Current Bank
{
Bank_Counter = i; // Set Bank Counter to number of current bank
// Set Page Pointer to first page in current bank
Page_Pointer = Bank_Pointer + 8;
break; // Break from loop as current bank has been found
}
最后,对已使用的 EEPROM 组进行测试。在这种情况下,EEPROM 组已使用,EEPROM 组指针更新到下一个 EEPROM 组,以测试其状态。
// Check for Used Bank
if(Bank_Status[0] == CURRENT_BANK && Bank_Status[4] == CURRENT_BANK)
// If Bank has been used, set pointer to next bank
Bank_Pointer += Bank_Size;
找到当前 EEPROM 组后,需要找到当前页面。一个页面可以具有三种不同的状态:空、当前和已使用。
空页面由 128 个状态位全为 1 (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) 表示。当前 EEPROM 组由前 64 位被设置为 0x5F5F5F5F5F5F5F5F、其余 64 位被设置为 1 表示。已使用的 EEPROM 组由全部 128 位被设置为 0x5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F 表示。可以根据需要更改这些值。
首先会测试组和当前页面。如果页面的当前状态为这两种状态之一,则表示找到了正确的页面,并退出该循环,因为不需要进一步的搜索。
// Check for Blank Page or Current Page
if(Page_Status[0] == BLANK_PAGE)
{
Page_Counter = i; // Set Page Counter to number of current page
break; // Break from loop as current page has been found
}
if (Page_Status[0] == CURRENT_PAGE && Page_Status[4] != CURRENT_PAGE)
{
Page_Counter = i + 1;//Increment Page Counter as one has been used
break; // Break from loop as current page has been found
}
如果页面状态不是这两种状态中的任何一种,则唯一的其他可能性是“已使用的页面”。在这种情况下,页面指针会更新到下一个页面,以测试其状态。
// Check for Used Page
if(Page_Status[0] == CURRENT_PAGE && Page_Status[4] == CURRENT_PAGE)
{
// If page has been used, set pointer to next page
Page_Pointer += EEPROM_PAGE_DATA_SIZE + 8;
}
此时,当前 EEPROM 组和页面已找到,调用函数可以继续运行。最后,此函数将会检查是否所有 EEPROM 组和页面均已使用。这种情况下,需要擦除该扇区。
if (!ReadFlag)
{
if (Bank_Counter == NUM_EEPROM_BANKS - 1 &&
Page_Counter == NUM_EEPROM_PAGES)
{
Erase_Inactive_Unit = 1;
EEPROM_UpdatePageStatus();
EEPROM_UpdateBankStatus();
Erase_Blank_Check = 1;
EEPROM_Erase();
RESET_BANK_POINTER;
RESET_PAGE_POINTER;
}
}
可以通过测试 EEPROM 组和页面计数器来执行该检查。表示已满 EEPROM 的 EEPROM 组和页面的数量取决于应用。如上述代码片段中所示针对当前 EEPROM 组和页面执行测试时,会设置这些计数器。然而,当设置了 Read_Flag 时,不会进行此检查。这是为了防止在从已满 EEPROM 单元读取时过早擦除非活动 EEPROM 单元。
如上方所示,如果存储器已满,则会调用 EEPROM_Erase() 函数,同时 EEPROM 组和页面指针会复位至第一个 EEPROM 组和第一个页面。