#include "eeprom_flash.h" const uint8_t EEPROM_Flash_Flag[4] = {0x55,0xAA,0x55,0xAA}; FLASH_EraseInitTypeDef EEPROM_AreaEraseInitStruct; TrueOrFalse_Flag_Struct_t IsFirstPowerOn_FlashFlag; TrueOrFalse_Flag_Struct_t IsPowerOffDataBkp_SaveFlag = FALSE; /****************************局部函数定义******************************/ //指定地址写入指定长度数据类型为32bit数据 static 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; } //数据写入 static void CopyDataToEEPROM_Flash(TrueOrFalse_Flag_Struct_t Flag_FirstPowerOn) { uint32_t Temp_32[2]; //Flash页擦除 EEPROM_Flash_Erase();//约102ms //默认值初始化,未初始化部分存储随机值 if(Flag_FirstPowerOn == TRUE) { //电机型号 strncpy(MC_VerInfo.Mode, (char*)"MOTINOVA. ", 16); //电机序列号 strncpy(MC_VerInfo.SN_Num, (char*)"0000000000000000", 16); //生产信息 strncpy(MC_MacInfo.Manufacturer, (char*)"TTIUM. ", 8); //生产信息 strncpy(MC_MacInfo.MacAddr, (char*)"WUHAN. ", 8); strncpy(MC_MacInfo.MacDate, (char*)"20191101", 8); } //写入数据 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);//生产信息 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO1, (uint8_t*)UserString1, 16);//用户自定义字符串1 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO2, (uint8_t*)UserString2, 16);//用户自定义字符串1 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO3, (uint8_t*)UserString3, 16);//用户自定义字符串1 //写入标志 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); } static void CopyDataFromEEPROM_Flash(void) { uint8_t Data_Buf[64]; int8_t Error_OK; //读取型号 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MODE, Data_Buf, 16); if(Error_OK == 0) { memcpy(MC_VerInfo.Mode, Data_Buf, 16); } //读取序列号 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_SN, Data_Buf, 16); if(Error_OK == 0) { memcpy(MC_VerInfo.SN_Num, Data_Buf, 16); } //读取生产信息 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MAC_INFO, Data_Buf, 32); if(Error_OK == 0) { memcpy(MC_MacInfo.Manufacturer, Data_Buf, 32); } //读取自定义字符串1 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO1, Data_Buf, 16); if(Error_OK == 0) { memcpy(&UserString1, Data_Buf, 16); } //读取自定义字符串2 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO2, Data_Buf, 16); if(Error_OK == 0) { memcpy(&UserString2, Data_Buf, 16); } //读取自定义字符串3 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO3, Data_Buf, 16); if(Error_OK == 0) { memcpy(&UserString3, Data_Buf, 16); } //读取掉电临时保存的数据 Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP_FLAG, Data_Buf, 4); if(Error_OK == 0) { if(strncmp("FLAG", (char*)Data_Buf, 4) == 0) //关机前进行过存储 { Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP, Data_Buf, 40); if(Error_OK == 0) { memcpy((uint8_t*)&MC_PowerOffBkp.ODO_Km, Data_Buf, 40); IsPowerOffDataBkp_SaveFlag = TRUE; } } } } /****************************全局函数定义******************************/ //擦除数据 void EEPROM_Flash_Erase(void) { uint32_t PageError; EEPROM_AreaEraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EEPROM_AreaEraseInitStruct.PageAddress = EEPROM_FLASH_BEGIN_ADDRESS; EEPROM_AreaEraseInitStruct.NbPages = (EEPROM_FLASH_END_ADDRESS - EEPROM_FLASH_BEGIN_ADDRESS + 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[8], CRC_Data, CRC_Result; uint8_t CRC_Buf[40], i; Length = Length >> 2;//按照32bit读取 for(i=0; i> 24) & 0xFF); CRC_Buf[4 * i + 1] = (uint8_t)((DataTemp32[i] >> 16) & 0xFF); CRC_Buf[4 * i + 2] = (uint8_t)((DataTemp32[i] >> 8) & 0xFF); CRC_Buf[4 * i + 3] = (uint8_t)(DataTemp32[i] & 0xFF); } CRC_Data = *(__IO uint32_t*)(FlashAddress + Length * 4); CRC_Result = CRC32_Calculate(CRC_Buf, i * 4); if((CRC_Data - CRC_Result) == 0) { memcpy(Data, CRC_Buf, 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, DataBuf[65]; 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(); IsFirstPowerOn_FlashFlag = FALSE; } else//数据无效 { IsFirstPowerOn_FlashFlag = TRUE; CopyDataToEEPROM_Flash(IsFirstPowerOn_FlashFlag); IsFirstPowerOn_FlashFlag = FALSE; } } void EEPROM_Flash_DataUpdate(void) { CopyDataToEEPROM_Flash(IsFirstPowerOn_FlashFlag); }