#include "can_process.h" #include "usart.h" /**********局部函数定义**********/ uint8_t cd_ReadChar(CAN_Buf_TypeDef * ptCANRx, uint8_t ucNum) { uint8_t ucData; uint16_t i; i = ucNum; if ((*ptCANRx).ucBufCnt >= ucNum) { i += (*ptCANRx).ucBufRdInde; if (i >= (*ptCANRx).ucBufSize) { i -=((*ptCANRx).ucBufSize); } } else { i=0; } ucData = *((*ptCANRx).pcBufAddr + i); return ucData; } void cd_DelChar(CAN_Buf_TypeDef * ptCANRx, uint8_t ucNum) { uint16_t i; if ((*ptCANRx).ucBufCnt >= ucNum) { __HAL_CAN_DISABLE_IT(&hcan, CAN_IT_FMP0);//关接收中断 (*ptCANRx).ucBufCnt -= ucNum; __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);//开接收中断 i = ucNum; i += (*ptCANRx).ucBufRdInde; if (i >= (*ptCANRx).ucBufSize) { i -= (*ptCANRx).ucBufSize; } (*ptCANRx).ucBufRdInde = i; } else { __HAL_CAN_DISABLE_IT(&hcan, CAN_IT_FMP0);//关接收中断 i = (*ptCANRx).ucBufCnt; (*ptCANRx).ucBufCnt = 0; __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);//开接收中断 i += (*ptCANRx).ucBufRdInde; if (i >= (*ptCANRx).ucBufSize) { i -= (*ptCANRx).ucBufSize; } (*ptCANRx).ucBufRdInde = i; } } //数据解析处理 void DataProcess(uint16_t ID, uint8_t Mode, uint16_t Cmd, uint8_t* Data) { uint8_t DataLength; DataLength = (uint8_t)(Cmd &0x00FF); switch(ID) { //处理MC发送的指令 case ID_MC_BC: case ID_MC_TO_PBU: { PowerOn_flag=1; MC_Online_Flag=1; MC_Online_TimeCnt=SysTime_5ms; switch(Cmd) { //MC广播的指令 case 0x1020://MC广播运行信息 { memcpy((uint8_t*)&MC_RunInfo.BikeSpeed, Data, sizeof(MC_RunInfo_Struct_t)); break; } case 0x1104://MC广播故障码 { MC_error_cnt=0; memcpy((uint8_t*)&MC_ErrorCode.Code, Data, sizeof(MC_ErrorCode_Struct_t)); break; } case 0x1305://MC关机就绪 { if(strncmp("READY", (char*)Data, DataLength) == 0) { PBU_PowerOff_Process.Ready_Status.Status_Bit.MC = 1; } break; } //MC发送给PBU的指令 case 0x5009://在线检测 { if(strncmp("HANDSHAKE", (char*)Data, DataLength) == 0) { SendData(ID_PBU_TO_MC, MODE_REPORT, 0x3105, (uint8_t*)"READY"); } break; } case 0x5100://查询物理ID { SendData(ID_PBU_BC, MODE_REPORT, 0x120C, (uint8_t*)PBU_CheckInfo.MAC_ID); break; } case 0x5200://查询校验码 { SendData(ID_PBU_BC, MODE_REPORT, 0x130C, (uint8_t*)PBU_CheckInfo.CheckCode); break; } case 0x5303://用户参数配置反馈 { if(strncmp("ACK", (char*)Data, DataLength) == 0) { PBU_MC_Cfg.MC_ACK_Flag = TRUE; } break; } default:break; } break; } //处理BMS发送的指令 case ID_BMS_BC: case ID_BMS_TO_PBU: { BMS_Online_Flag = 1; BMS_Online_TimeCnt=SysTime_5ms; switch(Cmd) { //BMS广播的指令 case 0x1010://BMS广播运行信息 { memcpy((uint8_t*)&BMS_RunInfo.Voltage, Data, sizeof(BMS_RunInfo_Struct_t)); if(BMS_RunInfo.Status.Status_Bit.Charge == 0x01) //电池连续发送7次进入充电状态,按键才进入充电状态 { BMS_Charging_count++; if(BMS_Charging_count>6) { BMS_Charging_count=0; BMS_ChargingFlag = TRUE; } } else { BMS_Charging_count=0; BMS_ChargingFlag = FALSE; } break; } case 0x1204://BMS广播故障码 { memcpy((uint8_t*)&BMS_ErrorCode.Code, Data, sizeof(BMS_ErrorCode_Struct_t)); break; } case 0x1308://BMS广播关机指令 { if(strncmp("SHUTDOWN", (char*)Data, DataLength) == 0) { //...处理存储关键信息 SendData(ID_PBU_BC, MODE_REPORT, 0x1405, (uint8_t*)"READY"); } break; } } break; } //处理HMI发送的指令 case ID_HMI_BC: case ID_HMI_TO_PBU: //处理CDL发送的指令 case ID_CDL_BC: case ID_CDL_TO_PBU: { switch(Cmd) { case 0x5000://查询PBU物理ID { SendData(ID_PBU_BC, MODE_REPORT, 0x120C, (uint8_t*)(PBU_CheckInfo.MAC_ID)); break; } case 0x5100://查询校验码 { SendData(ID_PBU_BC, MODE_REPORT, 0x130C, (uint8_t*)PBU_CheckInfo.CheckCode); break; } case 0x520C://写入校验码 { if(strncmp((char*)PBU_CheckInfo.CheckCode, (char*)Data, DataLength) != 0) { memcpy(PBU_CheckInfo.CheckCode, Data, 12); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x5300://查询PBU生产信息 { SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9420, (uint8_t*)PBU_MacInfo.Manufacturer); break; } case 0x5400://查询PBU版本信息 { SendData(ID_PBU_BC, MODE_REPORT, 0x1140, (uint8_t*)PBU_VerInfo.Mode); break; } case 0x5504://进入按键测试模式 { if(strncmp("STAR", (char*)Data, DataLength) == 0) { PBU_RunMode = PBU_RunMode_CDL_KeyTest; SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); } else if(strncmp("STOP", (char*)Data, DataLength) == 0) { PBU_RunMode = PBU_RunMode_MC_AssisitCtrl; SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); } break; } case 0x5600://查询PBU历史信息 { SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9310, (uint8_t*)&PBU_RunLog.RunTime); break; } case 0x5700://查询PBU出厂参数 { SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9210, &PBU_ConfigParam.RatedVoltage); break; } case 0x5810://写入PBU出厂参数 { // if(strncmp((char*)&PBU_ConfigParam.RatedVoltage, (char*)Data, DataLength) != 0) { memcpy(&PBU_ConfigParam.RatedVoltage, Data, 16); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x5900://查询自定义字符串1 { SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9510, (uint8_t*)UserString1); break; } case 0x5A10://写入自定义字符串1 { if(strncmp((char*)UserString1, (char*)Data, DataLength) != 0) { memcpy(UserString1, Data, 16); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x5B00://查询自定义字符串2 { SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9610, (uint8_t*)UserString2); break; } case 0x5C10://写入自定义字符串2 { if(strncmp((char*)UserString2, (char*)Data, DataLength) != 0) { memcpy(UserString2, Data, 16); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x5D00://查询自定义字符串3 { SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9710, (uint8_t*)UserString3); break; } case 0x5E10://写入自定义字符串3 { if(strncmp((char*)UserString3, (char*)Data, DataLength) != 0) { memcpy(UserString3, Data, 16); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x5F20://写入生产信息 { if(strncmp((char*)PBU_MacInfo.Manufacturer, (char*)Data, DataLength) != 0) { memcpy(PBU_MacInfo.Manufacturer, Data, 32); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x6010://写入Mode { if(strncmp((char*)PBU_VerInfo.Mode, (char*)Data, DataLength) != 0) { memcpy(PBU_VerInfo.Mode, Data, 16); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x6110://写入SN { if(strncmp((char*)PBU_VerInfo.SN_Num, (char*)Data, DataLength) != 0) { memcpy(PBU_VerInfo.SN_Num, Data, 16); EEPROM_DataUpdate(); } SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); break; } case 0x6205://复位指令 { if(strncmp("RESET", (char*)Data, DataLength) == 0) { SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK"); HAL_Delay(200); __set_FAULTMASK(1);//关闭所有中断 HAL_NVIC_SystemReset(); } break; } } break; } case ID_CDL_TO_PBU_TE://0x653 { switch(Cmd) { case 0x6205://复位指令 case 0xA10B://升级指令 PBU_TE_Status = UPDATE_ING; PBU_RunMode = PBU_RunMode_Updating; break; default: break; } SendUartDataToTE(ID_CDL_TO_PBU_TE,Mode, Cmd, Data); break; } default: break; } } /*********************End*******************/ /************全局函数定义*******************/ void CAN_RxData_Process(CAN_Buf_TypeDef* ptCANRx, uint16_t TimeOutCnt) { uint8_t Mode, CmdLength, DataLength, Data[150], CRC_Buf[150]; uint16_t Cmd, i; uint32_t CrcResult, CrcData; uint8_t FrameBegin1, FrameBegin2; if(ptCANRx->ucBufCnt >= 11) { //读取帧头 FrameBegin1 = cd_ReadChar(ptCANRx, 0); CRC_Buf[0] = FrameBegin1; FrameBegin2 = cd_ReadChar(ptCANRx, 1); CRC_Buf[1] = FrameBegin2; if((FrameBegin1 == FRAME_BEGIN1) && (FrameBegin2 == FRAME_BEGIN2)) { CRC_Buf[2] = (uint8_t)((ptCANRx->ucBufID >> 8) & 0xFF); CRC_Buf[3] = (uint8_t)(ptCANRx->ucBufID & 0xFF); //读取帧模式 Mode = cd_ReadChar(ptCANRx, 2); CRC_Buf[4] = Mode; if((Mode == MODE_READ) || (Mode == MODE_WRITE) || (Mode == MODE_REPORT)) { //读取命令段长度和命令字 CmdLength = cd_ReadChar(ptCANRx, 3); CRC_Buf[5] = CmdLength; Cmd = (cd_ReadChar(ptCANRx, 4) << 8) + cd_ReadChar(ptCANRx, 5); CRC_Buf[6] = (uint8_t)((Cmd >> 8) & 0xFF); CRC_Buf[7] = (uint8_t)(Cmd & 0xFF); DataLength = cd_ReadChar(ptCANRx, 5); if((CmdLength - DataLength) == 2) { if(ptCANRx->ucBufCnt < (CmdLength + 9))//帧头2bytes + 模式1byte + 命令段长度1byte + 校验位4bytes + 帧尾1byte { if(ptCANRx->IsWaitRX_Flag == FALSE) { ptCANRx->DelayTimeCnt = HAL_GetTick(); ptCANRx->IsWaitRX_Flag = TRUE; } if((HAL_GetTick() - ptCANRx->DelayTimeCnt) > TimeOutCnt)//超时,单位ms { cd_DelChar(ptCANRx, ptCANRx->ucBufCnt); ptCANRx->IsWaitRX_Flag = FALSE; } return; } else { ptCANRx->IsWaitRX_Flag = FALSE; //接收到完整正确数据包 for(i=0; iucBufID, Mode, Cmd, Data);//Mode为帧模式,Cmd为命令字,Data为数据段 cd_DelChar(ptCANRx, CmdLength + 9); return; } cd_DelChar(ptCANRx, 1); } } else { cd_DelChar(ptCANRx, 1); } } else { cd_DelChar(ptCANRx, 1); } } else { cd_DelChar(ptCANRx, 1); } } } //数据解析,忽略命令字表示的数据长度 void CAN_RxData_Process_Temp(CAN_Buf_TypeDef* ptCANRx, uint16_t TimeOutCnt) { uint8_t Mode, CmdLength, DataLength, Data[150], CRC_Buf[150]; uint16_t Cmd, i; uint32_t CrcResult, CrcData; uint8_t FrameBegin1, FrameBegin2; if(ptCANRx->ucBufCnt >= 11) { //读取帧头 FrameBegin1 = cd_ReadChar(ptCANRx, 0); CRC_Buf[0] = FrameBegin1; FrameBegin2 = cd_ReadChar(ptCANRx, 1); CRC_Buf[1] = FrameBegin2; if((FrameBegin1 == FRAME_BEGIN1) && (FrameBegin2 == FRAME_BEGIN2)) { CRC_Buf[2] = (uint8_t)((ptCANRx->ucBufID >> 8) & 0xFF); CRC_Buf[3] = (uint8_t)(ptCANRx->ucBufID & 0xFF); //读取帧模式 Mode = cd_ReadChar(ptCANRx, 2); CRC_Buf[4] = Mode; if((Mode == MODE_READ) || (Mode == MODE_WRITE) || (Mode == MODE_REPORT)) { //读取命令段长度和命令字 CmdLength = cd_ReadChar(ptCANRx, 3); CRC_Buf[5] = CmdLength; Cmd = (cd_ReadChar(ptCANRx, 4) << 8) + cd_ReadChar(ptCANRx, 5); CRC_Buf[6] = (uint8_t)((Cmd >> 8) & 0xFF); CRC_Buf[7] = (uint8_t)(Cmd & 0xFF); DataLength = CmdLength - 2; if(ptCANRx->ucBufCnt < (CmdLength + 9))//帧头2bytes + 模式1byte + 命令段长度1byte + 校验位4bytes + 帧尾1byte { if(ptCANRx->IsWaitRX_Flag == FALSE) { ptCANRx->DelayTimeCnt = HAL_GetTick(); ptCANRx->IsWaitRX_Flag = TRUE; } if((HAL_GetTick() - ptCANRx->DelayTimeCnt) > TimeOutCnt)//超时,单位ms { cd_DelChar(ptCANRx, ptCANRx->ucBufCnt); ptCANRx->IsWaitRX_Flag = FALSE; } return; } else { ptCANRx->IsWaitRX_Flag = FALSE; //接收到完整正确数据包 for(i=0; iucBufID, Mode, Cmd, Data);//Mode为帧模式,Cmd为命令字,Data为数据段 cd_DelChar(ptCANRx, CmdLength + 9); return; } cd_DelChar(ptCANRx, 1); } } else { cd_DelChar(ptCANRx, 1); } } else { cd_DelChar(ptCANRx, 1); } } } void SendData(uint16_t ID, uint8_t Mode, uint16_t Command, uint8_t* Data) { uint8_t SendBuf[150] = {0}; uint8_t CRC_Buf[150] = {0}; uint32_t CRC_Result = 0x00000000; uint8_t i; uint8_t DataLength; DataLength = (uint8_t)(Command & 0xFF); SendBuf[0] = FRAME_BEGIN1; CRC_Buf[0] = SendBuf[0]; SendBuf[1] = FRAME_BEGIN2; CRC_Buf[1] = SendBuf[1]; CRC_Buf[2] = (uint8_t)((ID >> 8) & 0xFF); CRC_Buf[3] = (uint8_t)(ID & 0xFF); SendBuf[2] = Mode; CRC_Buf[4] = SendBuf[2]; SendBuf[3] = DataLength + 2; CRC_Buf[5] = SendBuf[3]; SendBuf[4] = (uint8_t)((Command >> 8) & 0xFF); CRC_Buf[6] = SendBuf[4]; SendBuf[5] = DataLength; CRC_Buf[7] = SendBuf[5]; for(i = 0;i< DataLength;i++) { SendBuf[6 + i] = Data[i]; CRC_Buf[8 + i] = SendBuf[6 + i]; } CRC_Result = CRC32_Calculate(CRC_Buf, DataLength + 8);//帧头 2bytes + ID 2bytes + 模式 1byte + 命令段长度 1byte + 命令字 2bytes SendBuf[6 + DataLength] = (uint8_t)((CRC_Result >> 24) & 0xFF); SendBuf[7 + DataLength] = (uint8_t)((CRC_Result >> 16) & 0xFF); SendBuf[8 + DataLength] = (uint8_t)((CRC_Result >> 8) & 0xFF); SendBuf[9 + DataLength] = (uint8_t)(CRC_Result & 0xFF); SendBuf[10 + DataLength] = FRAME_END; CAN_SendData(ID, SendBuf, DataLength + 11); } /********************End********************/