stm32模拟eeprom要实现flash数据页转存,实现函数为
1 /** 2 * @brief Transfers last updated variables data from the full Page to 3 * an empty one. 4 * @param VirtAddress: 16 bit virtual address of the variable 5 * @param Data: 16 bit data to be written as variable value 6 * @retval Success or error status: 7 * - FLASH_COMPLETE: on success 8 * - PAGE_FULL: if valid page is full 9 * - NO_VALID_PAGE: if no valid page was found 10 * - Flash error code: on write Flash error 11 */ 12 uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
这个函数的过程为:
1. 得到当前可读有效页,并设置其为oldPage,另一页为NewPage。
2. 给NewPage设置RECEIVE_DATA状态
3.初始化写地址 切换到接收页
4. 写一个当前要保存的数据,如果单纯发起一次转存,则随意保存一个数据。
5. 读出除第三步保存过的所有要保存的变量数据,保存到NewPage中。
6. 擦除OldPage(执行时间15ms-2s,根据扇区大小而定(1K~128K))
7. 给NewPage设置VALID_PAGE状态。
第5步中 Get the valid Page end Address
1 if((PageStatus0 == RECEIVE_DATA)||(PageStatus1 == RECEIVE_DATA))//当页传输的时候把valid Page end Address切换到可读有效页的最后 2 { 3 Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE)); 4 } 5 else 6 { 7 Address=CurWrAddress-2; 8 }
转存完成后的各页的状态:NewPage:VALID_PAGE;
OldPage:ERASED;
但是在转存过程中系统断电,则各页的状态可能出现
1.NewPage:ERASED; OldPage:VALID_PAGE; 这种情况发生在EE_PageTransfer函数执行到第二步之前系统掉电。那么这次转存过程就当没有发生过,要保存的那个数据变量也得不到保存。
2.NewPage:RECEIVE_DATA; OldPage:VALID_PAGE; 这种情况发生在EE_PageTransfer函数执行到第六步之前系统掉电。
3.NewPage:RECEIVE_DATA; OldPage:ERASED; 这种情况发生第六步执行过程中系统掉电。
主要讨论第2、3中情况下开机初始化eeprom的时候处
1 //NewPage:RECEIVE_DATA; OldPage:VALID_PAGE; 2 InitCurrWrAddress();//初始化写地址
2 //这里NewPage为PAGE1 OldPage为Page0
3 4 /* Transfer data from Page0 to Page1 */ 5 for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++) 6 { 7 if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) 8 { 9 x = VarIdx; 10 } 11 if (VarIdx != x) 12 { 13 /* Read the last variables' updates */ 14 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); 15 /* In case variable corresponding to the virtual address was found */ 16 if (ReadStatus != 0x1) 17 { 18 /* Transfer the variable to the Page1 */ 19 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); 20 /* If program operation was failed, a Flash error code is returned */ 21 if (EepromStatus != FLASH_COMPLETE) 22 { 23 return EepromStatus; 24 } 25 } 26 } 27 }//for (VarIdx... 28 /* Mark Page1 as valid */ 29 FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE); 30 /* If program operation was failed, a Flash error code is returned */ 31 if (FlashStatus != FLASH_COMPLETE) 32 { 33 return FlashStatus; 34 } 35 /* Erase Page0 */ 36 FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE); 37 /* If erase operation was failed, a Flash error code is returned */ 38 if (FlashStatus != FLASH_COMPLETE) 39 { 40 return FlashStatus; 41 }
过程:
1.读出除第一个位置保存过的所有要保存的变量数据,保存到NewPage中。
2. 把RECEIVE_DATA状态改为VALID_PAGE
3. 擦除OldPage。
1 //NewPage:RECEIVE_DATA; OldPage:ERASED;OldPage:Page0 NewPage:Page1 2 /* Erase Page0 */ 3 FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE); 4 /* If erase operation was failed, a Flash error code is returned */ 5 if (FlashStatus != FLASH_COMPLETE) 6 { 7 return FlashStatus; 8 } 9 /* Mark Page1 as valid */ 10 FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS,VALID_PAGE); 11 /* If program operation was failed, a Flash error code is returned */ 12 if (FlashStatus != FLASH_COMPLETE) 13 { 14 return FlashStatus; 15 }
第三种情况下
1. 擦除OldPage
2. 把RECEIVE_DATA状态改为VALID_PAGE