#include "enviolo_can.h" #include "can.h" #include "speed_sensor.h" #include "motor_control.h" #include "log_save.h" #include "can_process.h" #include "eeprom_24c02.h" Enviolo_Struct_t CanEnvioloData = {0}; Enviolo_SetVal_Struct_t EnvioloSetData = {0}; Calibration_Struct_t Enviolo_Calibration = {0}; //计算1~9档位对应的变速比,范围为500~1800 const uint16_t Ratio_Table[9] = { 500, 662, 824, 986, 1148, 1310, 1472, 1634, 1800 }; /****************************************************************************** * @Function: 解析CAN报文,提取OBC发送的报文信息提取需要设置的目标踏频值和档位比例值 * @Discrible: 查看协议文档ID(0X731)-->0X4008的报文 * @Param: Data:需要分析的报文 RetVal:需要设置的值 * @Return: void * @Others: ****************************************************************************** * @Recode date version author modify * ------------------------------------------------------------------ * 20211025 V1.0.0 leechard create * *******************************************************************************/ void GetWorkSetVal(uint8_t* Data, Enviolo_SetVal_Struct_t *RetVal, Calibration_Struct_t *Calib) { static uint8_t u8Temp = 0; if(Data[2] == NOTNEED_CALIB)//无需校准 { if(Data[0] == WORKMODE_AUTO)//自动模式 { RetVal->u8DesiredGearBoxMode = WORKMODE_AUTO; RetVal->u16DesiredGearRatio = 0; RetVal->u16DesiredCanence = Data[1]; } else if(Data[0] == WORKMODE_MANUAL)//手动模式 { RetVal->u8DesiredGearBoxMode = WORKMODE_MANUAL; //根据手动设置的档位计算需要设置的变速比例值 RetVal->u16DesiredGearRatio = (Data[1] == 0)?Ratio_Table[0]:((Data[1]>8)?Ratio_Table[8]:Ratio_Table[Data[1]-1]); RetVal->u16DesiredCanence = 0; } u8Temp = 0; } else if(Data[2] == NEED_CALIB)//需要校准 { RetVal->u8DesiredGearBoxMode = WORKMODE_CALIB; if(u8Temp == 0) { Calib->u8CalibrationCmdToEnviolo = 1; u8Temp = 1; } } } /****************************************************************************** * @Function: 200MS发送报文到enviolo,默认5min不发送报文则enviolo自动休眠 * @Discrible: 通过工作模式设置相应的值到enviolo * @Param: * @Return: void * @Others: ****************************************************************************** * @Recode date version author modify * ------------------------------------------------------------------ * 20211025 V1.0.0 leechard create * *******************************************************************************/ void sendDataToEnviolo(Enviolo_SetVal_Struct_t *st_SendData, Calibration_Struct_t *st_Calib) { static uint8_t u8SendCnt = 0; uint8_t sendbuf[8]={0}; //发送100次控制指令后再发送一次配置指令 u8SendCnt++; if(u8SendCnt >= 100) { u8SendCnt = 0; CanEnvioloData.u8SendConfigDataToEnviolo = SEND_CONFIG; } //参数配置只发送一次 if(CanEnvioloData.u8SendConfigDataToEnviolo == SEND_CONFIG) { if((st_SendData->u8DesiredGearBoxMode == WORKMODE_MANUAL)||(st_SendData->u8DesiredGearBoxMode == WORKMODE_AUTO)) { GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_CONFIG_PARAM1, sizeof(MC_ConfigParam1), (uint8_t*)&MC_ConfigParam1.GasCtrlMode_Flag); sendbuf[0] = MC_ConfigParam1.TeethNum_F*2.4; //DU_Front_Chainring sendbuf[1] = MC_ConfigParam1.TeethNum_B; //DU_RearSprocket sendbuf[2] = DU_CADENCE_LOWLIMIT; //DU_Cadence_LowLimit sendbuf[3] = DU_CADENCE_HIGHLIMIT; //DU_Cadence_HighLimit sendbuf[4] = 0x00; //Reserved sendbuf[5] = (MC_ConfigParam1.WheelSize > 100)?(MC_ConfigParam1.WheelSize - 100):0;// sendbuf[6] = DU_SLEEPTIME; //DU_SleepTime sendbuf[7] = 0x00; //Reserved CAN_SendData(ID_ENVIOLO_CONFIG, sendbuf, sizeof(sendbuf)); CanEnvioloData.u8SendConfigDataToEnviolo = SEND_DATA; } } else if(CanEnvioloData.u8SendConfigDataToEnviolo == SEND_DATA) { if((MC_ControlCode.GearSt == MC_GearSt_WALK)||(MC_ControlCode.GearSt == MC_GearSt_OFF))//推行模式和0档位将档位设置为最低档 { sendbuf[0] = WORKMODE_MANUAL; sendbuf[1] = (uint8_t)(Ratio_Table[0]>>8); sendbuf[2] = (uint8_t)(Ratio_Table[0]); sendbuf[3] = 0X00; sendbuf[4] = 0X00; CAN_SendData(ID_ENVIOLO_CONTROL, sendbuf, sizeof(sendbuf)); } else { if(st_SendData->u8DesiredGearBoxMode == WORKMODE_MANUAL)//如果是手动模式 { sendbuf[0] = st_SendData->u8DesiredGearBoxMode; sendbuf[1] = (uint8_t)(st_SendData->u16DesiredGearRatio>>8); sendbuf[2] = (uint8_t)(st_SendData->u16DesiredGearRatio); sendbuf[3] = 0X00; sendbuf[4] = 0X00; CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf)); } else if(st_SendData->u8DesiredGearBoxMode == WORKMODE_AUTO)//如果是自动模式 { sendbuf[0] = st_SendData->u8DesiredGearBoxMode; sendbuf[1] = 0X00; sendbuf[2] = 0X00; sendbuf[3] = (uint8_t)(st_SendData->u16DesiredCanence>>8); sendbuf[4] = (uint8_t)(st_SendData->u16DesiredCanence); CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf)); } else if(st_SendData->u8DesiredGearBoxMode == WORKMODE_CALIB)//校准模式 { if(st_Calib->u8CalibrationCmdToEnviolo == 1)//第一次关闭自动变速器 { sendbuf[0] = 0X00; CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf)); st_Calib->u8CalibrationCmdToEnviolo++; } else if(st_Calib->u8CalibrationCmdToEnviolo == 2)//第二次让enviolo进入到校准指令中 { sendbuf[0] = 0X08; CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf)); st_Calib->u8CalibrationCmdToEnviolo++; } else if(st_Calib->u8CalibrationCmdToEnviolo == 3)//第三次使能enviolo的ACTIVE模式 { sendbuf[0] = 0X01;//开启变速器的数据报文模式做监听 Active CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf)); st_Calib->u8CalibrationCmdToEnviolo++; st_Calib->u8CalibrationCmdToOBC = DIS_PEDALLING;//让ui显示校准中 } } else { sendbuf[0] = WORKMODE_OFF; //关闭 sendbuf[1] = 0X00; sendbuf[2] = 0X00; sendbuf[3] = 0X00; sendbuf[4] = 0X00; CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf)); } } } } /****************************************************************************** * @Function: 200MS发送报文到OBC * @Discrible: 通过报文的设置让enviolo进入到不同的UI界面 * @Param: * @Return: void * @Others: ****************************************************************************** * @Recode date version author modify * ------------------------------------------------------------------ * 20211025 V1.0.0 leechard create * *******************************************************************************/ void sendDataToOBC(uint8_t u8Step) { static uint8_t u8OldStep = 0; uint8_t sendbuf[8]={MC_ConfigParam1.WheelSize,MC_ConfigParam1.StarModel,MC_ConfigParam1.SpeedLimit,MC_ConfigParam1.WheelSizeAdj,0X00,0X00,0X00,0X00};//轮胎默认周长,启动模式,限速值,轮胎微调值 if(u8OldStep != u8Step) { switch(u8Step) { case 1: { sendbuf[4] = 0x01;//UI界面提示需要校准 break; } case 2: { sendbuf[4] = 0x02;//UI界面显示校准中 break; } case 3: { sendbuf[4] = 0x00;//UI界面显示校准完成 break; } default: { break; } } u8OldStep = u8Step; SendData(ID_MC_TO_PBU, MODE_REPORT, 0x5408, sendbuf); } } /****************************************************************************** * @Function: 收到关机指令则发送关闭enviolo的报文 * @Discrible: 关机前最后一帧报文 * @Param: * @Return: void * @Others: ****************************************************************************** * @Recode date version author modify * ------------------------------------------------------------------ * 20211025 V1.0.0 leechard create * *******************************************************************************/ void sendDataToEnvioloPwroff(void) { uint8_t sendbuf[8]={0}; CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,8); } /****************************************************************************** * @Function: 解析enviolo发过来的报文 * @Discrible: 解析8字节报文数据 * @Param: 8字节报文数据 * @Return: void * @Others: ****************************************************************************** * @Recode date version author modify * ------------------------------------------------------------------ * 20211203 V1.0.0 leechard create * *******************************************************************************/ void Slot_EnvioloData(uint8_t *u8Data, Calibration_Struct_t *Calib) { CanEnvioloData.u8Get_Gear_Pedal_RPM = u8Data[0]; //反馈的踏频值 cadence CanEnvioloData.u8Get_Gear_CVP_Actuel_Ratio = u8Data[1]; //实际的档位值 1bit = 0.1ratio CanEnvioloData.u16Get_Gear_Vehicle_Speed = (u8Data[2])*5; //当前速度 乘以0.5 eg:50=25km/h 文档协议单位为0.1,故乘以5 CanEnvioloData.flGet_Gear_Battery_Voltage = (u8Data[3])*0.25; //当前电压值 乘以0.25 eg:102=25.5km/h CanEnvioloData.u16Get_Gear_Wheel_RPM = (uint16_t)(u8Data[4]<<8)|(uint16_t)(u8Data[5]); //车轮转速 需要设置车子周长 CanEnvioloData.u16CalibrationVal = (uint16_t)(u8Data[6]<<8)|(uint16_t)(u8Data[7]); //获取是否需要校准 //以下为校准信息的判断 if((CanEnvioloData.u16CalibrationVal&0X1000) == 0X1000) //bit51:Calibration Needed { Calib->u8CalibrationCmdToOBC = DIS_PEDAL;//需要校准 } else if((CanEnvioloData.u16CalibrationVal&0X2000) == 0X2000)//校准完成 //bit50:Calibration Success { Calib->u8CalibrationCmdToOBC = DIS_SUCCESS;//校准成功并完成 Calib->u8CalibrationCmdToEnviolo = 0; Calib->u8CalibrationCmdToOBC = 0; } if(MC_SpeedSensorData.IsStopFlag == TRUE) { MC_SpeedSensorData.IsStopFlag = FALSE; } CanEnvioloData.u16Timeout_Communication = 0; } /****************************************************************************** * @Function: enviolo通信检测,超时则报错 * @Discrible: * @Param: * @Return: void * @Others: ****************************************************************************** * @Recode date version author modify * ------------------------------------------------------------------ * 20211203 V1.0.0 leechard create * *******************************************************************************/ void MC_Fault_Enviolo_SpeedSensor_Process(MC_ErrorCode_Struct_t* p_MC_ErrorCode) { if(p_MC_ErrorCode->ERROR_Bit.Fault_SpeedSensor == 0) { if(CanEnvioloData.u16Timeout_Communication >= COMMUNICATION_TIMEOUT) { p_MC_ErrorCode->ERROR_Bit.Fault_SpeedSensor = 1; //记录故障日志 MC_ErrorLogSaveInfo.NotesInfo1 = 3; ErrorLogSave_Update(&MC_ErrorLogSaveInfo); IsErrorLogSaveInfoUpdateFlag = TRUE; //存储故障次数 MC_RunLog1.SPS_FaultCnt++; RunLogSaveIndex = 1; } } }