eeprom_24c02.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. #include "eeprom_24c02.h"
  2. #define Time_OUT 3000
  3. #define EEPROM_WP_GPIOx GPIOB
  4. #define EEPROM_WP_GPIO_PIN_x GPIO_PIN_1
  5. const uint8_t EEPROM_24C02_Flag[2] = {0x55,0xAA};
  6. int8_t AT24C02_OK = ACK_FAIL;
  7. I2C_Handle_Struct_t I2C_Handle_EEPROM = {GPIOB, GPIO_PIN_11, GPIOB, GPIO_PIN_10};
  8. //I2C引脚初始化
  9. void EEPROM_24C02_Init(I2C_Handle_Struct_t* I2C_Handle)
  10. {
  11. //保护
  12. GPIO_InitTypeDef GPIO_InitStruct;
  13. GPIO_InitStruct.Pin = EEPROM_WP_GPIO_PIN_x;
  14. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  15. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  16. HAL_GPIO_Init(EEPROM_WP_GPIOx, &GPIO_InitStruct);
  17. HAL_GPIO_WritePin(EEPROM_WP_GPIOx, EEPROM_WP_GPIO_PIN_x, GPIO_PIN_SET);
  18. I2C_GPIO_Config(I2C_Handle);
  19. }
  20. //指定地址读取1字节
  21. int8_t EEPROM_24C02_ReadOneByte(I2C_Handle_Struct_t* I2C_Handle, uint8_t ReadAddr, uint8_t *data) //指定地址读取一个字节
  22. {
  23. uint16_t Timeout_Cnt = 0;
  24. I2C_Start(I2C_Handle);
  25. I2C_Write_Byte(I2C_Handle, AT24C02_ADDR_WR); //发送写命令
  26. Timeout_Cnt = 0;
  27. do
  28. {
  29. Timeout_Cnt++;
  30. if(Timeout_Cnt>Time_OUT)
  31. {
  32. return ACK_FAIL;
  33. }
  34. }while(I2C_Check_Ack(I2C_Handle));
  35. I2C_Write_Byte(I2C_Handle, ReadAddr);
  36. Timeout_Cnt = 0;
  37. do
  38. {
  39. Timeout_Cnt++;
  40. if(Timeout_Cnt>Time_OUT)
  41. {
  42. return ACK_FAIL;
  43. }
  44. }while(I2C_Check_Ack(I2C_Handle));
  45. I2C_Start(I2C_Handle);
  46. I2C_Write_Byte(I2C_Handle, AT24C02_ADDR_RD); //发送读命令
  47. Timeout_Cnt = 0;
  48. do
  49. {
  50. Timeout_Cnt++;
  51. if(Timeout_Cnt>Time_OUT)
  52. {
  53. return ACK_FAIL;
  54. }
  55. }while(I2C_Check_Ack(I2C_Handle));
  56. I2C_Read_Byte(I2C_Handle, data);
  57. I2C_Send_Nack(I2C_Handle);
  58. I2C_Stop(I2C_Handle);
  59. return ACK_OK;
  60. }
  61. //指定地址写入1字节
  62. int8_t EEPROM_24C02_WriteOneByte(I2C_Handle_Struct_t* I2C_Handle, uint8_t WriteAddr,uint8_t DataToWrite) //指定地址写入一个字节
  63. {
  64. uint16_t Timeout_Cnt = 0;
  65. HAL_GPIO_WritePin(EEPROM_WP_GPIOx, EEPROM_WP_GPIO_PIN_x, GPIO_PIN_RESET);
  66. I2C_Start(I2C_Handle);
  67. I2C_Write_Byte(I2C_Handle, AT24C02_ADDR_WR); //发送写命令
  68. Timeout_Cnt = 0;
  69. do
  70. {
  71. Timeout_Cnt++;
  72. if(Timeout_Cnt>Time_OUT)
  73. {
  74. return ACK_FAIL;
  75. }
  76. }while(I2C_Check_Ack(I2C_Handle));
  77. I2C_Write_Byte(I2C_Handle, WriteAddr);
  78. Timeout_Cnt = 0;
  79. do
  80. {
  81. Timeout_Cnt++;
  82. if(Timeout_Cnt>Time_OUT)
  83. {
  84. return ACK_FAIL;
  85. }
  86. }while(I2C_Check_Ack(I2C_Handle));
  87. I2C_Write_Byte(I2C_Handle, DataToWrite);
  88. Timeout_Cnt = 0;
  89. do
  90. {
  91. Timeout_Cnt++;
  92. if(Timeout_Cnt>Time_OUT)
  93. {
  94. return ACK_FAIL;
  95. }
  96. }while(I2C_Check_Ack(I2C_Handle));
  97. I2C_Stop(I2C_Handle);
  98. HAL_Delay(10);
  99. HAL_GPIO_WritePin(EEPROM_WP_GPIOx, EEPROM_WP_GPIO_PIN_x, GPIO_PIN_SET);
  100. //看门狗清零
  101. #if DEBUG
  102. HAL_IWDG_Refresh(&hiwdg);
  103. #endif
  104. return ACK_OK;
  105. }
  106. //指定地址写入有效数据
  107. int8_t SaveParamToEEprom_24C02(I2C_Handle_Struct_t* I2C_Handle, uint8_t AddrBegin, uint8_t DataLen, uint8_t *Data)
  108. {
  109. uint8_t Temp_8 = 0, i;
  110. uint16_t CRC_Result = 0;
  111. //按字节存储数据
  112. for(i=0;i<DataLen;i++)
  113. {
  114. if(EEPROM_24C02_ReadOneByte(I2C_Handle, AddrBegin + i, &Temp_8) == ACK_FAIL)
  115. {
  116. return ACK_FAIL;
  117. }
  118. if(Temp_8 != Data[i])
  119. {
  120. Temp_8 = Data[i];
  121. if(EEPROM_24C02_WriteOneByte(I2C_Handle, AddrBegin + i, Temp_8) == ACK_FAIL)
  122. {
  123. return ACK_FAIL;
  124. }
  125. }
  126. }
  127. //存储校验位
  128. CRC_Result = CRC16_Xmodem(Data, DataLen);
  129. Temp_8 = (uint8_t)(CRC_Result >> 8);
  130. if(EEPROM_24C02_WriteOneByte(I2C_Handle, AddrBegin + DataLen , Temp_8) == ACK_FAIL)
  131. {
  132. return ACK_FAIL;
  133. }
  134. Temp_8 = (uint8_t)(CRC_Result & 0xFF);
  135. if(EEPROM_24C02_WriteOneByte(I2C_Handle, AddrBegin + DataLen + 1 , Temp_8) == ACK_FAIL)
  136. {
  137. return ACK_FAIL;
  138. }
  139. return ACK_OK;
  140. }
  141. //指定地址读取有效数据
  142. uint8_t EEPROM_ReadDataBuf[256];
  143. int8_t GetParamFromEEprom_24C02(I2C_Handle_Struct_t* I2C_Handle, uint8_t AddrBegin, uint8_t DataLen, uint8_t *Data)
  144. {
  145. uint8_t i, Temp2_8[2];
  146. uint16_t CRC_Data, CRC_Result;
  147. //读取DataLen个字节
  148. for(i=0;i<DataLen;i++)
  149. {
  150. if(EEPROM_24C02_ReadOneByte(I2C_Handle, AddrBegin + i, (EEPROM_ReadDataBuf + i)) == ACK_FAIL)
  151. {
  152. return ACK_FAIL;
  153. }
  154. }
  155. //计算校验
  156. CRC_Result = CRC16_Xmodem(EEPROM_ReadDataBuf, DataLen);
  157. //读取校验
  158. EEPROM_24C02_ReadOneByte(I2C_Handle, AddrBegin + DataLen, Temp2_8);
  159. EEPROM_24C02_ReadOneByte(I2C_Handle, AddrBegin + DataLen + 1, (Temp2_8 + 1));
  160. CRC_Data = (uint16_t)(Temp2_8[0] << 8) + Temp2_8[1];
  161. //判断数据是否有效
  162. if((CRC_Data - CRC_Result) == 0)
  163. {
  164. memcpy(Data, EEPROM_ReadDataBuf, DataLen);
  165. return ACK_OK;
  166. }
  167. else
  168. {
  169. return ACK_FAIL;
  170. }
  171. }
  172. //写入默认数据
  173. int8_t CopyDefaultDataToEEpprom_24C02(I2C_Handle_Struct_t* I2C_Handle)
  174. {
  175. uint8_t Temp_8[2];
  176. uint16_t CRC_Result = 0;
  177. Var_SetToDefaultParam();
  178. Var_SetToDefaultLog();
  179. EEPROM_24C02_ParamReset(I2C_Handle);//1363ms
  180. EEPROM_24C02_LogReset(I2C_Handle);//1240ms
  181. //写入数据有效标志
  182. memcpy((uint8_t*)Temp_8, (uint8_t*)EEPROM_24C02_Flag, sizeof(EEPROM_24C02_Flag));
  183. if(EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG, Temp_8[0]) == ACK_FAIL)
  184. {
  185. EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG, Temp_8[0]);
  186. }
  187. if(EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 1, Temp_8[1]) == ACK_FAIL)
  188. {
  189. EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 1, Temp_8[1]);
  190. }
  191. CRC_Result = CRC16_Xmodem(Temp_8, 2);
  192. if(EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 2, (uint8_t)(CRC_Result >> 8)) == ACK_FAIL)
  193. {
  194. EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 2, (uint8_t)(CRC_Result >> 8));
  195. }
  196. if(EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 3, (uint8_t)(CRC_Result & 0xFF)) == ACK_FAIL)
  197. {
  198. EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 3, (uint8_t)(CRC_Result & 0xFF));
  199. }
  200. return ACK_OK;
  201. }
  202. //从EEPROM读取数据
  203. int8_t CopyDataFromEEpprom_24C02(I2C_Handle_Struct_t* I2C_Handle)
  204. {
  205. //读出校验码 13ms
  206. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CHECKCODE, sizeof(MC_CheckInfo.CheckCode), MC_CheckInfo.CheckCode) == ACK_FAIL)
  207. {
  208. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CHECKCODE, sizeof(MC_CheckInfo.CheckCode), MC_CheckInfo.CheckCode);
  209. }
  210. //读出配置参数 30ms
  211. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM1, sizeof(MC_ConfigParam1_Struct_t), (uint8_t*)&MC_ConfigParam1.GasCtrlMode_Param) == ACK_FAIL)
  212. {
  213. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM1, sizeof(MC_ConfigParam1_Struct_t), (uint8_t*)&MC_ConfigParam1.GasCtrlMode_Param);
  214. }
  215. //读出力矩传感器校正信息 5ms
  216. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_PARAM, sizeof(MC_TorqueCorrectParam_Struct_t), (uint8_t*)&MC_TorqueCorrectParam.StarData) == ACK_FAIL)
  217. {
  218. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_PARAM, sizeof(MC_TorqueCorrectParam_Struct_t), (uint8_t*)&MC_TorqueCorrectParam.StarData);
  219. }
  220. //读出马达参数 21ms
  221. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_MOTOR_PARAM, sizeof(MC_MotorParam_Struct_t), (uint8_t*)&MC_MotorParam.Rate_Power) == ACK_FAIL)
  222. {
  223. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_MOTOR_PARAM, sizeof(MC_MotorParam_Struct_t), (uint8_t*)&MC_MotorParam.Rate_Power);
  224. }
  225. //读出运行历史1 44ms
  226. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt) == ACK_FAIL)
  227. {
  228. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt);
  229. }
  230. MC_RunLog1.PowerOnCnt++;
  231. //写入开机次数 75ms
  232. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt) == ACK_FAIL)
  233. {
  234. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt);
  235. }
  236. //读出运行历史2
  237. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG2, sizeof(MC_RunLog2_Struct_t), (uint8_t*)&MC_RunLog2.MCU_FaultCnt) == ACK_FAIL)
  238. {
  239. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG2, sizeof(MC_RunLog2_Struct_t), (uint8_t*)&MC_RunLog2.MCU_FaultCnt);
  240. }
  241. //读出力矩传感器零点偏移值 22ms
  242. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET, sizeof(TorqueOffSetData_Struct_t), (uint8_t*)&TorqueOffSetData.Data[0]) == ACK_FAIL)
  243. {
  244. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET, sizeof(TorqueOffSetData_Struct_t), (uint8_t*)&TorqueOffSetData.Data[0]);
  245. }
  246. //读出密钥 11ms
  247. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key) == ACK_FAIL)
  248. {
  249. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key);
  250. }
  251. //读取平均功耗 16ms
  252. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_AVG_POWER, sizeof(MC_AvgPower_Struct_t), (uint8_t*)&MC_AvgPower.GearSt_ECO) == ACK_FAIL)
  253. {
  254. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_AVG_POWER, sizeof(MC_AvgPower_Struct_t), (uint8_t*)&MC_AvgPower.GearSt_ECO);
  255. }
  256. //读取骑行历史信息
  257. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km) == ACK_FAIL)
  258. {
  259. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km);
  260. }
  261. //读取用户配置参数2 31ms
  262. if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM2, sizeof(MC_ConfigParam2_Struct_t), (uint8_t*)&MC_ConfigParam2.ZeroAngle_Pitch) == ACK_FAIL)
  263. {
  264. GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM2, sizeof(MC_ConfigParam2_Struct_t), (uint8_t*)&MC_ConfigParam2.ZeroAngle_Pitch);
  265. }
  266. return ACK_OK;
  267. }
  268. //EEPROM_24C02检测
  269. int8_t EEPROM_24C02_Check(I2C_Handle_Struct_t* I2C_Handle)
  270. {
  271. uint8_t Temp_8[2] = {0};
  272. uint16_t FlagCRC, FlagCRC_Result;
  273. //读取存储标志并计算校验码
  274. EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG, Temp_8);//1ms
  275. EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 1, (Temp_8 + 1));//1ms
  276. FlagCRC_Result = CRC16_Xmodem(Temp_8, 2);
  277. //读取存储的校验码
  278. EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 2, Temp_8);
  279. EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 3, (Temp_8 + 1));
  280. FlagCRC = ((uint16_t)Temp_8[0] << 8) + Temp_8[1];
  281. //判断数据是否有效
  282. if((FlagCRC - FlagCRC_Result) == 0) // 数据有效
  283. {
  284. return(CopyDataFromEEpprom_24C02(I2C_Handle));
  285. }
  286. else if(IsFirstPowerOnFlag == TRUE) // 数据无效且开机次数为0时,写入默认参数
  287. {
  288. return(CopyDefaultDataToEEpprom_24C02(I2C_Handle));
  289. }
  290. else
  291. {
  292. return ACK_FAIL;
  293. }
  294. }
  295. //清除指定区间段有效数据
  296. void EEPROM_24C02_ClearData(I2C_Handle_Struct_t* I2C_Handle, uint8_t AddrBegin, uint8_t EndAddr, uint8_t Data)
  297. {
  298. uint8_t i, Length;
  299. Length = EndAddr - AddrBegin;
  300. for(i=0; i<Length; i++)
  301. {
  302. EEPROM_24C02_WriteOneByte(I2C_Handle, AddrBegin + i ,Data);
  303. }
  304. }
  305. //配置参数还原
  306. void EEPROM_24C02_ParamReset(I2C_Handle_Struct_t* I2C_Handle)
  307. {
  308. //写入MC校验码
  309. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CHECKCODE, sizeof(MC_CheckInfo.CheckCode), MC_CheckInfo.CheckCode) == ACK_FAIL)
  310. {
  311. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CHECKCODE, sizeof(MC_CheckInfo.CheckCode), MC_CheckInfo.CheckCode);
  312. }
  313. //写入密钥
  314. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key) == ACK_FAIL)
  315. {
  316. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key);
  317. }
  318. //写入用户配置参数1
  319. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM1, sizeof(MC_ConfigParam1_Struct_t), (uint8_t*)&MC_ConfigParam1.GasCtrlMode_Param) == ACK_FAIL)
  320. {
  321. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM1, sizeof(MC_ConfigParam1_Struct_t), (uint8_t*)&MC_ConfigParam1.GasCtrlMode_Param);
  322. }
  323. //写入用户配置参数2
  324. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM2, sizeof(MC_ConfigParam2_Struct_t), (uint8_t*)&MC_ConfigParam2.ZeroAngle_Pitch) == ACK_FAIL)
  325. {
  326. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM2, sizeof(MC_ConfigParam2_Struct_t), (uint8_t*)&MC_ConfigParam2.ZeroAngle_Pitch);
  327. }
  328. //写入马达参数
  329. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_MOTOR_PARAM, sizeof(MC_MotorParam_Struct_t), (uint8_t*)&MC_MotorParam.Rate_Power) == ACK_FAIL)
  330. {
  331. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_MOTOR_PARAM, sizeof(MC_MotorParam_Struct_t), (uint8_t*)&MC_MotorParam.Rate_Power);
  332. }
  333. //写入默认力矩传感器校正信息
  334. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_PARAM, sizeof(MC_TorqueCorrectParam_Struct_t), (uint8_t*)&MC_TorqueCorrectParam.StarData) == ACK_FAIL)
  335. {
  336. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_PARAM, sizeof(MC_TorqueCorrectParam_Struct_t), (uint8_t*)&MC_TorqueCorrectParam.StarData);
  337. }
  338. //写入力矩传感器零点偏移值
  339. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET, sizeof(TorqueOffSetData_Struct_t), (uint8_t*)TorqueOffSetData.Data) == ACK_FAIL)
  340. {
  341. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET, sizeof(TorqueOffSetData_Struct_t), (uint8_t*)TorqueOffSetData.Data);
  342. }
  343. }
  344. //历史数据还原
  345. void EEPROM_24C02_LogReset(I2C_Handle_Struct_t* I2C_Handle)
  346. {
  347. //写入运行历史1
  348. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt) == ACK_FAIL)
  349. {
  350. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt);
  351. }
  352. //写入运行历史2
  353. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG2, sizeof(MC_RunLog2_Struct_t), (uint8_t*)&MC_RunLog2.MCU_FaultCnt) == ACK_FAIL)
  354. {
  355. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG2, sizeof(MC_RunLog2_Struct_t), (uint8_t*)&MC_RunLog2.MCU_FaultCnt);
  356. }
  357. //写入骑行历史信息
  358. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km) == ACK_FAIL)
  359. {
  360. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km);
  361. }
  362. //写入平均功耗
  363. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_AVG_POWER, sizeof(MC_AvgPower_Struct_t), (uint8_t*)&MC_AvgPower.GearSt_ECO) == ACK_FAIL)
  364. {
  365. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_AVG_POWER, sizeof(MC_AvgPower_Struct_t), (uint8_t*)&MC_AvgPower.GearSt_ECO);
  366. }
  367. }
  368. //掉电数据从Flash转移到24C02
  369. int8_t SavePowerOffBakData(I2C_Handle_Struct_t* I2C_Handle, TrueOrFalse_Flag_Struct_t IsSaveFlag)
  370. {
  371. if(IsSaveFlag == TRUE) //关机前有存储记录,则把从FLASH取出的数据转移到EEPROM中
  372. {
  373. //更新历史信息存储数据
  374. MC_RunLog1.RunTime = MC_PowerOffBkp.Run_Time;
  375. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt) == ACK_FAIL)
  376. {
  377. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt);
  378. }
  379. //更新骑行信息存储数据
  380. MC_RideLog.ODO_Km = MC_PowerOffBkp.ODO_Km;
  381. MC_RideLog.ODO_Time = MC_PowerOffBkp.ODO_Time;
  382. MC_RideLog.TRIP_Km = MC_PowerOffBkp.Trip_Km;
  383. MC_RideLog.TRIP_Time = MC_PowerOffBkp.Trip_Time;
  384. if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km) == ACK_FAIL)
  385. {
  386. SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km);
  387. }
  388. }
  389. //更新运行信息中ODO信息
  390. MC_RunInfo.ODO_Km = MC_RideLog.ODO_Km / 10;
  391. return 0;
  392. }
  393. //存储历史数据
  394. int8_t RunLogSave_Process(uint8_t* RunLogIndex)
  395. {
  396. if(*RunLogIndex == 1)
  397. {
  398. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt);
  399. *RunLogIndex = 0;
  400. }
  401. else if(*RunLogIndex == 2)
  402. {
  403. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_RUN_LOG2, sizeof(MC_RunLog2_Struct_t), (uint8_t*)&MC_RunLog2.MCU_FaultCnt);
  404. *RunLogIndex = 0;
  405. }
  406. return 0;
  407. }
  408. //根据历史信息中开机次数判断是否进行第一次开机
  409. TrueOrFalse_Flag_Struct_t CheckFactoryModeFromEEPROM(I2C_Handle_Struct_t* I2C_Handle, uint8_t Addr)
  410. {
  411. uint8_t Temp_8[4] = {0};
  412. //读取存储标志并计算校验码
  413. EEPROM_24C02_ReadOneByte(I2C_Handle, Addr, Temp_8);
  414. EEPROM_24C02_ReadOneByte(I2C_Handle, Addr + 1, (Temp_8 + 1));
  415. EEPROM_24C02_ReadOneByte(I2C_Handle, Addr + 2, (Temp_8 + 2));
  416. EEPROM_24C02_ReadOneByte(I2C_Handle, Addr + 3, (Temp_8 + 3));
  417. return((Temp_8[0] & Temp_8[1] & Temp_8[2] & Temp_8[3] == 0xFF) ? TRUE : FALSE);
  418. }