enviolo_can.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "enviolo_can.h"
  2. #include "can.h"
  3. #include "speed_sensor.h"
  4. #include "motor_control.h"
  5. #include "log_save.h"
  6. #include "can_process.h"
  7. Enviolo_Struct_t CanEnvioloData = {0};
  8. Enviolo_SetVal_Struct_t EnvioloSetData = {0};
  9. Calibration_Struct_t Enviolo_Calibration = {0};
  10. //计算1~9档位对应的变速比,范围为500~1800
  11. const uint16_t Ratio_Table[9] =
  12. {
  13. 500,
  14. 662,
  15. 824,
  16. 986,
  17. 1148,
  18. 1310,
  19. 1472,
  20. 1634,
  21. 1800
  22. };
  23. /******************************************************************************
  24. * @Function: 解析CAN报文,提取OBC发送的报文信息提取需要设置的目标踏频值和档位比例值
  25. * @Discrible: 查看协议文档ID(0X731)-->0X4008的报文
  26. * @Param: Data:需要分析的报文 RetVal:需要设置的值
  27. * @Return: void
  28. * @Others:
  29. ******************************************************************************
  30. * @Recode date version author modify
  31. * ------------------------------------------------------------------
  32. * 20211025 V1.0.0 leechard create
  33. *
  34. *******************************************************************************/
  35. void GetWorkSetVal(uint8_t* Data, Enviolo_SetVal_Struct_t *RetVal, Calibration_Struct_t *Calib)
  36. {
  37. static uint8_t u8Temp = 0;
  38. if(Data[2] == NOTNEED_CALIB)//无需校准
  39. {
  40. if(Data[0] == WORKMODE_AUTO)//自动模式
  41. {
  42. RetVal->u8DesiredGearBoxMode = WORKMODE_AUTO;
  43. RetVal->u16DesiredGearRatio = 0;
  44. RetVal->u16DesiredCanence = Data[1];
  45. }
  46. else if(Data[0] == WORKMODE_MANUAL)//手动模式
  47. {
  48. RetVal->u8DesiredGearBoxMode = WORKMODE_MANUAL;
  49. //根据手动设置的档位计算需要设置的变速比例值
  50. RetVal->u16DesiredGearRatio = (Data[1] == 0)?Ratio_Table[0]:((Data[1]>8)?Ratio_Table[8]:Ratio_Table[Data[1]-1]);
  51. RetVal->u16DesiredCanence = 0;
  52. }
  53. u8Temp = 0;
  54. }
  55. else if(Data[2] == NEED_CALIB)//需要校准
  56. {
  57. RetVal->u8DesiredGearBoxMode = WORKMODE_CALIB;
  58. if(u8Temp == 0)
  59. {
  60. Calib->u8CalibrationCmdToEnviolo = 1;
  61. u8Temp = 1;
  62. }
  63. }
  64. }
  65. /******************************************************************************
  66. * @Function: 200MS发送报文到enviolo,默认5min不发送报文则enviolo自动休眠
  67. * @Discrible: 通过工作模式设置相应的值到enviolo
  68. * @Param:
  69. * @Return: void
  70. * @Others:
  71. ******************************************************************************
  72. * @Recode date version author modify
  73. * ------------------------------------------------------------------
  74. * 20211025 V1.0.0 leechard create
  75. *
  76. *******************************************************************************/
  77. void sendDataToEnviolo(Enviolo_SetVal_Struct_t *st_SendData, Calibration_Struct_t *st_Calib)
  78. {
  79. uint8_t sendbuf[8]={0};
  80. //参数配置只发送一次
  81. if((st_SendData->u8DesiredGearBoxMode == WORKMODE_MANUAL)||(st_SendData->u8DesiredGearBoxMode == WORKMODE_AUTO))
  82. {
  83. if(CanEnvioloData.u8SendConfigDataToEnviolo == 0)
  84. {
  85. sendbuf[0] = DU_FRONT_CHAINRING; //DU_Front_Chainring
  86. sendbuf[1] = DU_REARSPROCKET; //DU_RearSprocket
  87. sendbuf[2] = DU_CADENCE_LOWLIMIT; //DU_Cadence_LowLimit
  88. sendbuf[3] = DU_CADENCE_HIGHLIMIT;//DU_Cadence_HighLimit
  89. sendbuf[4] = 0x00; //Reserved
  90. sendbuf[5] = (MC_ConfigParam1.WheelSize > 100)?(MC_ConfigParam1.WheelSize - 100):0;//
  91. sendbuf[6] = DU_SLEEPTIME; //DU_SleepTime
  92. sendbuf[7] = 0x00; //Reserved
  93. CAN_SendData(ID_ENVIOLO_CONFIG, sendbuf, sizeof(sendbuf));
  94. CanEnvioloData.u8SendConfigDataToEnviolo = 1;
  95. }
  96. }
  97. if((MC_ControlCode.GearSt == MC_GearSt_WALK)||(MC_ControlCode.GearSt == MC_GearSt_OFF))//推行模式和0档位将档位设置为最低档
  98. {
  99. sendbuf[0] = WORKMODE_MANUAL;
  100. sendbuf[1] = (uint8_t)(Ratio_Table[0]>>8);
  101. sendbuf[2] = (uint8_t)(Ratio_Table[0]);
  102. sendbuf[3] = 0X00;
  103. sendbuf[4] = 0X00;
  104. CAN_SendData(ID_ENVIOLO_CONTROL, sendbuf, sizeof(sendbuf));
  105. }
  106. // else if(MC_ControlCode.GearSt == MC_GearSt_OFF)//关机状态 关闭自动变速器
  107. // {
  108. // CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  109. // }
  110. else
  111. {
  112. if(st_SendData->u8DesiredGearBoxMode == WORKMODE_MANUAL)//如果是手动模式
  113. {
  114. sendbuf[0] = st_SendData->u8DesiredGearBoxMode;
  115. sendbuf[1] = (uint8_t)(st_SendData->u16DesiredGearRatio>>8);
  116. sendbuf[2] = (uint8_t)(st_SendData->u16DesiredGearRatio);
  117. sendbuf[3] = 0X00;
  118. sendbuf[4] = 0X00;
  119. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  120. }
  121. else if(st_SendData->u8DesiredGearBoxMode == WORKMODE_AUTO)//如果是自动模式
  122. {
  123. sendbuf[0] = st_SendData->u8DesiredGearBoxMode;
  124. sendbuf[1] = 0X00;
  125. sendbuf[2] = 0X00;
  126. sendbuf[3] = (uint8_t)(st_SendData->u16DesiredCanence>>8);
  127. sendbuf[4] = (uint8_t)(st_SendData->u16DesiredCanence);
  128. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  129. }
  130. else if(st_SendData->u8DesiredGearBoxMode == WORKMODE_CALIB)//校准模式
  131. {
  132. if(st_Calib->u8CalibrationCmdToEnviolo == 1)//第一次关闭自动变速器
  133. {
  134. sendbuf[0] = 0X00;
  135. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  136. st_Calib->u8CalibrationCmdToEnviolo++;
  137. }
  138. else if(st_Calib->u8CalibrationCmdToEnviolo == 2)//第二次让enviolo进入到校准指令中
  139. {
  140. sendbuf[0] = 0X08;
  141. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  142. st_Calib->u8CalibrationCmdToEnviolo++;
  143. }
  144. else if(st_Calib->u8CalibrationCmdToEnviolo == 3)//第三次使能enviolo的ACTIVE模式
  145. {
  146. sendbuf[0] = 0X01;//开启变速器的数据报文模式做监听 Active
  147. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  148. st_Calib->u8CalibrationCmdToEnviolo++;
  149. st_Calib->u8CalibrationCmdToOBC = DIS_PEDALLING;//让ui显示校准中
  150. }
  151. }
  152. else
  153. {
  154. sendbuf[0] = WORKMODE_OFF; //关闭
  155. sendbuf[1] = 0X00;
  156. sendbuf[2] = 0X00;
  157. sendbuf[3] = 0X00;
  158. sendbuf[4] = 0X00;
  159. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  160. }
  161. }
  162. }
  163. /******************************************************************************
  164. * @Function: 200MS发送报文到OBC
  165. * @Discrible: 通过报文的设置让enviolo进入到不同的UI界面
  166. * @Param:
  167. * @Return: void
  168. * @Others:
  169. ******************************************************************************
  170. * @Recode date version author modify
  171. * ------------------------------------------------------------------
  172. * 20211025 V1.0.0 leechard create
  173. *
  174. *******************************************************************************/
  175. void sendDataToOBC(uint8_t u8Step)
  176. {
  177. static uint8_t u8OldStep = 0;
  178. uint8_t sendbuf[8]={MC_ConfigParam1.WheelSize,MC_ConfigParam1.StarModel,MC_ConfigParam1.SpeedLimit,MC_ConfigParam1.WheelSizeAdj,0X00,0X00,0X00,0X00};//轮胎默认周长,启动模式,限速值,轮胎微调值
  179. if(u8OldStep != u8Step)
  180. {
  181. switch(u8Step)
  182. {
  183. case 1:
  184. {
  185. sendbuf[4] = 0x01;//UI界面提示需要校准
  186. break;
  187. }
  188. case 2:
  189. {
  190. sendbuf[4] = 0x02;//UI界面显示校准中
  191. break;
  192. }
  193. case 3:
  194. {
  195. sendbuf[4] = 0x00;//UI界面显示校准完成
  196. break;
  197. }
  198. default:
  199. {
  200. break;
  201. }
  202. }
  203. u8OldStep = u8Step;
  204. SendData(ID_MC_TO_PBU, MODE_REPORT, 0x5408, sendbuf);
  205. }
  206. }
  207. /******************************************************************************
  208. * @Function: 收到关机指令则发送关闭enviolo的报文
  209. * @Discrible: 关机前最后一帧报文
  210. * @Param:
  211. * @Return: void
  212. * @Others:
  213. ******************************************************************************
  214. * @Recode date version author modify
  215. * ------------------------------------------------------------------
  216. * 20211025 V1.0.0 leechard create
  217. *
  218. *******************************************************************************/
  219. void sendDataToEnvioloPwroff(void)
  220. {
  221. uint8_t sendbuf[8]={0};
  222. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  223. }
  224. /******************************************************************************
  225. * @Function: 解析enviolo发过来的报文
  226. * @Discrible: 解析8字节报文数据
  227. * @Param: 8字节报文数据
  228. * @Return: void
  229. * @Others:
  230. ******************************************************************************
  231. * @Recode date version author modify
  232. * ------------------------------------------------------------------
  233. * 20211203 V1.0.0 leechard create
  234. *
  235. *******************************************************************************/
  236. void Slot_EnvioloData(uint8_t *u8Data, Calibration_Struct_t *Calib)
  237. {
  238. CanEnvioloData.u8Get_Gear_Pedal_RPM = u8Data[0]; //反馈的踏频值 cadence
  239. CanEnvioloData.u8Get_Gear_CVP_Actuel_Ratio = u8Data[1]; //实际的档位值 1bit = 0.1ratio
  240. CanEnvioloData.u16Get_Gear_Vehicle_Speed = (u8Data[2])*5; //当前速度 乘以0.5 eg:50=25km/h 文档协议单位为0.1,故乘以5
  241. CanEnvioloData.flGet_Gear_Battery_Voltage = (u8Data[3])*0.25; //当前电压值 乘以0.25 eg:102=25.5km/h
  242. CanEnvioloData.u16Get_Gear_Wheel_RPM = (uint16_t)(u8Data[4]<<8)|(uint16_t)(u8Data[5]); //车轮转速 需要设置车子周长
  243. CanEnvioloData.u16CalibrationVal = (uint16_t)(u8Data[6]<<8)|(uint16_t)(u8Data[7]); //获取是否需要校准
  244. //以下为校准信息的判断
  245. if((CanEnvioloData.u16CalibrationVal&0X1000) == 0X1000) //bit51:Calibration Needed
  246. {
  247. Calib->u8CalibrationCmdToOBC = DIS_PEDAL;//需要校准
  248. }
  249. else if((CanEnvioloData.u16CalibrationVal&0X2000) == 0X2000)//校准完成 //bit50:Calibration Success
  250. {
  251. Calib->u8CalibrationCmdToOBC = DIS_SUCCESS;//校准成功并完成
  252. Calib->u8CalibrationCmdToEnviolo = 0;
  253. Calib->u8CalibrationCmdToOBC = 0;
  254. }
  255. if(MC_SpeedSensorData.IsStopFlag == TRUE)
  256. {
  257. MC_SpeedSensorData.IsStopFlag = FALSE;
  258. }
  259. CanEnvioloData.u16Timeout_Communication = 0;
  260. }
  261. /******************************************************************************
  262. * @Function: enviolo通信检测,超时则报错
  263. * @Discrible:
  264. * @Param:
  265. * @Return: void
  266. * @Others:
  267. ******************************************************************************
  268. * @Recode date version author modify
  269. * ------------------------------------------------------------------
  270. * 20211203 V1.0.0 leechard create
  271. *
  272. *******************************************************************************/
  273. void MC_Fault_Enviolo_SpeedSensor_Process(MC_ErrorCode_Struct_t* p_MC_ErrorCode)
  274. {
  275. if(p_MC_ErrorCode->ERROR_Bit.Fault_SpeedSensor == 0)
  276. {
  277. if(CanEnvioloData.u16Timeout_Communication >= COMMUNICATION_TIMEOUT)
  278. {
  279. p_MC_ErrorCode->ERROR_Bit.Fault_SpeedSensor = 1;
  280. //记录故障日志
  281. MC_ErrorLogSaveInfo.NotesInfo1 = 1;
  282. ErrorLogSave_Update(&MC_ErrorLogSaveInfo);
  283. IsErrorLogSaveInfoUpdateFlag = TRUE;
  284. //存储故障次数
  285. MC_RunLog1.SPS_FaultCnt++;
  286. RunLogSaveIndex = 1;
  287. }
  288. }
  289. }