tasks.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. #include "tasks.h"
  2. #include "iwdg.h"
  3. #include "gpio.h"
  4. #include "can_process.h"
  5. #include "uart_process.h"
  6. #include "eeprom_24c02.h"
  7. #include "eeprom_flash.h"
  8. #include "adc.h"
  9. #include "hall_sensor.h"
  10. #include "torque_sensor.h"
  11. #include "gas_sensor.h"
  12. #include "math_tools.h"
  13. #include "remain_distance.h"
  14. #include "protect_check.h"
  15. #include "fault_check.h"
  16. #include "key_driver.h"
  17. #include "encrypt.h"
  18. /************************全局变量************************/
  19. TrueOrFalse_Flag_Struct_t IsInitFinish_Flag = FALSE;
  20. /**************************局部函数定义*********************/
  21. /**************************全局函数定义*********************/
  22. //1ms任务处理函数
  23. void HAL_SYSTICK_Callback(void)
  24. {
  25. static uint16_t TimeCnt_10ms = 0;
  26. static uint16_t TimeCnt_100ms = 0;
  27. static uint16_t TimeCnt_1000ms = 0;
  28. static uint32_t FaultDelayTime = 0;
  29. if(IsInitFinish_Flag == FALSE)
  30. {
  31. return;
  32. }
  33. //踏频传感器采集及计算
  34. CadenceSensor_Process(&MC_CadenceResult, MC_ConfigParam.StopTime);
  35. //根据电机工作模式(MC_WorkMode)、力矩传感器和指拨AD值(ADC_SensorData)、控制档位(MC_ControlCode.GearSt)计算控制FOC输入值(MC_CalParam)
  36. if(((uint8_t)(MC_WorkMode ^ MC_WorkMode_Back) != (uint8_t)~0) ||
  37. ((uint8_t)(MC_ControlCode.GearSt ^ MC_ControlCode_Back.GearSt) != (uint8_t)~0) ||
  38. ((uint8_t)(MC_ControlCode.LightSwitch ^ MC_ControlCode_Back.LightSwitch) != (uint8_t)~0))
  39. {
  40. if((HAL_GetTick() - FaultDelayTime) > 200)
  41. {
  42. MC_ErrorCode.ERROR_Bit.Fault_MCU = 1;
  43. }
  44. }
  45. else
  46. {
  47. FaultDelayTime = HAL_GetTick();
  48. }
  49. MC_CalParam_Cal(MC_WorkMode, ADC_SensorData, MC_ControlCode.GearSt, IsBreakTrig_Flag, &MC_CalParam);
  50. //更新控制参数备份值
  51. Update_MC_CalParam_Back();
  52. //更新力矩传感器零点值
  53. TorqueOffSetData_Present_Update(&TorqueOffSetData.PresentData, ADC1_Result[ADC1_RANK_TORQUE_SENSOR], MC_TorqueCorrectParam.K, &MC_ErrorCode);
  54. //更新指拨零点值
  55. GasSensorOffSetData_Update(&GasSensor_OffSet, ADC1_Result[ADC1_RANK_GAS], &MC_ErrorCode);
  56. //10ms任务
  57. TimeCnt_10ms++;
  58. if(TimeCnt_10ms >= 10)
  59. {
  60. TimeCnt_10ms = 0;
  61. }
  62. //100ms任务
  63. TimeCnt_100ms++;
  64. if(TimeCnt_100ms >= 100)
  65. {
  66. TimeCnt_100ms = 0;
  67. //踏频计算滑动均值滤波
  68. MC_RunInfo.Cadence = MovingAverageFilter(MC_CadenceResult.Cadence_Data, MC_Cadence_Array, sizeof(MC_Cadence_Array) / 2);
  69. }
  70. //1000ms任务
  71. TimeCnt_1000ms++;
  72. if(TimeCnt_1000ms >= 1000)
  73. {
  74. TimeCnt_1000ms = 0;
  75. }
  76. }
  77. //CAN数据解析函数
  78. void CanRx_Process(void)
  79. {
  80. CAN_RxData_Process(&CAN_RxBuf_Struct_PBU, 500);
  81. CAN_RxData_Process_Temp(&CAN_RxBuf_Struct_BMS, 500);
  82. // CAN_RxData_Process(&CAN_RxBuf_Struct_BMS, 500);
  83. CAN_RxData_Process(&CAN_RxBuf_Struct_HMI, 500);
  84. CAN_RxData_Process(&CAN_RxBuf_Struct_CDL, 500);
  85. }
  86. //UART数据解析函数
  87. void UartRx_Process(void)
  88. {
  89. Uart_RxData_Process(&UART_RxBuff_Struct3, 500);
  90. }
  91. //MC运行信息更新
  92. void MC_RunInfo_Update(void)
  93. {
  94. static uint32_t PeriodTimeCnt = 0;
  95. if((HAL_GetTick() - PeriodTimeCnt) >= 200)
  96. {
  97. PeriodTimeCnt = HAL_GetTick();
  98. //计算电功率
  99. MC_RunInfo.Power = (uint16_t)((uint32_t)(MC_RunInfo.BusCurrent * MC_RunInfo.BusVoltage) / 1000000) / 2;
  100. MC_RunInfo.Power = (MC_RunInfo.Power < 20) ? 0 : MC_RunInfo.Power;
  101. //更新踏频方向
  102. MC_RunInfo.CadenceDir = MC_CadenceResult.Cadence_Dir;
  103. //计算力矩值
  104. MC_RunInfo.Torque = ADC_SensorData.TorqueSensor / 28;
  105. //当前助力档位
  106. MC_RunInfo.GearSt = MC_ControlCode.GearSt;
  107. //当前灯开关
  108. MC_RunInfo.LightSwitch = MC_ControlCode.LightSwitch;
  109. //剩余电量
  110. MC_RunInfo.SOC = (DeviceOnLine_Status.Status_Bit.BMS_OffLine == 1) ? Battery_SocCal(MC_RunInfo.BusVoltage, MC_RunInfo.BusCurrent)
  111. : BMS_RunInfo.SOC;
  112. //续航里程
  113. MC_RunInfo.RemainDistance = RemainDis.remainDistance;
  114. //总里程计算
  115. #define ODO_KM_SAVE_UNIT 1 //ODO里程存储最小单位
  116. static uint32_t WheelTurnCount = 0;
  117. if((MC_SpeedSensorData.WheelTurnCount - WheelTurnCount) >= (ODO_KM_SAVE_UNIT * 100000 / MC_ConfigParam.WheelSize))
  118. {
  119. MC_RunInfo.ODO_Km = MC_RunLog.ODO_Km + 1;
  120. WheelTurnCount = MC_SpeedSensorData.WheelTurnCount;
  121. }
  122. //存储骑行总里程
  123. if((MC_RunInfo.ODO_Km - MC_RunLog.ODO_Km) >= ODO_KM_SAVE_UNIT)
  124. {
  125. MC_RunLog.ODO_Km = MC_RunInfo.ODO_Km;
  126. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_RUN_LOG, sizeof(MC_RunLog_Struct_t), (uint8_t*)&MC_RunLog.PowerOnCnt);
  127. }
  128. //平均功耗
  129. MC_RunInfo.PowerPerKm = RemainDis.Power_per_km_result / 10;
  130. }
  131. }
  132. //MC故障码发送
  133. void MC_SendErrorCode_Process(MC_ErrorCode_Struct_t ErrorCode)
  134. {
  135. static uint32_t PeriodTimeCnt = 0;
  136. if(ErrorCode.Code != 0x00000000)
  137. {
  138. if((HAL_GetTick() - PeriodTimeCnt) > 500)
  139. {
  140. PeriodTimeCnt = HAL_GetTick();
  141. SendData(ID_MC_BC, MODE_REPORT, 0x1104, (uint8_t*)&ErrorCode.Code);
  142. }
  143. }
  144. else
  145. {
  146. PeriodTimeCnt = HAL_GetTick();
  147. }
  148. }
  149. //MC主动发送运行信息
  150. void MC_SendRunInfo_Process(MC_WorkMode_Struct_t WorkMode)
  151. {
  152. static uint32_t PeriodTimeCnt = 0;
  153. if(WorkMode == MC_WorkMode_Config)
  154. {
  155. if((HAL_GetTick() - PeriodTimeCnt) >= 200)
  156. {
  157. SendData(ID_MC_BC, MODE_REPORT, 0x1020, (uint8_t*)&MC_RunInfo.BikeSpeed);
  158. PeriodTimeCnt = HAL_GetTick();
  159. }
  160. }
  161. else
  162. {
  163. PeriodTimeCnt = HAL_GetTick();
  164. }
  165. }
  166. //发给TE的传感器数据处理
  167. void MC_TE_SensorData_Process(uint16_t Speed, MC_TE_SensorData_Struct_t* p_MC_TE_SensorData)
  168. {
  169. static uint32_t PeriodTimeCnt = 0;
  170. static GPIO_PinState Cadence_Hall_1;
  171. static GPIO_PinState Cadence_Hall_2;
  172. static GPIO_PinState Motor_Hall_A;
  173. static GPIO_PinState Motor_Hall_B;
  174. static GPIO_PinState Break;
  175. static GPIO_PinState SpeedSensor;
  176. static TrueOrFalse_Flag_Struct_t IsFirstEnterFalg = TRUE;
  177. GPIO_PinState GPIO_PinState_Temp;
  178. //初始化变量
  179. if(IsFirstEnterFalg == TRUE)
  180. {
  181. Cadence_Hall_1 = HAL_GPIO_ReadPin(CADENCE_1_GPIO_Port, CADENCE_1_Pin);
  182. Cadence_Hall_2 = HAL_GPIO_ReadPin(CADENCE_2_GPIO_Port, CADENCE_2_Pin);
  183. Motor_Hall_A = HAL_GPIO_ReadPin(HALL_A_GPIO_Port, HALL_A_Pin);
  184. Motor_Hall_B = HAL_GPIO_ReadPin(HALL_B_GPIO_Port, HALL_B_Pin);
  185. Break = HAL_GPIO_ReadPin(BREAK_IN_GPIO_Port, BREAK_IN_Pin);
  186. SpeedSensor = HAL_GPIO_ReadPin(SPEED_SENSOR_GPIO_Port, SPEED_SENSOR_Pin);
  187. p_MC_TE_SensorData->CadenceHall_1_Cnt = 0;
  188. p_MC_TE_SensorData->CadenceHall_2_Cnt = 0;
  189. p_MC_TE_SensorData->MotorHall_A_Cnt = 0;
  190. p_MC_TE_SensorData->MotorHall_B_Cnt = 0;
  191. p_MC_TE_SensorData->BreakTrgiCnt = 0;
  192. p_MC_TE_SensorData->SpeedSensorTrigCnt = 0;
  193. IsFirstEnterFalg = FALSE;
  194. }
  195. //ADC数据更新采集
  196. p_MC_TE_SensorData->AD_BusCurrent = ADC1_Result_Filt[ADC1_RANK_CURRENT];
  197. p_MC_TE_SensorData->AD_RoilTemp = ADC1_Result_Filt[ADC1_RANK_NTC_ROIL];
  198. p_MC_TE_SensorData->AD_TE_Voltage = ADC1_Result_Filt[ADC1_RANK_3V3_TE];
  199. p_MC_TE_SensorData->AD_Torque = ADC1_Result_Filt[ADC1_RANK_TORQUE_SENSOR];
  200. //踏频霍尔1
  201. GPIO_PinState_Temp = HAL_GPIO_ReadPin(CADENCE_1_GPIO_Port, CADENCE_1_Pin);
  202. if(Cadence_Hall_1 != GPIO_PinState_Temp)
  203. {
  204. p_MC_TE_SensorData->CadenceHall_1_Cnt++;
  205. }
  206. Cadence_Hall_1 = GPIO_PinState_Temp;
  207. //踏频霍尔2
  208. GPIO_PinState_Temp = HAL_GPIO_ReadPin(CADENCE_2_GPIO_Port, CADENCE_2_Pin);
  209. if(Cadence_Hall_2 != GPIO_PinState_Temp)
  210. {
  211. p_MC_TE_SensorData->CadenceHall_2_Cnt++;
  212. }
  213. Cadence_Hall_2 = GPIO_PinState_Temp;
  214. //马达霍尔A
  215. GPIO_PinState_Temp = HAL_GPIO_ReadPin(HALL_A_GPIO_Port, HALL_A_Pin);
  216. if(Motor_Hall_A != GPIO_PinState_Temp)
  217. {
  218. p_MC_TE_SensorData->MotorHall_A_Cnt++;
  219. }
  220. Motor_Hall_A = GPIO_PinState_Temp;
  221. //马达霍尔B
  222. GPIO_PinState_Temp = HAL_GPIO_ReadPin(HALL_B_GPIO_Port, HALL_B_Pin);
  223. if(Motor_Hall_B != GPIO_PinState_Temp)
  224. {
  225. p_MC_TE_SensorData->MotorHall_B_Cnt++;
  226. }
  227. Motor_Hall_B = GPIO_PinState_Temp;
  228. //刹车
  229. GPIO_PinState_Temp = HAL_GPIO_ReadPin(BREAK_IN_GPIO_Port, BREAK_IN_Pin);
  230. if(Break != GPIO_PinState_Temp)
  231. {
  232. p_MC_TE_SensorData->BreakTrgiCnt++;
  233. }
  234. Break = GPIO_PinState_Temp;
  235. //速度传感器
  236. GPIO_PinState_Temp = HAL_GPIO_ReadPin(SPEED_SENSOR_GPIO_Port, SPEED_SENSOR_Pin);
  237. if(SpeedSensor != GPIO_PinState_Temp)
  238. {
  239. p_MC_TE_SensorData->SpeedSensorTrigCnt++;
  240. }
  241. SpeedSensor = GPIO_PinState_Temp;
  242. //电机转速值
  243. p_MC_TE_SensorData->SynC_Clock_Freq = 1000; //1000KHz
  244. //数据发送
  245. if((HAL_GetTick() - PeriodTimeCnt) >= 500)
  246. {
  247. SendCmdData(&UART_TxBuff_Struct3, MODE_REPORT, 0x1014, (uint8_t*)&p_MC_TE_SensorData->AD_Torque);
  248. IsComOK_TE = FALSE;
  249. PeriodTimeCnt = HAL_GetTick();
  250. }
  251. }
  252. //根据踏频和母线电流计算限流系数
  253. uint8_t MC_CadenceLimit_Cal(uint8_t Cadence, uint16_t Current, uint8_t T_Roil)
  254. {
  255. static uint32_t PeriodTimeCnt = 0;
  256. static uint32_t IdcFiltSum = 0;
  257. static uint8_t IdcFiltCnt = 0; //滤波输入值计算
  258. static uint16_t IdcFilt = 0; //滤波结果
  259. static uint16_t Limit_Cnt = 0; //限流计时值
  260. static uint16_t OK_Cnt = 0; //限流恢复计时值
  261. static FlagStatus LimitFlag = RESET;
  262. static uint8_t Result = 100;
  263. if((HAL_GetTick() - PeriodTimeCnt) >= 100)
  264. {
  265. PeriodTimeCnt = HAL_GetTick();
  266. //母线电流滤波
  267. IdcFiltSum += Current;
  268. IdcFiltCnt++;
  269. if(IdcFiltCnt >= 8)
  270. {
  271. IdcFilt = IdcFiltSum >> 3;
  272. IdcFiltCnt = 0;
  273. IdcFiltSum = 0;
  274. }
  275. //限流保护计时
  276. if((Cadence < 70) && (IdcFilt > 6000))
  277. {
  278. Limit_Cnt++;
  279. }
  280. else
  281. {
  282. Limit_Cnt = 0;
  283. }
  284. //限流恢复计时
  285. if(((Cadence > 70) || (IdcFilt < 5000)) && (T_Roil < 150))
  286. {
  287. OK_Cnt++;
  288. }
  289. else
  290. {
  291. OK_Cnt = 0;
  292. }
  293. //限流判断
  294. if(Limit_Cnt > 300)
  295. {
  296. Limit_Cnt = 0;
  297. LimitFlag = SET;
  298. }
  299. //限流恢复判断
  300. if(OK_Cnt > 100)
  301. {
  302. OK_Cnt = 0;
  303. LimitFlag = RESET;
  304. }
  305. //限流系数计算
  306. if(LimitFlag == SET)
  307. {
  308. if(Cadence < 70)
  309. {
  310. Result = 30 + Cadence;
  311. Result = (Result > 100) ? 100 : Result;
  312. }
  313. else
  314. {
  315. Result = 100;
  316. }
  317. }
  318. else
  319. {
  320. Result = 100;
  321. }
  322. }
  323. return Result;
  324. }
  325. //接收到关机指令处理
  326. void PowerOff_Process(void)
  327. {
  328. MC_ControlCode.GearSt = MC_GearSt_OFF;
  329. Update_MC_ControlCode_Back();
  330. SendData(ID_MC_BC, MODE_REPORT, 0x1305, (uint8_t*)"READY");
  331. }
  332. //CAN设备通信状态检测处理
  333. void MC_CanRxCheck_Process(MC_WorkMode_Struct_t WorkMode, MC_GearSt_Struct_t* GearSt)
  334. {
  335. if(WorkMode == MC_WorkMode_Run)
  336. {
  337. //PBU通信状态检测
  338. if(IsComOK_PBU.IsOK_Flag == TRUE)
  339. {
  340. if((HAL_GetTick() - IsComOK_PBU.OK_TrigTime) > 1000)
  341. {
  342. IsComOK_PBU.IsOK_Flag = FALSE;
  343. *GearSt = MC_GearSt_OFF;
  344. Update_MC_ControlCode_Back();
  345. }
  346. }
  347. else
  348. {
  349. *GearSt = MC_GearSt_OFF;
  350. Update_MC_ControlCode_Back();
  351. }
  352. }
  353. }
  354. //运行总时间计算
  355. void MC_RunTime_Cal(uint32_t* p_Runtime)
  356. {
  357. static uint32_t PeriodTimeCnt = 0;
  358. static uint8_t Count = 0;
  359. if((HAL_GetTick()- PeriodTimeCnt) >= 60000)
  360. {
  361. PeriodTimeCnt = HAL_GetTick();
  362. (*p_Runtime)++;
  363. //存储运行总时间
  364. Count++;
  365. if(Count >= 5)
  366. {
  367. Count = 0;
  368. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_RUN_LOG, sizeof(MC_RunLog_Struct_t), (uint8_t*)&MC_RunLog.PowerOnCnt);
  369. }
  370. }
  371. }
  372. //设备在线检测
  373. void MC_OnLineCheck(OnLine_Status_Struct_t* p_OnLineStatus, MC_ErrorCode_Struct_t* p_ErrorCode)
  374. {
  375. uint8_t SendTimeCnt;
  376. uint32_t PeriodTimeCnt;
  377. //发送指令查询PBU是否在线
  378. PeriodTimeCnt = HAL_GetTick();
  379. SendTimeCnt = 0;
  380. do
  381. {
  382. CAN_RxData_Process(&CAN_RxBuf_Struct_PBU, 500);
  383. if((HAL_GetTick() - PeriodTimeCnt) >= 50)
  384. {
  385. PeriodTimeCnt = HAL_GetTick();
  386. SendTimeCnt++;
  387. SendData(ID_MC_TO_PBU, MODE_READ, 0x5009, (uint8_t*)"HANDSHAKE");
  388. }
  389. //看门狗清零
  390. #if DEBUG
  391. HAL_IWDG_Refresh(&hiwdg);
  392. #endif
  393. }while((p_OnLineStatus->Status_Bit.PBU_OffLine == 1) && (SendTimeCnt <= 4));
  394. p_ErrorCode->ERROR_Bit.Fault_PBU_Check = p_OnLineStatus->Status_Bit.PBU_OffLine;
  395. //发送指令查询HMI是否在线
  396. if(PBU_ConfigParam.NoHMI_Flag == MC_SUPPORT_DISABLE)
  397. {
  398. PeriodTimeCnt = HAL_GetTick();
  399. SendTimeCnt = 0;
  400. do
  401. {
  402. CAN_RxData_Process(&CAN_RxBuf_Struct_HMI, 500);
  403. if((HAL_GetTick() - PeriodTimeCnt) >= 50)
  404. {
  405. PeriodTimeCnt = HAL_GetTick();
  406. SendTimeCnt++;
  407. SendData(ID_MC_TO_HMI, MODE_READ, 0x7009, (uint8_t*)"HANDSHAKE");
  408. }
  409. //看门狗清零
  410. #if DEBUG
  411. HAL_IWDG_Refresh(&hiwdg);
  412. #endif
  413. }while((p_OnLineStatus->Status_Bit.HMI_OffLine == 1) && (SendTimeCnt <= 4));
  414. }
  415. else
  416. {
  417. p_OnLineStatus->Status_Bit.HMI_OffLine = 0;
  418. }
  419. p_ErrorCode->ERROR_Bit.Fault_HMI_Check = p_OnLineStatus->Status_Bit.HMI_OffLine;
  420. //发送指令查询BMS是否在线
  421. PeriodTimeCnt = HAL_GetTick();
  422. SendTimeCnt = 0;
  423. do
  424. {
  425. CAN_RxData_Process_Temp(&CAN_RxBuf_Struct_BMS, 500);
  426. if((HAL_GetTick() - PeriodTimeCnt) >= 50)
  427. {
  428. PeriodTimeCnt = HAL_GetTick();
  429. SendTimeCnt++;
  430. SendData(ID_MC_TO_BMS, MODE_READ, 0x3009, (uint8_t*)"HANDSHAKE");
  431. }
  432. //看门狗清零
  433. #if DEBUG
  434. HAL_IWDG_Refresh(&hiwdg);
  435. #endif
  436. }while((p_OnLineStatus->Status_Bit.BMS_OffLine == 1) && (SendTimeCnt <= 4));
  437. p_ErrorCode->ERROR_Bit.Fault_BMS_Check = p_OnLineStatus->Status_Bit.BMS_OffLine;
  438. }
  439. //设备授权校验
  440. void MC_DeviceCheck(MC_ErrorCode_Struct_t* p_ErrorCode)
  441. {
  442. uint8_t T[16];
  443. CheckCodeCal(NULL, Secret_Key, T);
  444. }
  445. /**************************全局函数定义结束*****************/