#include "eeprom_flash.h" #include "enviolo_can.h" const uint8_t EEPROM_Flash_Flag[4] = {0x55,0xAA,0x55,0xAA}; FLASH_EraseInitTypeDef EEPROM_AreaEraseInitStruct; TrueOrFalse_Flag_Struct_t IsPowerOffDataBkp_SaveFlag = FALSE; TrueOrFalse_Flag_Struct_t IsFlashSaveDataUpdate = FALSE; /****************************局部变量定义******************************/ uint8_t Flash_ReadDataBuf[256]; uint32_t Flash_WriteDataBuf[256]; /****************************全局函数定义******************************/ //数据写入 void CopyDataToEEPROM_Flash(void) { uint32_t Temp_32[2]; //Flash页擦除 EEPROM_Flash_Erase(EEPROM_FLASH_BEGIN_ADDRESS, EEPROM_FLASH_END_ADDRESS);//约102ms //写入型号 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_MODE, (uint8_t*)MC_VerInfo.Mode, 16); //写入序列号 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_SN, (uint8_t*)MC_VerInfo.SN_Num, 16); //写入生产信息 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_MAC_INFO, (uint8_t*)MC_MacInfo.Manufacturer, 32); //写入自定义字符串1 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO1, (uint8_t*)UserString1, 16); //写入自定义字符串2 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO2, (uint8_t*)UserString2, 16); //写入自定义字符串3 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO3, (uint8_t*)UserString3, 16); //写入自动变速器控制参数 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_GEARBOX_PARAMS, (uint8_t*)&GearBox_OBC_SetParams.GearNum, 8); //写入电池放电曲线参数 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_BATTERY_PARMAS, (uint8_t*)&BatteryCellInfo.DesignCap, sizeof(BatterCellInfo_Struct_t)); //写入产品标签信息 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_TAG_INFO, (uint8_t*)MC_TagInfo, 32); //写入标志 Temp_32[0] = (EEPROM_Flash_Flag[0] << 24) + (EEPROM_Flash_Flag[1] << 16) + (EEPROM_Flash_Flag[2] << 8) + EEPROM_Flash_Flag[3]; Temp_32[1] = CRC32_Calculate((uint8_t*)EEPROM_Flash_Flag, 4); FLASH_Write(EEPROM_FLASH_ADDR_FLAG, Temp_32, 2); } //数据读取 void CopyDataFromEEPROM_Flash(void) { int8_t Error_OK; //读取型号 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MODE, Flash_ReadDataBuf, 16); if(Error_OK == 0) { memcpy(MC_VerInfo.Mode, Flash_ReadDataBuf, 16); } //读取序列号 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_SN, Flash_ReadDataBuf, 16); if(Error_OK == 0) { memcpy(MC_VerInfo.SN_Num, Flash_ReadDataBuf, 16); } //读取生产信息 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MAC_INFO, Flash_ReadDataBuf, 32); if(Error_OK == 0) { memcpy(MC_MacInfo.Manufacturer, Flash_ReadDataBuf, 32); } //读取自定义字符串1 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO1, Flash_ReadDataBuf, 16); if(Error_OK == 0) { memcpy(&UserString1, Flash_ReadDataBuf, 16); } //读取自定义字符串2 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO2, Flash_ReadDataBuf, 16); if(Error_OK == 0) { memcpy(&UserString2, Flash_ReadDataBuf, 16); } //读取自定义字符串3 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO3, Flash_ReadDataBuf, 16); if(Error_OK == 0) { memcpy(&UserString3, Flash_ReadDataBuf, 16); } //读取自动变速器控制参数 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_GEARBOX_PARAMS, Flash_ReadDataBuf, 8); if(Error_OK == 0) { memcpy((uint8_t*)&GearBox_OBC_SetParams.GearNum, Flash_ReadDataBuf, 8); } //读取电池放电曲线参数 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_BATTERY_PARMAS, Flash_ReadDataBuf, sizeof(BatterCellInfo_Struct_t)); if(Error_OK == 0) { memcpy((uint8_t*)&BatteryCellInfo.DesignCap, Flash_ReadDataBuf, sizeof(BatterCellInfo_Struct_t)); } //读取产品标签信息 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_TAG_INFO, Flash_ReadDataBuf, 32); if(Error_OK == 0) { memcpy(&MC_TagInfo, Flash_ReadDataBuf, 32); } } //指定地址写入指定长度数据类型为32bit数据 void FLASH_Write(uint32_t FlashAddress, uint32_t* Data, uint16_t DataLength) { uint32_t i = 0; HAL_FLASH_Unlock(); for (i = 0; (i < DataLength) && (FlashAddress <= (EEPROM_FLASH_END_ADDRESS-4)); i++) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(Data + i)) == HAL_OK) { FlashAddress += 4; } else { // Error occurred while writing data in Flash memory HAL_FLASH_Lock(); return; } } HAL_FLASH_Lock(); return; } //擦除数据 void EEPROM_Flash_Erase(uint32_t BeginAddress, uint32_t EndAddress) { uint32_t PageError; EEPROM_AreaEraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EEPROM_AreaEraseInitStruct.PageAddress = BeginAddress; EEPROM_AreaEraseInitStruct.NbPages = (EndAddress - BeginAddress + 1) / 1024; HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); HAL_FLASHEx_Erase(&EEPROM_AreaEraseInitStruct, &PageError); HAL_FLASH_Lock(); HAL_Delay(100); } //指定地址读取指定长度数据类型为8bit数据 int8_t ReadDataFromEEPROM_Flash(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数 { uint32_t DataTemp32, CRC_Data, CRC_Result; uint8_t i; Length = Length >> 2;//按照32bit读取 for(i=0; i> 24) & 0xFF); Flash_ReadDataBuf[4 * i + 1] = (uint8_t)((DataTemp32 >> 16) & 0xFF); Flash_ReadDataBuf[4 * i + 2] = (uint8_t)((DataTemp32 >> 8) & 0xFF); Flash_ReadDataBuf[4 * i + 3] = (uint8_t)(DataTemp32 & 0xFF); } CRC_Data = *(__IO uint32_t*)(FlashAddress + Length * 4); CRC_Result = CRC32_Calculate(Flash_ReadDataBuf, i * 4); if((CRC_Data - CRC_Result) == 0) { memcpy(Data, Flash_ReadDataBuf, Length * 4); return 0; } else { return -1; } } //指定地址写入指定长度数据类型为8bit数据,并写入crc校验码 void SaveDataToEEPROM_Flash(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数 { uint32_t CRC_Result; uint8_t PakageNum, i; PakageNum = Length / 4; //数据组包成32bit,最后一包存储CRC校验结果 for(i=0; i> 24; DataBuf[1] = Flag >> 16; DataBuf[2] = Flag >> 8; DataBuf[3] = Flag & 0xFF; FlagResult = CRC32_Calculate(DataBuf, 4); //判断数据是否有效 if((FlagResult - FlagCrc) == 0) //数据有效 { CopyDataFromEEPROM_Flash(); } else //数据无效,写入默认参数 { CopyDataToEEPROM_Flash(); } } void EEPROM_Flash_DataUpdate(TrueOrFalse_Flag_Struct_t* IsUpdateFlag) { if(*IsUpdateFlag == TRUE) { CopyDataToEEPROM_Flash(); *IsUpdateFlag = FALSE; } } TrueOrFalse_Flag_Struct_t EEPROM_Flash_TempCheck(void) { int8_t Error_OK; //读取掉电临时保存的数据 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP_FLAG, Flash_ReadDataBuf, 4); if(Error_OK == 0) { if(strncmp("FLAG", (char*)Flash_ReadDataBuf, 4) == 0) //关机前进行过存储 { Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP, Flash_ReadDataBuf, 40); if(Error_OK == 0) { memcpy((uint8_t*)&MC_PowerOffBkp.ODO_Km, Flash_ReadDataBuf, 40); return TRUE; } } } return FALSE; }