//******************************************************************** // Ver 1.0 // 2021.11.19 1、新建文件。 // 2022.08.18 2、修正读取警告标志为0问题。 //******************************************************************** #include "config.h" SCP_Str SCP_Info; void SCP_Init(void) { SCP_InfoInit(); UART_Init(UART0, 115200, UART_LEN_8BITS, UART_STOP_1BITS, UART_PARITY_NONE); //RS485_GpioInit(); } void SCP_SetOverTime(INT32U Value) { SCP_Info.CommCnt = Value * 1000 / 100; BATT_FLAG_COMM0OVT = 0; } void SCP_OverTimeCount(void) { if(SCP_OverTimeCnt > 0) { SCP_OverTimeCnt --; } else if(BATT_FLAG_COMM0OVT == 0) { BATT_FLAG_COMM0OVT = 1; } } //和校验 /* INT8U SumCheck(INT8U *ptr, INT32U Len) { INT8U tSumCheck = 0; while (Len--) { tSumCheck += (*ptr); ptr++; } return (tSumCheck); } */ void SCP_ErrorReport(INT8U ErrorCode) { //SCP_Info.SendBuff.Head = SCP_HEAD; SCP_Info.SendBuff.AddrDes = SCP_Info.SendBuff.AddrSrc; SCP_Info.SendBuff.AddrSrc = SCP_BMS_ADDR; SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = ErrorCode; SCP_Info.SendBuff.CheckSum = CRC16((INT8U *) & (SCP_Info.SendBuff.Head), (SCP_Info.SendBuff.Len + 6)); SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 0] = (INT8U)(SCP_Info.SendBuff.CheckSum >> 0); SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 1] = (INT8U)(SCP_Info.SendBuff.CheckSum >> 8); SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 2] = SCP_END1; SCP_Send((INT8U *) & (SCP_Info.SendBuff.Head), (SCP_Info.SendBuff.Len + 9)); } void SCP_RunInfoFill(void) { BATT_Info.Status.Voltage = BATT_Voltage / 10; BATT_Info.Status.Current = BATT_Current / 10; if(BATT_TsFet > BATT_TsMax) { BATT_Info.Status.MaxTemp = BATT_TsFet; } else { BATT_Info.Status.MaxTemp = BATT_TsMax; } BATT_Info.Status.Temp = BATT_Temp; BATT_Info.Status.Soc = BATT_Rsoc; BATT_Info.Status.RemainingCapacity = BATT_RC / 10; BATT_Info.Status.Status.WORDS = 0; //BATT_Info.Status.Status.BYTES[1] = 0; //BATT_Info.Status.Alarm.BYTES[0] = 0; //2022.08.18 注释此处清0操作,解决读取标志位为0问题 //BATT_Info.Status.Alarm.BYTES[1] = 0; if(BATT_FLAG_STA == STA_IDLE) { BATT_Info.Status.Status.BITS.IDLE = 1; } else { BATT_Info.Status.Status.BITS.CHG = BATT_FLAG_CHG; BATT_Info.Status.Status.BITS.DSG = BATT_FLAG_DSG; } BATT_Info.Status.Status.BITS.CFET = BATT_FLAG_CFET; BATT_Info.Status.Status.BITS.DFET = BATT_FLAG_DFET; BATT_Info.Status.Status.BITS.SOCL = BATT_FLAG_SOCL; BATT_Info.Status.Status.BITS.BAL = ((BATT_FLAG_BAL == 2) ? 1 : 0); BATT_Info.Status.Status.BITS.FC = (BATT_FLAG_FC != 0) ? 1 : 0; BATT_Info.Status.Status.BITS.WAKEON = BATT_FLAG_ON; //BATT_Info.Status.Status.BITS.CHGON = (BATT_FLAG_ON & 0x02) ? 1 : 0; BATT_Info.Status.Status.BITS.BALE = BATT_FLAG_BALE; BATT_Info.Status.Status.BITS.CRGLINK = BATT_FLAG_CRGLINK; BATT_Info.Status.Status.BITS.PDSG = BATT_FLAG_PCFET; BATT_Info.Status.Status.BITS.LOCKF = FET_FLAG_LOCK; BATT_Info.Status.Status.BITS.P5VOUT = PWR5V_Sta(); BATT_Info.Status.Status.BITS.P5VEN = BATT_FLAG_P5VEN; //2022.08.24 增加P5VEN标志,指示灯板5V使能状态。 /*BATT_Info.Status.Alarm.BITS.CUV = (BATT_FLAG_UV > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.COV = (BATT_FLAG_OV > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.PUV = (BATT_FLAG_PUV > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.POV = (BATT_FLAG_POV > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.OTC = (BATT_FLAG_OTC > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.UTC = (BATT_FLAG_UTC > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.OTD = (BATT_FLAG_OTD > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.UTD = (BATT_FLAG_UTD > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.OCC = (BATT_FLAG_OCC > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.OCD = (BATT_FLAG_OCD > 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.SD = (BATT_FLAG_SCD != 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.OTF = (BATT_FLAG_OTF != 0) ? 1 : 0; BATT_Info.Status.Alarm.BITS.BAL = (BATT_FLAG_BAL > 1) ? 1 : 0; BATT_Info.Status.Alarm.BITS.DFETF = (BATT_FLAG_FETF & 0x01) ? 1 : 0; BATT_Info.Status.Alarm.BITS.CFETF = (BATT_FLAG_FETF & 0x02) ? 1 : 0; //2022.04.20 增加 BATT_Info.Status.Alarm.BITS.CFETOF = BATT_FLAG_CFETOUTFAIL; //2022.07.06 增加CFET信号失效标志 BATT_Info.Status.Alarm.BITS.DFETOF = BATT_FLAG_DFETOUTFAIL; //2022.07.06 增加DFET信号失效标志 BATT_Info.Status.Alarm.BITS.COV2F = BATT_FLAG_COV2F; //2022.07.06 增加二次保护触发标志 */ MEM_Copy((INT8U *)(&BATT_Info.Status), (INT8U *)(SCP_Info.SendBuff.Data), (SCP_Info.SendBuff.Len + 8)); } //数据为小端模式,低字节在前,高字节在后 INT8U SCP_CmdProcess(INT8U Cmd) { INT16U_Str tValue; //INT8U_Str tFlag; INT8U i = 0; //tFlag.BYTES = 0; tValue.HALFWORDS = 0; //SCP_Info.SendBuff.Head = SCP_HEAD; //SCP_Info.SendBuff.Cmd = Cmd + 0x11; SCP_Info.SendBuff.AddrDes = SCP_Info.SendBuff.AddrSrc; SCP_Info.SendBuff.AddrSrc = SCP_BMS_ADDR; switch (Cmd) { case SCP_CMD_MANUINFO: //返回制造商信息 SCP_Info.SendBuff.Len = 34; MEM_Copy((INT8U *)(BATT_Info.Flash.ManufactureName), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_PRODINFO1: //返回产品信息 SCP_Info.SendBuff.Len = 78; MEM_Copy((INT8U *)(BATT_Info.Flash.DeviceName), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_PRODINFO2: //返回产品信息 SCP_Info.SendBuff.Len = 58; MEM_Copy((INT8U *)(BATT_Info.Flash.SN), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_SETSTRGDSG: //设置存储放电信息 BATT_CmdProcess(SCP_CMD_SETSTRGDSG, (INT8U *) & (SCP_Info.SendBuff.Data[0])); SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; // break; case SCP_CMD_STRGDSGINFO: //返回存储放电信息 SCP_Info.SendBuff.Len = 16; MEM_Copy((INT8U *)(&BATT_Info.Flash.Storage.Time0), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_RUNINFO: //返回运行状态信息 SCP_Info.SendBuff.Len = 20; SCP_RunInfoFill(); break; case SCP_CMD_BALINFO: //返回电芯均衡统计信息 SCP_Info.SendBuff.Len = 86; MEM_Copy((INT8U *)(&BATT_Info.Info.BalanceStats), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_CELLINFO: //返回电芯信息 SCP_Info.SendBuff.Len = 48; MEM_Copy((INT8U *)(&BATT_Info.Info.Vc[0]), (INT8U *)(&SCP_Info.SendBuff.Data[0]), 36); MEM_Copy((INT8U *)(&BATT_Info.Info.VcAvg), (INT8U *)(&SCP_Info.SendBuff.Data[36]), 12); break; case SCP_CMD_ALARMINFO: //返回报警信息 SCP_Info.SendBuff.Len = 62; if(SCP_Info.SendBuff.Data[0] > 2) { SCP_Info.SendBuff.Data[0] = 2; } SCP_Info.SendBuff.Data[1] = 0; MEM_Copy((INT8U *)(&BATT_Info.Info.AlarmLog.AlarmTimeStamp[SCP_Info.SendBuff.Data[0] * 10]), (INT8U *)(&SCP_Info.SendBuff.Data[2]), SCP_Info.SendBuff.Len); break; case SCP_CMD_RUNLOG: //返回运行信息 SCP_Info.SendBuff.Len = 36; MEM_Copy((INT8U *)(&BATT_Info.Info.UseInfoLog), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_STATISTICS: //返回统计信息 SCP_Info.SendBuff.Len = 64; MEM_Copy((INT8U *)(&BATT_Info.Info.AlarmLog.AlarmCnt), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_KEYON: //开机 SCP_Info.SendBuff.Len = 1; BATT_FLAG_ON |= 0x02; BATT_FetEn((CFET | DFET), ENABLE); BATT_FetLock((CFET | DFET), DISABLE); //清除MOS锁定 BATT_StorageStep = 0; if(FET_FLAG_PREDISCHARGE == PREDISCHARGE_OFF) { FET_FLAG_PREDISCHARGE = PREDISCHARGE_START; } SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; KEY_ResetCnt(P5V); KEY_WriteFlag(P5V, Lpress2, 0); //2022.06.02 增加写入5V检测有效标志 //BATT_AlarmLogWrite(ALARM_ON); break; case SCP_CMD_KEYOFF: //关机 SCP_Info.SendBuff.Len = 1; BATT_PowerOn(POWERON_KEY, DISABLE); SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; BATT_FLAG_RUNMODE = 0; //2022.07.14 增加按键关机退出测试模式 BATT_FLAG_CRG = 0; PWR5V_Freed(); //BATT_CmdProcess(SCP_CMD_PWR5VOFF, (INT8U *)0); BATT_ClrAllAlarmFlag(); //2022.08.29 增加关机清除所有警告标志 BATT_CmdProcess(SCP_CMD_NORMOL_MODE, (INT8U *)&BATT_Info.Flash.RunMode); //BATT_AlarmLogWrite(ALARM_OFF); break; case SCP_CMD_CFETON: //使能充电MOS,开机有效 SCP_Info.SendBuff.Len = 1; BATT_FetEn((CFET | DFET), ENABLE); if(FET_FLAG_PREDISCHARGE == 0) { BATT_PowerOn(POWERON_CRG, ENABLE); } BATT_CrgOffLineCntReset(30); BATT_FetLock((CFET | DFET), DISABLE); //清除MOS锁定 BATT_StorageStep = 0; BATT_FLAG_CRG = 1; BATT_FLAG_ON |= 0x01; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; KEY_ResetCnt(P5V); KEY_WriteFlag(P5V, Lpress2, 0); //2022.06.02 增加写入5V检测有效标志 //BATT_AlarmLogWrite(ALARM_ON); break; case SCP_CMD_CFETOFF: //禁止充电MOS SCP_Info.SendBuff.Len = 1; //BATT_FetEn(CFET, DISABLE); //BATT_FetEn(DFET, DISABLE); BATT_FLAG_CRG = 0; BATT_PowerOn(POWERON_CRG, DISABLE); SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; //BATT_AlarmLogWrite(ALARM_OFF); break; case SCP_CMD_PWR5V: //5V电源打开、关闭 if(SCP_Info.SendBuff.Len == 0) //无附加参数直接关闭电源 { PWR5V_Freed(); BATT_CmdProcess(SCP_CMD_PWR5VOFF, (INT8U *)0); } else if((SCP_Info.SendBuff.Len == 1) && //有附加参数按附加参数操作 (SCP_Info.SendBuff.Data[0] == 0x01)) { PWR5V_On(); BATT_CmdProcess(SCP_CMD_PWR5VON, (INT8U *)0); } else if((SCP_Info.SendBuff.Len == 1) && (SCP_Info.SendBuff.Data[0] == 0x00)) { PWR5V_Freed(); BATT_CmdProcess(SCP_CMD_PWR5VOFF, (INT8U *)0); } else { SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_UNDEF; } SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; break; case SCP_CMD_SETRTC: //设置RTC RTC_Info.Time.year = Byte2HalfWord(SCP_Info.SendBuff.Data); RTC_Info.Time.month = SCP_Info.SendBuff.Data[2]; RTC_Info.Time.day = SCP_Info.SendBuff.Data[3]; RTC_Info.Time.hour = SCP_Info.SendBuff.Data[4]; RTC_Info.Time.min = SCP_Info.SendBuff.Data[5]; RTC_Info.Time.sec = SCP_Info.SendBuff.Data[6]; RTC_Info.Time.week = RTC_CalWeek(&RTC_Info.Time); RTC_SetCounterValue(&RTC_Info.Time); SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; break; case SCP_CMD_RTCINFO: //返回RTC信息 SCP_Info.SendBuff.Len = 7; RTC_GetCounterValue(&RTC_Info.Time); MEM_Copy((INT8U *)(&RTC_Info.Time), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_SETCHGCAP: //限制容量充电, //BATT_FLAG_LCCHG = 1; BATT_ChargeEndSoc = SCP_Info.SendBuff.Data[0]; SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; //2022.08.01 修改为返回限制容量 //SCP_Info.SendBuff.Data[0] = BATT_ChargeEndSoc; break; case SCP_CMD_ENCHGCAP: //使能限制容量充电, BATT_FLAG_LCCHG = 1; SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; //SCP_Info.SendBuff.Data[0] = BATT_ChargeEndSoc; break; case SCP_CMD_READCHGCAP: //使能限制容量充电, SCP_Info.SendBuff.Len = 2; SCP_Info.SendBuff.Data[0] = BATT_FLAG_LCCHG; SCP_Info.SendBuff.Data[1] = BATT_ChargeEndSoc; break; case SCP_CMD_SETFORCEDSG: //强制放电到指令容量, BATT_FLAG_LCDSG = 1; BATT_DischargeEndSoc = SCP_Info.SendBuff.Data[0]; SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; //SCP_Info.SendBuff.Data[0] = BATT_DischargeEndSoc; break; case SCP_CMD_READFORCEDSG: //读取强制放电到指令容量设置, SCP_Info.SendBuff.Len = 2; SCP_Info.SendBuff.Data[0] = BATT_FLAG_LCDSG; SCP_Info.SendBuff.Data[1] = BATT_DischargeEndSoc; break; case SCP_CMD_SETPDSG: //设置预放电流和时间 BATT_CmdProcess(SCP_CMD_SETPDSG, SCP_Info.SendBuff.Data); SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; break; case SCP_CMD_READPDSG: //读取预放电流和时间 SCP_Info.SendBuff.Len = 4; MEM_Copy((INT8U *)(&BATT_Info.Flash.PreDischargeCurrentMin), (INT8U *)(SCP_Info.SendBuff.Data), SCP_Info.SendBuff.Len); break; case SCP_CMD_CLRFLAG: //清除运行信息的标志 BATT_ClrAllAlarmFlag(); SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; break; case SCP_CMD_DEBUG: BATT_CmdProcess(SCP_Info.SendBuff.Data[0], (INT8U *) & (SCP_Info.SendBuff.Data[1])); SCP_Info.SendBuff.Cmd = SCP_CMD_ERRINFO; i = 1; if(SCP_Info.SendBuff.Data[0] == SCP_CMD_TEST_MODE) { SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; BATT_FLAG_RUNMODE = 1; } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_FACT_MODE) { SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; BATT_FLAG_RUNMODE = 2; } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_NORMOL_MODE) { SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; BATT_FLAG_RUNMODE = 0; } /*else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_UPDATE_BOOT) { SCP_Info.SendBuff.Len = 1; FLASH_Write(0x08000000, (INT8U *)g_loadercode, 0x2000); SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; BATT_FLAG_RUNMODE = 0; }*/ else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_SET_CYCLE) { SCP_Info.SendBuff.Len = 3; MEM_Copy((INT8U *)&BATT_Cycle, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_RST_VER) { SCP_Info.SendBuff.Len = 3; //SCP_Info.SendBuff.Data[i++]=0; //保留 SCP_Info.SendBuff.Data[i++] = BATT_FLASH_SWVersion; //软件版本号 SCP_Info.SendBuff.Data[i++] = BATT_FLASH_HWVersion; //硬件版本号 } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_CALI_RES) { SCP_Info.SendBuff.Len = 7; tValue.HALFWORDS = BATT_Current; //电池包电流,1mA SCP_Info.SendBuff.Data[i++] = tValue.BYTES[0]; SCP_Info.SendBuff.Data[i++] = tValue.BYTES[1]; MEM_Copy((INT8U *)&BATT_FLASH_CcGain, (INT8U *)&SCP_Info.SendBuff.Data[i], 4); } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_SET_RES) { SCP_Info.SendBuff.Len = 5; MEM_Copy((INT8U *)&BATT_FLASH_CcGain, (INT8U *)&SCP_Info.SendBuff.Data[i], 4); } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_CALI_OFFSET) { SCP_Info.SendBuff.Len = 9; //tValue.HALFWORDS = BATT_FLASH_CcOffset; //静态偏移 //SCP_Info.SendBuff.Data[i++] = tValue.BYTES[0]; //SCP_Info.SendBuff.Data[i++] = tValue.BYTES[1]; MEM_Copy((INT8U *)&BATT_FLASH_CcOffset, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_Info.Flash.AfeOffset, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_Info.Info.Voltage, (INT8U *)&SCP_Info.SendBuff.Data[i], 4); i += 4; } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_CALI_INFO) { SCP_Info.SendBuff.Len = 13; MEM_Copy((INT8U *)&BATT_FLASH_AfeOffset, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_CcOffset, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_CcGain, (INT8U *)&SCP_Info.SendBuff.Data[i], 4); i += 4; MEM_Copy((INT8U *)&ADC_GAIN, (INT8U *)&SCP_Info.SendBuff.Data[i], 4); i += 4; } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_READLOG) { SCP_Info.SendBuff.Len = 1 + sizeof(UseInfoLog_Str); MEM_Copy((INT8U *) & (BATT_Info.Info.UseInfoLog), (INT8U *)&SCP_Info.SendBuff.Data[i], (SCP_Info.SendBuff.Len - 1)); } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_AFE_REG) { SCP_Info.SendBuff.Len = 9; MEM_Copy((INT8U *)&BATT_FLASH_AfeOffset, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_CcOffset, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_CcGain, (INT8U *)&SCP_Info.SendBuff.Data[i], 4); i += 4; } else if((SCP_Info.SendBuff.Data[0] == SCP_CMD_RST_FLASH) || (SCP_Info.SendBuff.Data[0] == SCP_CMD_RST_AFE) || (SCP_Info.SendBuff.Data[0] == SCP_CMD_SET_ID) || (SCP_Info.SendBuff.Data[0] == SCP_CMD_CLR_CVLL) || (SCP_Info.SendBuff.Data[0] == SCP_CMD_SET_SN)) { SCP_Info.SendBuff.Len = 1; SCP_Info.SendBuff.Data[0] = SCP_ERRORCODE_NULL; // } else if((SCP_Info.SendBuff.Data[0] == SCP_CMD_SET_PARA) || (SCP_Info.SendBuff.Data[0] == SCP_CMD_READ_PARA)) { SCP_Info.SendBuff.Len = 39; MEM_Copy((INT8U *)&BATT_FLASH_Ov1, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_Ov2, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_OvRel, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_Uv1, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_Uv2, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_UvRel, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_Otc2, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_OtcRel, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_Utc2, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_UtcRel, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_Otd2, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_OtdRel, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_Utd2, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; MEM_Copy((INT8U *)&BATT_FLASH_UtdRel, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; tValue.HALFWORDS = BATT_FLASH_Occ1 / 10; //充电过流1 MEM_Copy(tValue.BYTES, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; tValue.HALFWORDS = BATT_FLASH_Occ2 / 10; //充电过流2 MEM_Copy(tValue.BYTES, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; tValue.HALFWORDS = BATT_FLASH_Ocd1 / 10; //放电过流1 MEM_Copy(tValue.BYTES, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; tValue.HALFWORDS = BATT_FLASH_Ocd2 / 10; //放电过流2 MEM_Copy(tValue.BYTES, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); i += 2; tValue.HALFWORDS = BATT_FLASH_FDC / 10; //设计容量,10mAh MEM_Copy(tValue.BYTES, (INT8U *)&SCP_Info.SendBuff.Data[i], 2); } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_READ_INFO) { SCP_Info.SendBuff.Len = 1 + 52 + 16; MEM_Copy((INT8U *)&BATT_Info.Info.Voltage, (INT8U *)&SCP_Info.SendBuff.Data[i], 52); i += 52; MEM_Copy((INT8U *)&BATT_Info.Info.Rsoc, (INT8U *)&SCP_Info.SendBuff.Data[i], 16); } else if(SCP_Info.SendBuff.Data[0] == SCP_CMD_READ_PREDSGINFO) { SCP_Info.SendBuff.Len = 1 + 16; MEM_Copy((INT8U *)BATT_PreDischargeCurrent, (INT8U *)&SCP_Info.SendBuff.Data[i], 16); } break; default: SCP_Info.SendBuff.Len = 2; SCP_Info.SendBuff.Data[1] = SCP_ERRORCODE_UNDEF; break; } SCP_Info.SendBuff.CheckSum = CRC16((INT8U *) & (SCP_Info.SendBuff.Head), (SCP_Info.SendBuff.Len + 6)); SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 0] = (INT8U)(SCP_Info.SendBuff.CheckSum >> 0); SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 1] = (INT8U)(SCP_Info.SendBuff.CheckSum >> 8); SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 2] = SCP_END1; SCP_Send((INT8U *) & (SCP_Info.SendBuff.Head), (9 + SCP_Info.SendBuff.Len)); return (1); } //协议解析 INT8U SCP_Analyze(INT8U *ptr, INT8U Len) { INT8U i; for (i = 0; i < Len; i++) //搜索包头 { if ((ptr[i] == SCP_HEAD1) && (ptr[i + 1] == SCP_HEAD2)) { break; } } BATT_SleepDelayTime(10); SCP_SetOverTime(2); //2022.07.29 增加通信超时2秒计时 //BATT_FLAG_INIT=1; Len = Len - i; //重新计算数据帧长度 ptr += i; //重新计算数据偏移 MEM_Fill((INT8U *) & (SCP_Info), 0, sizeof(SCP_Str) - 6); MEM_Copy(ptr, (INT8U *) & (SCP_Info), (ptr[5] + 9)); //复制接收到的数据帧到接收缓冲区 //检查源地址 if((SCP_Info.SendBuff.AddrSrc == SCP_LED_ADDR) || (SCP_Info.SendBuff.AddrSrc == SCP_PC_ADDR)) { NOP(); } else { SCP_ErrorReport(SCP_ERRORCODE_ADDRS); return (SCP_ERRORCODE_ADDRS); } //检查目标地址 if(SCP_Info.SendBuff.AddrDes != SCP_BMS_ADDR) { //SCP_ErrorReport(SCP_ERRORCODE_ADDRD); return (SCP_ERRORCODE_ADDRD); } //检查数据长度 if(Len < SCP_Info.SendBuff.Len) { SCP_ErrorReport(SCP_ERRORCODE_LEN); return (SCP_ERRORCODE_LEN); } //检查操作寄存器是否在允许范围内,暂空缺 //检查结束标志是否正常 if(SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 2] != SCP_END1) { SCP_ErrorReport(SCP_ERRORCODE_END); return (SCP_ERRORCODE_END); } //校验数据是否正确 SCP_Info.SendBuff.CheckSum = (INT16U)(SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len]) | (((INT16U)(SCP_Info.SendBuff.Data[SCP_Info.SendBuff.Len + 1])) << 8); if (SCP_Info.SendBuff.CheckSum != CRC16((INT8U *) & (SCP_Info.SendBuff.Head), (6 + SCP_Info.SendBuff.Len))) { SCP_ErrorReport(SCP_ERRORCODE_CRC); return (SCP_ERRORCODE_CRC); } //检查命令字,检查上锁状态不处理加密指令 if((SCP_Info.SendBuff.Cmd == SCP_CMD_DEBUG) && //复位指令添加解锁 (SCP_Info.SendBuff.Data[0] == SCP_CMD_RST_MCU)) { BATT_FLAG_SCPLOCK = 1; } if(SCP_Info.SendBuff.Cmd == SCP_CMD_UNLOCK) { if((SCP_Info.SendBuff.Data[0] == 0x01) && (SCP_Info.SendBuff.Data[1] == 0x23) && (SCP_Info.SendBuff.Data[2] == 0x45) && (SCP_Info.SendBuff.Data[3] == 0x67)) { BATT_FLAG_SCPLOCK = 1; SCP_ErrorReport(SCP_ERRORCODE_NULL); return(SCP_ERRORCODE_NULL); } else { SCP_ErrorReport(SCP_ERRORCODE_PASSWORD); return(SCP_ERRORCODE_PASSWORD); } } else if(SCP_Info.SendBuff.Cmd == SCP_CMD_LOCK) { BATT_FLAG_SCPLOCK = 0; SCP_ErrorReport(SCP_ERRORCODE_NULL); return(SCP_ERRORCODE_NULL); } if((BATT_FLAG_SCPLOCK == 0) && (SCP_Info.SendBuff.Cmd >= SCP_CMD_DEBUG)) { SCP_ErrorReport(SCP_ERRORCODE_LOCK); return (SCP_ERRORCODE_LOCK); } //命令处理 SCP_CmdProcess(SCP_Info.SendBuff.Cmd); return (0); }