eeprom_flash.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #include "eeprom_flash.h"
  2. const uint8_t EEPROM_Flash_Flag[4] = {0x55,0xAA,0x55,0xAA};
  3. FLASH_EraseInitTypeDef EEPROM_AreaEraseInitStruct;
  4. TrueOrFalse_Flag_Struct_t IsFirstPowerOn_FlashFlag;
  5. TrueOrFalse_Flag_Struct_t IsPowerOffDataBkp_SaveFlag = FALSE;
  6. /****************************局部函数定义******************************/
  7. //指定地址写入指定长度数据类型为32bit数据
  8. static void FLASH_Write(uint32_t FlashAddress, uint32_t* Data, uint16_t DataLength)
  9. {
  10. uint32_t i = 0;
  11. HAL_FLASH_Unlock();
  12. for (i = 0; (i < DataLength) && (FlashAddress <= (EEPROM_FLASH_END_ADDRESS-4)); i++)
  13. {
  14. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(Data + i)) == HAL_OK)
  15. {
  16. FlashAddress += 4;
  17. }
  18. else
  19. {
  20. // Error occurred while writing data in Flash memory
  21. HAL_FLASH_Lock();
  22. return;
  23. }
  24. }
  25. HAL_FLASH_Lock();
  26. return;
  27. }
  28. //数据写入
  29. static void CopyDataToEEPROM_Flash(TrueOrFalse_Flag_Struct_t Flag_FirstPowerOn)
  30. {
  31. uint32_t Temp_32[2];
  32. //Flash页擦除
  33. EEPROM_Flash_Erase();//约102ms
  34. //默认值初始化,未初始化部分存储随机值
  35. if(Flag_FirstPowerOn == TRUE)
  36. {
  37. //电机型号
  38. strncpy(MC_VerInfo.Mode, (char*)"MOTINOVA. ", 16);
  39. //电机序列号
  40. strncpy(MC_VerInfo.SN_Num, (char*)"0000000000000000", 16);
  41. //生产信息
  42. strncpy(MC_MacInfo.Manufacturer, (char*)"TTIUM. ", 8); //生产信息
  43. strncpy(MC_MacInfo.MacAddr, (char*)"WUHAN. ", 8);
  44. strncpy(MC_MacInfo.MacDate, (char*)"20191101", 8);
  45. }
  46. //写入数据
  47. SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_MODE, (uint8_t*)MC_VerInfo.Mode, 16);//型号
  48. SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_SN, (uint8_t*)MC_VerInfo.SN_Num, 16);//序列号
  49. SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_MAC_INFO, (uint8_t*)MC_MacInfo.Manufacturer, 32);//生产信息
  50. SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO1, (uint8_t*)UserString1, 16);//用户自定义字符串1
  51. SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO2, (uint8_t*)UserString2, 16);//用户自定义字符串1
  52. SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO3, (uint8_t*)UserString3, 16);//用户自定义字符串1
  53. //写入标志
  54. Temp_32[0] = (EEPROM_Flash_Flag[0] << 24) + (EEPROM_Flash_Flag[1] << 16) + (EEPROM_Flash_Flag[2] << 8) + EEPROM_Flash_Flag[3];
  55. Temp_32[1] = CRC32_Calculate((uint8_t*)EEPROM_Flash_Flag, 4);
  56. FLASH_Write(EEPROM_FLASH_ADDR_FLAG, Temp_32, 2);
  57. }
  58. static void CopyDataFromEEPROM_Flash(void)
  59. {
  60. uint8_t Data_Buf[64];
  61. int8_t Error_OK;
  62. //读取型号
  63. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MODE, Data_Buf, 16);
  64. if(Error_OK == 0)
  65. {
  66. memcpy(MC_VerInfo.Mode, Data_Buf, 16);
  67. }
  68. //读取序列号
  69. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_SN, Data_Buf, 16);
  70. if(Error_OK == 0)
  71. {
  72. memcpy(MC_VerInfo.SN_Num, Data_Buf, 16);
  73. }
  74. //读取生产信息
  75. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MAC_INFO, Data_Buf, 32);
  76. if(Error_OK == 0)
  77. {
  78. memcpy(MC_MacInfo.Manufacturer, Data_Buf, 32);
  79. }
  80. //读取自定义字符串1
  81. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO1, Data_Buf, 16);
  82. if(Error_OK == 0)
  83. {
  84. memcpy(&UserString1, Data_Buf, 16);
  85. }
  86. //读取自定义字符串2
  87. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO2, Data_Buf, 16);
  88. if(Error_OK == 0)
  89. {
  90. memcpy(&UserString2, Data_Buf, 16);
  91. }
  92. //读取自定义字符串3
  93. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO3, Data_Buf, 16);
  94. if(Error_OK == 0)
  95. {
  96. memcpy(&UserString3, Data_Buf, 16);
  97. }
  98. //读取掉电临时保存的数据
  99. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP_FLAG, Data_Buf, 4);
  100. if(Error_OK == 0)
  101. {
  102. if(strncmp("FLAG", (char*)Data_Buf, 4) == 0) //关机前进行过存储
  103. {
  104. Error_OK = ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP, Data_Buf, 40);
  105. if(Error_OK == 0)
  106. {
  107. memcpy((uint8_t*)&MC_PowerOffBkp.ODO_Km, Data_Buf, 40);
  108. IsPowerOffDataBkp_SaveFlag = TRUE;
  109. }
  110. }
  111. }
  112. }
  113. /****************************全局函数定义******************************/
  114. //擦除数据
  115. void EEPROM_Flash_Erase(void)
  116. {
  117. uint32_t PageError;
  118. EEPROM_AreaEraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
  119. EEPROM_AreaEraseInitStruct.PageAddress = EEPROM_FLASH_BEGIN_ADDRESS;
  120. EEPROM_AreaEraseInitStruct.NbPages = (EEPROM_FLASH_END_ADDRESS - EEPROM_FLASH_BEGIN_ADDRESS + 1) / 1024;
  121. HAL_FLASH_Unlock();
  122. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  123. HAL_FLASHEx_Erase(&EEPROM_AreaEraseInitStruct, &PageError);
  124. HAL_FLASH_Lock();
  125. HAL_Delay(100);
  126. }
  127. //指定地址读取指定长度数据类型为8bit数据
  128. int8_t ReadDataFromEEPROM_Flash(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数
  129. {
  130. uint32_t DataTemp32[8], CRC_Data, CRC_Result;
  131. uint8_t CRC_Buf[40], i;
  132. Length = Length >> 2;//按照32bit读取
  133. for(i=0; i<Length; i++)
  134. {
  135. DataTemp32[i] = *(__IO uint32_t*)(FlashAddress + i * 4);
  136. CRC_Buf[4 * i] = (uint8_t)((DataTemp32[i] >> 24) & 0xFF);
  137. CRC_Buf[4 * i + 1] = (uint8_t)((DataTemp32[i] >> 16) & 0xFF);
  138. CRC_Buf[4 * i + 2] = (uint8_t)((DataTemp32[i] >> 8) & 0xFF);
  139. CRC_Buf[4 * i + 3] = (uint8_t)(DataTemp32[i] & 0xFF);
  140. }
  141. CRC_Data = *(__IO uint32_t*)(FlashAddress + Length * 4);
  142. CRC_Result = CRC32_Calculate(CRC_Buf, i * 4);
  143. if((CRC_Data - CRC_Result) == 0)
  144. {
  145. memcpy(Data, CRC_Buf, Length * 4);
  146. return 0;
  147. }
  148. else
  149. {
  150. return -1;
  151. }
  152. }
  153. //指定地址写入指定长度数据类型为8bit数据,并写入crc校验码
  154. void SaveDataToEEPROM_Flash(uint32_t FlashAddress, uint8_t* Data, uint8_t Length) // Length必须为4的倍数
  155. {
  156. uint32_t CRC_Result, DataBuf[65];
  157. uint8_t PakageNum, i;
  158. PakageNum = Length / 4;
  159. //数据组包成32bit,最后一包存储CRC校验结果
  160. for(i=0; i<PakageNum; i++)
  161. {
  162. DataBuf[i] = (Data[4 * i + 0] << 24) + (Data[4 * i + 1] << 16) + (Data[4 * i + 2] << 8) + Data[4 * i + 3];
  163. }
  164. CRC_Result = CRC32_Calculate(Data, Length);
  165. DataBuf[PakageNum] = CRC_Result;
  166. //存储数据
  167. FLASH_Write(FlashAddress, DataBuf, PakageNum + 1);
  168. }
  169. void EEPROM_Flash_Check(void)
  170. {
  171. uint8_t DataBuf[4];
  172. uint32_t Flag, FlagCrc, FlagResult;
  173. //读标志位
  174. Flag = *(__IO uint32_t*)(EEPROM_FLASH_ADDR_FLAG);
  175. //读校验位
  176. FlagCrc = *(__IO uint32_t*)(EEPROM_FLASH_ADDR_FLAG + 4);
  177. DataBuf[0] = Flag >> 24;
  178. DataBuf[1] = Flag >> 16;
  179. DataBuf[2] = Flag >> 8;
  180. DataBuf[3] = Flag & 0xFF;
  181. FlagResult = CRC32_Calculate(DataBuf, 4);
  182. //判断数据是否有效
  183. if((FlagResult - FlagCrc) == 0)//数据有效
  184. {
  185. CopyDataFromEEPROM_Flash();
  186. IsFirstPowerOn_FlashFlag = FALSE;
  187. }
  188. else//数据无效
  189. {
  190. IsFirstPowerOn_FlashFlag = TRUE;
  191. CopyDataToEEPROM_Flash(IsFirstPowerOn_FlashFlag);
  192. IsFirstPowerOn_FlashFlag = FALSE;
  193. }
  194. }
  195. void EEPROM_Flash_DataUpdate(void)
  196. {
  197. CopyDataToEEPROM_Flash(IsFirstPowerOn_FlashFlag);
  198. }