/** ****************************************************************************** * @file InverterSwitch_Page2.c * @author - * @version - * @date 2026.3.26 * @brief - ****************************************************************************** * @attention * * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "global.h" //这里放的是基本款的第2页函数,不根据发货要求变动 //CAN: //13.SMA 14.Sunways 15.Luxpower 16.Schneider //17.AlpSolarr //Modbus: //18.SRNE 19.Voltronic 20.COSUPER //21.SMK 22.SAKO 23.SNADI 24.invt //SMA 艾思玛 void CAN_Protocol_SMA(void) { uint8_t data[8]; uint16_t totalCapacity; int16_t tempVol; int16_t tempCur; uint16_t chgVolLimit; uint16_t dsgVolLimit; int16_t chgCurLimit; int16_t dsgCurLimit; uint8_t protectByte1 = 0; uint8_t protectByte2 = 0; uint8_t protectByte3 = 0; uint8_t protectByte4 = 0; uint8_t alarmByte1 = 0; uint8_t alarmByte2 = 0; uint8_t alarmByte3 = 0; uint8_t alarmByte4 = 0; int16_t T_Average; // 平均温度 //Data0 BIT0.1 General[Cancel] //0000 0010 protectByte1 |= 0x02; //保护 //放电高温保护 //over temp at discharging if(((canMem[0].status_byte2 & 0x0008) != 0) || ((canMem[0].status_byte4 & 0x0202) != 0)) { protectByte1 &= 0x7f; protectByte1 |= 0x40; } else { protectByte1 &= 0xbf; protectByte1 |= 0x80; } //欠压保护 //cell_uv+pack_uv+l0v if(((canMem[0].status_byte1 & 0x0202) != 0) || ((canMem[0].status_byte3 & 0x0008) != 0)) { protectByte1 &= 0xdf; protectByte1 |= 0x10; } else { protectByte1 &= 0xef; protectByte1 |= 0x20; } // //过压保护 // //cell_ov+pack_ov+pf // if((canMem[0].status_byte1 & 0x0141) != 0) // { // if(canMem[0].soc < 99) // { // protectByte1 &= 0xf7; //去掉leave // protectByte1 |= 0x04; //赋值arrive // } // else // { // protectByte1 &= 0xfb; // protectByte1 |= 0x08; // } // } // else // { // protectByte1 &= 0xfb; // protectByte1 |= 0x08; // } //放电过流保护 //discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x042c) != 0) || ((canMem[0].status_byte2 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0020) != 0)) { protectByte2 &= 0x7f; protectByte2 |= 0x40; } else { protectByte2 &= 0xbf; protectByte2 |= 0x80; } //充电低温保护 //Data1 BIT4.5 under temp at charging //0001 0000 if( ((canMem[0].status_byte2 & 0x0001) != 0) || ((canMem[0].status_byte4 & 0x0404) != 0) ) { protectByte2 &= 0xdf; protectByte2 |= 0x10; } else { protectByte2 &= 0xef; protectByte2 |= 0x20; } //充电高温保护 //Data1 BIT2.3 over temp at charging //0000 0100 if( ((canMem[0].status_byte2 & 0x0002) != 0) || ((canMem[0].status_byte4 & 0x0101) != 0) ) { protectByte2 &= 0xf7; protectByte2 |= 0x04; } else { protectByte2 &= 0xfb; protectByte2 |= 0x08; } //放电低温保护 //Data1 BIT0.1 under temp at discharging //0000 0001 if( ((canMem[0].status_byte2 & 0x0004) != 0) || ((canMem[0].status_byte4 & 0x0808) != 0) ) { protectByte2 &= 0xfd; protectByte2 |= 0x01; } else { protectByte2 &= 0xfe; protectByte2 |= 0x02; } //短路 //Data2 BIT4.5 short circuit //0001 0000 if((canMem[0].status_byte1 & 0x20) != 0) { protectByte3 &= 0xdf; protectByte3 |= 0x10; } else { protectByte3 &= 0xef; protectByte3 |= 0x20; } //充电过流保护 //charge over current if( ((canMem[0].status_byte1 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0010) != 0)) { protectByte3 &= 0xfd; protectByte3 |= 0x01; } else { protectByte3 &= 0xfe; protectByte3 |= 0x02; } //Data2 BIT2.3 Contactor[Cancel] //0000 1000 protectByte3 |= 0x08; //Data2 BIT6.7 BMS internal[Cancel] //1000 0000 protectByte3 |= 0x80; // //Data3 BIT0.1 cell imbanlance //0000 0001 // if((bmsMem.balanceStatus & 0x01) !=0) //0x01表示平衡 // { // protectByte4 &= 0xfe; // protectByte4 |= 0x02; // } // else // { // protectByte4 &= 0xfd; // protectByte4 |= 0x01; // } //告警 //放电高温告警 //over temp at discharging if(((canMem[0].status_byte2 & 0x2200) != 0) || ((canMem[0].status_byte4 & 0x2000) != 0)) { alarmByte1 &= 0x7f; alarmByte1 |= 0x40; } else { alarmByte1 &= 0xbf; alarmByte1 |= 0x80; } //欠压告警 if((canMem[0].status_byte3 & 0x0A00) != 0) { alarmByte1 &= 0xdf; alarmByte1 |= 0x10; } else { alarmByte1 &= 0xef; alarmByte1 |= 0x20; } // //过压告警 // if((canMem[0].status_byte3 & 0x0500) != 0) // { // if(canMem[0].soc < 99) // { // alarmByte1 &= 0xf7; //去掉leave // alarmByte1 |= 0x04; //赋值arrive // } // else // { // alarmByte1 &= 0xfb; // alarmByte1 |= 0x08; // } // } // else // { // alarmByte1 &= 0xfb; // alarmByte1 |= 0x08; // } //放电过流告警 if((canMem[0].status_byte3 & 0x2000) != 0) { alarmByte2 &= 0x7f; alarmByte2 |= 0x40; } else { alarmByte2 &= 0xbf; alarmByte2 |= 0x80; } //充电低温告警 //Data1 BIT4.5 under temp at charging //0001 0000 if( ((canMem[0].status_byte2 & 0x4400) != 0) || ((canMem[0].status_byte4 & 0x4000) != 0) ) { alarmByte2 &= 0xdf; alarmByte2 |= 0x10; } else { alarmByte2 &= 0xef; alarmByte2 |= 0x20; } //充电高温告警 //Data1 BIT2.3 over temp at charging //0000 0100 if( ((canMem[0].status_byte2 & 0x1100) != 0) || ((canMem[0].status_byte4 & 0x1000) != 0) ) { alarmByte2 &= 0xf7; alarmByte2 |= 0x04; } else { alarmByte2 &= 0xfb; alarmByte2 |= 0x08; } //放电低温告警 //Data1 BIT0.1 under temp at discharging //0000 0001 if( ((canMem[0].status_byte2 & 0x8800) != 0) || ((canMem[0].status_byte4 & 0x8000) != 0) ) { alarmByte2 &= 0xfd; alarmByte2 |= 0x01; } else { alarmByte2 &= 0xfe; alarmByte2 |= 0x02; } //短路 //Data2 BIT4.5 short circuit //0001 0000 if((canMem[0].status_byte1 & 0x20) != 0) { alarmByte3 &= 0xdf; alarmByte3 |= 0x10; } else { alarmByte3 &= 0xef; alarmByte3 |= 0x20; } //充电过流告警 if((canMem[0].status_byte3 & 0x1000) != 0) { alarmByte3 &= 0xfd; alarmByte3 |= 0x01; } else { alarmByte3 &= 0xfe; alarmByte3 |= 0x02; } // if((bmsMem.balanceStatus & 0x01) !=0) //0x01表示平衡 // { // alarmByte4 &= 0xfe; // alarmByte4 |= 0x02; // } // else // { // alarmByte4 &= 0xfd; // alarmByte4 |= 0x01; // } if(CAN_SendCount ==0) //ID=0x35a - Alarms/Warnings { data[0] = protectByte1; data[1] = protectByte2; data[2] = protectByte3; data[3] = protectByte4; data[4] = alarmByte1; //报警和保护信号相同 data[5] = alarmByte2; data[6] = alarmByte3; data[7] = alarmByte4; CAN1_SendData(0x35a, &data[0]); } if(CAN_SendCount ==1) //ID = 0x351 - 电池充电/放电电压,充电/放电限流 { //充放电电流限制需要有符号区别吗? chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V if(chg_forbidFlg == 1) { chgCurLimit = 0; //SMA禁充 } else if(chg_curlimitFlg == 1) { chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { dsgCurLimit = 0; //SMA禁放 } else { dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } data[0] = chgVolLimit & 0xFF; //充电电压限制低位 data[1] = (chgVolLimit >> 8) & 0xFF; data[2] = chgCurLimit & 0xFF; //充电电流限制低位 data[3] = (chgCurLimit >> 8) & 0xFF; data[4] = dsgCurLimit & 0xFF; //放电电流限制低位 data[5] = (dsgCurLimit >> 8) & 0xFF; data[6] = dsgVolLimit & 0xFF; //放电电压限制低位 data[7] = (dsgVolLimit >> 8) & 0xFF; CAN1_SendData(0x351, &data[0]); } if(CAN_SendCount ==2) //ID = 0x355 - 电量SOC/SOH { data[0] = canMem[0].soc & 0xFF; //SOC data[1] = 0; data[2] = canMem[0].soh & 0xFF; //SOH data[3] = 0; data[4] = 0X00; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x355, &data[0]); } if(CAN_SendCount ==3) //ID = 0x356 - 电池电压/电流/温度 { tempVol = (uint16_t)(bmsMem.packVoltage/10); //单位0.01 tempCur = (int16_t)(canMem[0].cur/10); //单位0.1 T_Average = canMem[0].temp;// 平均温度 data[0] = tempVol & 0xFF; data[1] = (tempVol >>8) & 0xFF; //电池包电压 data[2] = tempCur & 0xFF; data[3] = (tempCur >>8) & 0xFF; //电池包电流 data[4] = (T_Average -2731) & 0xFF;; data[5] = ((T_Average -2731) >>8) & 0xFF; //温度-暂时取平均温度,具体哪一路需要客户确认 data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x356, &data[0]); } if(CAN_SendCount ==4) //ID = 0x35e - 制造商名称-ASCII { data[0] = 'B'; data[1] = 'T'; data[2] = 'Y'; data[3] = 'G'; data[4] = '-'; data[5] = 'B'; data[6] = 'M'; data[7] = 'S'; CAN1_SendData(0x35e, &data[0]); } if(CAN_SendCount ==5) //ID = 0x35f - 电池类型,BMS版本,电池容量,保留的制造商ID { totalCapacity = ncc_Ah * OnlineNum; //单位1Ah data[0] = 0X00; data[1] = 0X00; data[2] = 0X00; //版本号暂无 data[3] = 0X00; data[4] = totalCapacity & 0xFF; //电池容量 data[5] = (totalCapacity >> 8) & 0xFF; data[6] = 0X00; data[7] = 0X00; CAN1_SendData(0x35f, &data[0]); } if(CAN_SendCount>=6) { CAN_SendCount = 0; } } //Sunways 尚唯斯 void CAN_Protocol_Sunways(void) { uint8_t data[8]; uint16_t totalCapacity; uint16_t tempVol; int16_t tempCur; uint16_t chgVolLimit; uint16_t dsgVolLimit; int16_t chgCurLimit = bmsMem.inverter_chgCurLimit; int16_t dsgCurLimit = bmsMem.inverter_dsgCurLimit; uint8_t protectByte1 = 0; uint8_t protectByte2 = 0; int16_t T_Average; // 平均温度 uint8_t alarmByte1 = 0; uint8_t alarmByte2 = 0; uint8_t alarmByte3 = 0; //0x399传输告警位 uint8_t status = 0; //0x399传输状态位 uint8_t protectByte3 = 0; //0x399传输故障位 //保护 //放电过流保护 //discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x042c) != 0) || ((canMem[0].status_byte2 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0020) != 0)) { protectByte1 |= 0x80; } else { protectByte1 &= 0x7f; } //低温保护 //under temp at charging or discharging if(((canMem[0].status_byte2 & 0x0005) != 0) || ((canMem[0].status_byte4 & 0x0C0C) != 0)) { protectByte1 |= 0x10; } else { protectByte1 &= 0xef; } //过温保护 //over temp at charging or discharging if(((canMem[0].status_byte2 & 0x000A) != 0) || ((canMem[0].status_byte4 & 0x0303) != 0)) { protectByte1 |= 0x08; } else { protectByte1 &= 0xf7; } //欠压保护 //cell_uv+pack_uv+l0v if(((canMem[0].status_byte1 & 0x0202) != 0) || ((canMem[0].status_byte3 & 0x0008) != 0)) { protectByte1 |= 0x04; alarmByte3 |= 0x02; protectByte3 |= 0x04; } else { protectByte1 &= 0xfb; alarmByte3 &= 0xfd; protectByte3 &= 0xfb; } // //过压保护 // //cell_ov+pack_ov+pf // if((canMem[0].status_byte1 & 0x0141) != 0) // { // if(canMem[0].soc < 99) // { // protectByte1 |= 0x02; // } // else // { // protectByte1 &= 0xfd; // } // } // else // { // protectByte1 &= 0xfd; // } //充电过流保护 //charge over current if( ((canMem[0].status_byte1 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0010) != 0)) { protectByte2 |= 0x01; } else { protectByte2 &= 0xfe; } //告警 //放电过流告警 if((canMem[0].status_byte3 & 0x2000) != 0) { alarmByte1 |= 0x80; } else { alarmByte1 &= 0x7f; } //低温告警 if(((canMem[0].status_byte2 & 0xCC00) != 0) || ((canMem[0].status_byte4 & 0xC000) != 0)) { alarmByte1 |= 0x10; } else { alarmByte1 &= 0xef; } //过温告警 if(((canMem[0].status_byte2 & 0x3300) != 0) || ((canMem[0].status_byte4 & 0x3000) != 0)) { alarmByte1 |= 0x08; } else { alarmByte1 &= 0xf7; } //欠压告警 if((canMem[0].status_byte3 & 0x0A00) != 0) { alarmByte1 |= 0x04; } else { alarmByte1 &= 0xfb; } // //过压告警 // if((canMem[0].status_byte3 & 0x0500) != 0) // { // if(canMem[0].soc < 99) // { // alarmByte1 |= 0x02; // } // else // { // alarmByte1 &= 0xfd; // } // } // else // { // alarmByte1 &= 0xfd; // } //充电过流告警 if((canMem[0].status_byte3 & 0x1000) != 0) { alarmByte2 |= 0x01; } else { alarmByte2 &= 0xfe; } if(CAN_SendCount ==0) //ID=0x359 { data[0] = protectByte1; data[1] = protectByte2; data[2] = alarmByte1; data[3] = alarmByte2; data[4] = OnlineNum; data[5] = 0x50; data[6] = 0x4E; data[7] = 0X00; CAN1_SendData(0x359, &data[0]); } if(CAN_SendCount ==1) //ID = 0x351 { //充放电电流限制需要有符号区别吗? chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V if(chg_forbidFlg == 1) { chgCurLimit = 0; //Sol-Ark禁充 } else if(chg_curlimitFlg == 1) { chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { dsgCurLimit = 0; //Sol-Ark禁放 } else { dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } data[0] = chgVolLimit & 0xFF; //充电电压限制低位 data[1] = (chgVolLimit >> 8) & 0xFF; data[2] = chgCurLimit & 0xFF; //充电电流限制低位 data[3] = (chgCurLimit >> 8) & 0xFF; data[4] = dsgCurLimit & 0xFF; //放电电流限制低位 data[5] = (dsgCurLimit >> 8) & 0xFF; data[6] = dsgVolLimit & 0xFF; //放电电压限制低位 data[7] = (dsgVolLimit >> 8) & 0xFF; CAN1_SendData(0x351, &data[0]); } if(CAN_SendCount ==2) { data[0] = canMem[0].soc & 0xFF; //SOC data[1] = 0; data[2] = canMem[0].soh & 0xFF; //SOH data[3] = 0; data[4] = 0X00; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x355, &data[0]); } if(CAN_SendCount ==3) { tempVol = (uint16_t)(bmsMem.packVoltage/10); //单位0.01 tempCur = (int16_t)(canMem[0].cur/10); //单位0.1 T_Average = canMem[0].temp;// 平均温度 data[0] = tempVol & 0xFF; data[1] = (tempVol >>8) & 0xFF; //电池包电压 data[2] = tempCur & 0xFF; data[3] = (tempCur >>8) & 0xFF; //电池包电流 data[4] = (T_Average -2731) & 0xFF;; data[5] = ((T_Average -2731) >>8) & 0xFF; //温度-暂时取平均温度,具体哪一路需要客户确认 data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x356, &data[0]); } if(CAN_SendCount ==4) { status = 0x03; if(chg_forbidFlg == 1)//sunways { status &= ~0x01; //禁充 } if(dsg_forbidFlg == 1)//sunways { status &= ~0x02; //禁放 } if(chg_forceFlg == 1)//sunways { status |= ~0x04; //强充 } data[0] = 0x00; data[1] = 0x00; data[2] = alarmByte3; data[3] = status; data[4] = protectByte3; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x399, &data[0]); } if(CAN_SendCount ==5) { totalCapacity = ncc_Ah * OnlineNum; //单位1Ah data[0] = 0x00;//电池类型 data[1] = 0x00; data[2] = VersionMem.Software[0] & 0xFF;//BMS版本号,仅传输大版本号及小修改 data[3] = VersionMem.Software[3] & 0xFF; data[4] = totalCapacity & 0xFF; //容量 data[5] = (totalCapacity >> 8) & 0xFF; data[6] = 0x00;//制造商ID data[7] = 0X00; CAN1_SendData(0x35F, &data[0]); } if(CAN_SendCount ==6) { RequestFlag = 0xC0; //充电允许0x80,放电允许0x40,不强充~0x20 if(chg_forbidFlg == 1)//sunways { RequestFlag &= 0x7F; //禁充 } if(dsg_forbidFlg == 1)//sunways { RequestFlag &= 0xBF; //禁放 } if(chg_forceFlg == 1)//sunways { RequestFlag |= 0x20; //强充 } data[0] = RequestFlag; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0X00; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x35C, &data[0]); } if(CAN_SendCount ==7) //0x370 { data[0] = bmsMem.vCell[0] & 0xFF; //电芯N电压 data[1] = (bmsMem.vCell[0] >> 8) & 0xFF; data[2] = bmsMem.vCell[1] & 0xFF; //电芯N+1电压 data[3] = (bmsMem.vCell[1] >> 8) & 0xFF; data[4] = bmsMem.vCell[2] & 0xFF; //电芯N+2电压 data[5] = (bmsMem.vCell[2] >> 8) & 0xFF; data[6] = bmsMem.vCell[3] & 0xFF; //电芯N+3电压 data[7] = (bmsMem.vCell[3] >> 8) & 0xFF; CAN1_SendData(0x370, &data[0]); } if(CAN_SendCount ==8) //0x371 { data[0] = bmsMem.vCell[4] & 0xFF; //电芯N+4电压 data[1] = (bmsMem.vCell[4] >> 8) & 0xFF; data[2] = bmsMem.vCell[5] & 0xFF; //电芯N+5电压 data[3] = (bmsMem.vCell[5] >> 8) & 0xFF; data[4] = bmsMem.vCell[6] & 0xFF; //电芯N+6电压 data[5] = (bmsMem.vCell[6] >> 8) & 0xFF; data[6] = bmsMem.vCell[7] & 0xFF; //电芯N+7电压 data[7] = (bmsMem.vCell[7] >> 8) & 0xFF; CAN1_SendData(0x371, &data[0]); } if(CAN_SendCount ==9) //0x372 { data[0] = bmsMem.vCell[8] & 0xFF; //电芯N+8电压 data[1] = (bmsMem.vCell[8] >> 8) & 0xFF; data[2] = bmsMem.vCell[9] & 0xFF; //电芯N+9电压 data[3] = (bmsMem.vCell[9] >> 8) & 0xFF; data[4] = bmsMem.vCell[10] & 0xFF; //电芯N+10电压 data[5] = (bmsMem.vCell[10] >> 8) & 0xFF; data[6] = bmsMem.vCell[11] & 0xFF; //电芯N+11电压 data[7] = (bmsMem.vCell[11] >> 8) & 0xFF; CAN1_SendData(0x372, &data[0]); } if(CAN_SendCount ==10) //0x373 { data[0] = bmsMem.vCell[12] & 0xFF; //电芯N+12电压 data[1] = (bmsMem.vCell[12] >> 8) & 0xFF; data[2] = bmsMem.vCell[13] & 0xFF; //电芯N+13电压 data[3] = (bmsMem.vCell[13] >> 8) & 0xFF; data[4] = bmsMem.vCell[14] & 0xFF; //电芯N+14电压 data[5] = (bmsMem.vCell[14] >> 8) & 0xFF; data[6] = bmsMem.vCell[15] & 0xFF; //电芯N+15电压 data[7] = (bmsMem.vCell[15] >> 8) & 0xFF; CAN1_SendData(0x373, &data[0]); } if(CAN_SendCount ==11) //0x3D0 { data[0] = ((bmsMem.mcu_T1 - 2731)/10 + 50) & 0xFF; data[1] = ((bmsMem.mcu_T2 - 2731)/10 + 50) & 0xFF; data[2] = ((bmsMem.mcu_T3 - 2731)/10 + 50) & 0xFF; data[3] = ((bmsMem.mcu_T4 - 2731)/10 + 50) & 0xFF; data[4] = ((bmsMem.afe_T1 - 2731)/10 + 50) & 0xFF; data[5] = ((bmsMem.afe_T2 - 2731)/10 + 50) & 0xFF;; data[6] = ((bmsMem.afe_T3 - 2731)/10 + 50) & 0xFF;; data[7] = 0X00; CAN1_SendData(0x3D0, &data[0]); } if(CAN_SendCount ==12) //0x3DA { data[0] = bmsMem.can_VolMax & 0xFF; data[1] = (bmsMem.can_VolMax >>8) & 0xFF; data[2] = bmsMem.can_VolMin & 0xFF; data[3] = (bmsMem.can_VolMin >>8) & 0xFF; data[4] = (bmsMem.can_VolMaxIndex + 1) & 0xFF; data[5] = (bmsMem.can_VolMinIndex + 1) & 0xFF; data[6] = 0X00; data[7] = 0X00; CAN1_SendData(0x3DA, &data[0]); } if(CAN_SendCount ==13) //0x3DB { data[0] = ((bmsMem.can_TempMax - 2731)/10 + 50) & 0xFF; data[1] = (((bmsMem.can_TempMax - 2731)/10 + 50) >>8) & 0xFF; data[2] = ((bmsMem.can_TempMin - 2731)/10 + 50) & 0xFF; data[3] = (((bmsMem.can_TempMin - 2731)/10 + 50) >>8) & 0xFF; data[4] = (bmsMem.can_TempMaxIndex + 1) & 0xFF; data[5] = (bmsMem.can_TempMinIndex + 1) & 0xFF; data[6] = 0X00; data[7] = 0X00; CAN1_SendData(0x3DB, &data[0]); } if(CAN_SendCount ==14) //0x35E { data[0] = 0x50; //制造商名称 data[1] = 0x4E; data[2] = 0x00; data[3] = 0x00; data[4] = 0X00; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x35E, &data[0]); } if(CAN_SendCount>=15) { CAN_SendCount = 0; } } //Lux power 深圳鹏城 void CAN_Protocol_Luxpower(void) { uint8_t data[8]; uint16_t totalCapacity;//总容量 uint16_t tempVol; int16_t tempCur; //总电流 uint16_t chgVolLimit; uint16_t dsgVolLimit; int16_t chgCurLimit; int16_t dsgCurLimit; uint8_t protectByte1 = 0; uint8_t protectByte2 = 0; uint8_t alarmByte1 = 0; uint8_t alarmByte2 = 0; int16_t T_Max; // 最高温度 int16_t T_Min; // 最低温度 uint16_t cellVolMax=0; // 电芯单体最高电压 uint16_t cellVolMin=0; // 电芯单体最低电压 //保护 //放电过流保护 //discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x042c) != 0) || ((canMem[0].status_byte2 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0020) != 0)) { protectByte1 |= 0x80; } else { protectByte1 &= 0x7f; } //低温保护 //under temp at charging or discharging if(((canMem[0].status_byte2 & 0x0005) != 0) || ((canMem[0].status_byte4 & 0x0C0C) != 0)) { protectByte1 |= 0x10; } else { protectByte1 &= 0xef; } //过温保护 //over temp at charging or discharging if(((canMem[0].status_byte2 & 0x000A) != 0) || ((canMem[0].status_byte4 & 0x0303) != 0)) { protectByte1 |= 0x08; } else { protectByte1 &= 0xf7; } //欠压保护 //cell_uv+pack_uv+l0v if(((canMem[0].status_byte1 & 0x0202) != 0) || ((canMem[0].status_byte3 & 0x0008) != 0)) { protectByte1 |= 0x04; } else { protectByte1 &= 0xfb; } // //过压保护 // //cell_ov+pack_ov+pf // if((canMem[0].status_byte1 & 0x0141) != 0) // { // if(canMem[0].soc < 99) // { // protectByte1 |= 0x02; // } // else // { // protectByte1 &= 0xfd; // } // } // else // { // protectByte1 &= 0xfd; // } //充电过流保护 //charge over current if( ((canMem[0].status_byte1 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0010) != 0)) { protectByte2 |= 0x01; } else { protectByte2 &= 0xfe; } //告警 //放电过流告警 if((canMem[0].status_byte3 & 0x2000) != 0) { alarmByte1 |= 0x80; } else { alarmByte1 &= 0x7f; } //低温告警 if(((canMem[0].status_byte2 & 0xCC00) != 0) || ((canMem[0].status_byte4 & 0xC000) != 0)) { alarmByte1 |= 0x10; } else { alarmByte1 &= 0xef; } //过温告警 if(((canMem[0].status_byte2 & 0x3300) != 0) || ((canMem[0].status_byte4 & 0x3000) != 0)) { alarmByte1 |= 0x08; } else { alarmByte1 &= 0xf7; } //欠压告警 if((canMem[0].status_byte3 & 0x0A00) != 0) { alarmByte1 |= 0x04; } else { alarmByte1 &= 0xfb; } // //过压告警 // if((canMem[0].status_byte3 & 0x0500) != 0) // { // if(canMem[0].soc < 99) // { // alarmByte1 |= 0x02; // } // else // { // alarmByte1 &= 0xfd; // } // } // else // { // alarmByte1 &= 0xfd; // } //充电过流告警 if((canMem[0].status_byte3 & 0x1000) != 0) { alarmByte2 |= 0x01; } else { alarmByte2 &= 0xfe; } if(CAN_SendCount ==0) //ID = 0x359 --- 报警/保护、总容量 { totalCapacity = ncc_Ah * OnlineNum; //单位1Ah data[0] = protectByte1; data[1] = protectByte2; data[2] = alarmByte1; data[3] = alarmByte2; data[4] = OnlineNum; data[5] = totalCapacity & 0xFF; data[6] = (totalCapacity >> 8) & 0xFF; data[7] = 0X00; CAN1_SendData(0x359, &data[0]); } if(CAN_SendCount ==1) //ID = 0x351 --- 充/放电限压/限流 { //充放电电流限制需要有符号区别吗? chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V if(chg_forbidFlg == 1) { chgCurLimit = 0; //Luxpower禁充 } else if(chg_curlimitFlg == 1) { chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { dsgCurLimit = 0; //Luxpower禁放 } else { dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } data[0] = chgVolLimit & 0xFF; //充电电压限制低位 data[1] = (chgVolLimit >> 8) & 0xFF; data[2] = chgCurLimit & 0xFF; //充电电流限制低位 data[3] = (chgCurLimit >> 8) & 0xFF; data[4] = dsgCurLimit & 0xFF; //放电电流限制低位 data[5] = (dsgCurLimit >> 8) & 0xFF; data[6] = dsgVolLimit & 0xFF; //放电电压限制低位 data[7] = (dsgVolLimit >> 8) & 0xFF; CAN1_SendData(0x351, &data[0]); } if(CAN_SendCount ==2) //ID = 0x355 --- SOC/SOH、最大/小电压 { cellVolMax = canMem[0].VolMax; cellVolMin = canMem[0].VolMin; data[0] = canMem[0].soc & 0xFF; //SOC data[1] = 0; data[2] = canMem[0].soh & 0xFF; //SOH data[3] = 0; data[4] = cellVolMax & 0xFF; //最大单体电压 data[5] = (cellVolMax >> 8) & 0xFF; data[6] = cellVolMin & 0xFF; //最小单体电压 data[7] = (cellVolMin >> 8) & 0xFF; CAN1_SendData(0x355, &data[0]); } if(CAN_SendCount ==3) //ID = 0x356 --- 总电压/电流、最大/小温度 { tempVol = (uint16_t)(bmsMem.packVoltage/10); //单位0.01 tempCur = (int16_t)(canMem[0].cur/10); //单位0.1 T_Max = canMem[0].TempMax; // 最高温度 单位0.1 T_Min = canMem[0].TempMin; // 最低温度 单位0.1 data[0] = tempVol & 0xFF; data[1] = (tempVol >>8) & 0xFF; //电池包电压 data[2] = tempCur & 0xFF; data[3] = (tempCur >>8) & 0xFF; //电池包电流 data[4] = (T_Max -2731) & 0xFF; //最高单体温度 data[5] = ((T_Max -2731) >> 8) & 0xFF; data[6] = (T_Min -2731) & 0xFF; //最低单体温度 data[7] = ((T_Min -2731) >> 8) & 0xFF; CAN1_SendData(0x356, &data[0]); } if(CAN_SendCount ==4) //ID = 0x35C --- 总电压/电流、最大/小温度 { RequestFlag = 0xC0; //充电允许0x80,放电允许0x40,不强充~0x20 if(chg_forbidFlg == 1)//Lux power { RequestFlag &= 0x7F; //禁充 } if(dsg_forbidFlg == 1)//Lux power { RequestFlag &= 0xBF; //禁放 } if(chg_forceFlg == 1)//Lux power { RequestFlag |= 0x20; //强充 } data[0] = RequestFlag; //充电允许,放电允许 data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0X00; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x35C, &data[0]); } if(CAN_SendCount>=5) { CAN_SendCount = 0; } } //Schneider 施耐德 void CAN_Protocol_Schneider(void) { uint8_t data[8]; uint16_t totalCapacity; //总容量 uint32_t tempVol; //总电压 int32_t tempCur; //总电流 uint32_t chgVolLimit; //充电限压 uint32_t dsgVolLimit; //放电限压 int32_t chgCurLimit; //充电限流 int32_t dsgCurLimit; //放电限流 uint8_t protectByte1 = 0; //保护位1,与告警位1值相同 uint8_t alarmByte1 = 0; int16_t T_Average; // 平均温度 int16_t T_Max; // 最高温度 int16_t T_Min; // 最低温度 uint16_t cellVolMax=0; // 电芯单体最高电压 uint16_t cellVolMin=0; // 电芯单体最低电压 // //Data2 BIT6 cell imbalance // if((bmsMem.balanceStatus & 0x01) !=0) //表示开启了均衡 // { // protectByte1 |= 0xBF; // alarmByte1 |= 0xBF; // } // else // { // protectByte1 &= 0x40; // alarmByte1 &= 0x40; // } //保护 //欠压保护 //cell_uv+pack_uv+l0v if(((canMem[0].status_byte1 & 0x0202) != 0) || ((canMem[0].status_byte3 & 0x0008) != 0)) { protectByte1 |= 0x20; } else { protectByte1 &= 0xDF; } // //过压保护 // //cell_ov+pack_ov+pf // if((canMem[0].status_byte1 & 0x0141) != 0) // { // if(canMem[0].soc < 99) // { // protectByte1 |= 0x10; // } // else // { // protectByte1 &= 0xEF; // } // } // else // { // protectByte1 &= 0xEF; // } //低温保护 //under temp at charging or discharging if(((canMem[0].status_byte2 & 0x0005) != 0) || ((canMem[0].status_byte4 & 0x0C0C) != 0)) { protectByte1 |= 0x08; } else { protectByte1 &= 0xF7; } //过温保护 //over temp at charging or discharging if(((canMem[0].status_byte2 & 0x000A) != 0) || ((canMem[0].status_byte4 & 0x0303) != 0)) { protectByte1 |= 0x04; } else { protectByte1 &= 0xFB; } //放电过流保护 //discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x042c) != 0) || ((canMem[0].status_byte2 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0020) != 0)) { protectByte1 |= 0x02; } else { protectByte1 &= 0xFD; } //充电过流保护 //charge over current if( ((canMem[0].status_byte1 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0010) != 0)) { protectByte1 |= 0x01; } else { protectByte1 &= 0xFE; } //告警 //欠压告警 if((canMem[0].status_byte3 & 0x0A00) != 0) { alarmByte1 |= 0x20; } else { alarmByte1 &= 0xDF; } // //过压告警 // if((canMem[0].status_byte3 & 0x0500) != 0) // { // if(canMem[0].soc < 99) // { // alarmByte1 |= 0x10; // } // else // { // alarmByte1 &= 0xEF; // } // } // else // { // alarmByte1 &= 0xEF; // } //低温告警 if(((canMem[0].status_byte2 & 0xCC00) != 0) || ((canMem[0].status_byte4 & 0xC000) != 0)) { alarmByte1 |= 0x08; } else { alarmByte1 &= 0xF7; } //过温告警 if(((canMem[0].status_byte2 & 0x3300) != 0) || ((canMem[0].status_byte4 & 0x3000) != 0)) { alarmByte1 |= 0x04; } else { alarmByte1 &= 0xFB; } //放电过流告警 if((canMem[0].status_byte3 & 0x2000) != 0) { alarmByte1 |= 0x02; } else { alarmByte1 &= 0xFD; } //充电过流告警 if((canMem[0].status_byte3 & 0x1000) != 0) { alarmByte1 |= 0x01; } else { alarmByte1 &= 0xFE; } if(CAN_SendCount ==0) //ID = 0x321 - 最大充电电压、最小放电电压 { //充放电电流限制需要有符号区别吗? chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V data[0] = 0x00; data[1] = 0x00; data[2] = (chgVolLimit >> 8) & 0xFF; data[3] = chgVolLimit & 0xFF; //最大充电电压 data[4] = 0x00; data[5] = 0x00; data[6] = (dsgVolLimit >> 8) & 0xFF; data[7] = dsgVolLimit & 0xFF; //最小放电电压 CAN1_SendData(0x321, &data[0]); } if(CAN_SendCount ==1) //ID = 0x322 - 最大充电电流、最大放电电流 { //充放电电流限制需要有符号区别吗? if(chg_forbidFlg == 1) { chgCurLimit = 0; //Schneider禁充 } else if(chg_curlimitFlg == 1) { chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { dsgCurLimit = 0; //Schneider禁放 } else { dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } data[0] = 0x00; data[1] = 0x00; data[2] = (chgCurLimit >> 8) & 0xFF; data[3] = chgCurLimit & 0xFF; //最大充电电流 data[4] = 0x00; data[5] = 0x00; data[6] = (dsgCurLimit >> 8) & 0xFF; data[7] = dsgCurLimit & 0xFF; //最大放电电流 CAN1_SendData(0x322, &data[0]); } if(CAN_SendCount ==2) //ID = 0x323 - 电池电压、电流 { tempVol = (int16_t)(bmsMem.packVoltage/10); //单位0.01 tempCur = (int16_t)(canMem[0].cur/10); //单位0.1 data[0] = 0x00; data[1] = 0x00; data[2] = (tempVol >>8) & 0xFF; //电池组电压 0.01 data[3] = tempVol & 0xFF; data[4] = 0x00; data[5] = 0x00; data[6] = (tempCur >>8) & 0xFF; //电池组电流 0.1 data[7] = tempCur & 0xFF; CAN1_SendData(0x323, &data[0]); } if(CAN_SendCount ==3) //ID = 0x324 - 温度、SOC { totalCapacity = 100 * ncc_Ah * OnlineNum; //单位0.01Ah T_Average = canMem[0].temp;// 平均温度 data[0] = ((T_Average-2731) >>8) & 0xFF; data[1] = (T_Average-2731) & 0xFF; //平均温度 0.1 data[2] = 0x00; data[3] = canMem[0].soc & 0xFF; //SOC data[4] = 0x00; data[5] = 0x00; data[6] = 0x00; data[7] = 0x00; CAN1_SendData(0x324, &data[0]); } if(CAN_SendCount ==4) //ID = 0x325 - 允许位、报警/保护 { RequestFlag = 0xC0; //充电允许0x02,放电允许0x04,不强充~0x01 if(chg_forbidFlg == 1)//Schneider { RequestFlag &= 0xFD; //禁充 } if(dsg_forbidFlg == 1)//Schneider { RequestFlag &= 0xFB; //禁放 } if(chg_forceFlg == 1)//Schneider { RequestFlag |= 0x01; //强充 } data[0] = RequestFlag; //充电允许放电允许 data[1] = 0x00; data[2] = protectByte1; data[3] = 0x00; data[4] = alarmByte1; data[5] = 0x00; data[6] = 0x00; data[7] = 0x00; CAN1_SendData(0x325, &data[0]); } if(CAN_SendCount ==5) //ID = 0x326 - SOH、满充容量 { totalCapacity = 100 * ncc_Ah * OnlineNum; //单位0.01Ah data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0; data[5] = canMem[0].soh & 0xFF; //SOH data[6] = (totalCapacity >> 8) & 0xFF; data[7] = totalCapacity & 0xFF; //电池满充容量 10mAh CAN1_SendData(0x326, &data[0]); } if(CAN_SendCount ==6) //ID = 0x327 - 电池最高/低温度、电池最高/低电压 { T_Max = canMem[0].TempMax; // 最高温度 T_Min = canMem[0].TempMin; // 最低温度 cellVolMax = canMem[0].VolMax; cellVolMin = canMem[0].VolMin; data[0] = ((T_Max -2731) >> 8) & 0xFF; data[1] = (T_Max -2731) & 0xFF; //最大电池温度 data[2] = ((T_Min -2731) >> 8) & 0xFF; data[3] = (T_Min -2731) & 0xFF; //最小电池温度 data[4] = (cellVolMax >> 8) & 0xFF; data[5] = cellVolMax & 0xFF; //最大电池电压 data[6] = (cellVolMin >> 8) & 0xFF; data[7] = cellVolMin & 0xFF; //最小电池电压 CAN1_SendData(0x327, &data[0]); } if(CAN_SendCount>=7) { CAN_SendCount = 0; } } //AlpSolarr 力高 void CAN_Protocol_AlpSolarr(void) { uint8_t data[8]; uint16_t totalCapacity; uint16_t tempVol; int16_t tempCur; uint16_t chgVolLimit; uint16_t dsgVolLimit; int16_t chgCurLimit; int16_t dsgCurLimit; uint8_t protectByte1 = 0; uint8_t protectByte2 = 0; int16_t T_Average; // 平均温度 int16_t T_Max; // 最高温度 int16_t T_Min; // 最低温度 uint16_t cellVolMax=0; // 电芯单体最高电压 int16_t cellVolMin=0; // 电芯单体最低电压 //BIT7 discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x2c) !=0) || ((canMem[0].status_byte4 & 0x20) !=0) ) { protectByte1 |= 0x80; } else { protectByte1 &= 0x7f; } //BIT4 cell under temp at charging or discharging //add mcu temp protect status if( ((canMem[0].status_byte2 & 0x05) !=0) || ((canMem[0].status_byte4 & 0x0C) !=0) ) { protectByte1 |= 0x10; } else { protectByte1 &= 0xEF; } //BIT3 cell over temp at charging or discharging //add mcu temp protect status if( ((canMem[0].status_byte2 & 0x0A) !=0) || ((canMem[0].status_byte4 & 0x03) !=0) ) { protectByte1 |= 0x08; } else { protectByte1 &= 0xF7; } //BIT2 cell uv if((canMem[0].status_byte1 & 0x02) !=0) { protectByte1 |= 0x04; } else { protectByte1 &= 0xfb; } //BIT1 cell ov if((canMem[0].status_byte1 & 0x01) !=0) { if(canMem[0].soc < 99) { protectByte1 |= 0x02; } else { protectByte1 &= 0xfd; } } else { protectByte1 &= 0xfd; } //BIT0 charge over current if( ((canMem[0].status_byte1 & 0x10) !=0) || ((canMem[0].status_byte4 & 0x10) !=0) ) { protectByte2 |= 0x01; } else { protectByte2 &= 0xfe; } // //Data1 BIT4 cell balance // if((bmsMem.balanceStatus & 0x01) !=0) // { // protectByte2 |= 0x10; // } // else // { // protectByte2 &= 0xef; // } if(CAN_SendCount ==0) //ID=0x359 { data[0] = protectByte1; data[1] = protectByte2; data[2] = protectByte1; data[3] = protectByte2; data[4] = 0X00; data[5] = 0X00; data[6] = 0X00; data[7] = 0X00; CAN1_SendData(0x359, &data[0]); } if(CAN_SendCount ==1) //ID = 0x351 { //充放电电流限制需要有符号区别吗? chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V if(chg_forbidFlg == 0) { chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } else { chgCurLimit = 0; //禁充 } if(dsg_forbidFlg == 0) { dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } else { dsgCurLimit = 0; //禁放 } data[0] = chgVolLimit & 0xFF; //充电电压限制低位 data[1] = (chgVolLimit >> 8) & 0xFF; data[2] = chgCurLimit & 0xFF; //充电电流限制低位 data[3] = (chgCurLimit >> 8) & 0xFF; data[4] = dsgCurLimit & 0xFF; //放电电流限制低位 data[5] = (dsgCurLimit >> 8) & 0xFF; data[6] = dsgVolLimit & 0xFF; //放电电压限制低位 data[7] = (dsgVolLimit >> 8) & 0xFF; CAN1_SendData(0x351, &data[0]); } if(CAN_SendCount ==2) { data[0] = canMem[0].soc & 0xFF; //SOC data[1] = 0; data[2] = canMem[0].soh & 0xFF; //SOH data[3] = 0; data[4] = 0X00; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x355, &data[0]); } if(CAN_SendCount ==3) { tempVol = (uint16_t)(bmsMem.packVoltage/10); //单位0.01 tempCur = (int16_t)(canMem[0].cur/10); //单位0.1 T_Average = canMem[0].temp;// 平均温度 data[0] = tempVol & 0xFF; data[1] = (tempVol >>8) & 0xFF; //电池包电压 data[2] = tempCur & 0xFF; data[3] = (tempCur >>8) & 0xFF; //电池包电流 data[4] = (T_Average -2731) & 0xFF;; data[5] = ((T_Average -2731) >>8) & 0xFF; //温度-暂时取平均温度,具体哪一路需要客户确认 data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x356, &data[0]); } if(CAN_SendCount ==4) //ID = 0x370 - 最大/最小单体温度,最大/最小单体电压(新加入) { T_Max = canMem[0].TempMax; // 最高温度 T_Min = canMem[0].TempMin; // 最低温度 cellVolMax = canMem[0].VolMax; cellVolMin = canMem[0].VolMin; data[0] = (T_Max -2731) & 0xFF; //最大单体温度 data[1] = ((T_Max -2731) >> 8) & 0xFF; data[2] = (T_Min -2731) & 0xFF; //最小单体温度 data[3] = ((T_Min -2731) >> 8) & 0xFF; data[4] = cellVolMax & 0xFF; //最大单体电压 data[5] = (cellVolMax >> 8) & 0xFF; data[6] = cellVolMin & 0xFF; //最小单体电压 data[7] = (cellVolMin >> 8) & 0xFF; CAN1_SendData(0x370, &data[0]); } if(CAN_SendCount ==5) { RequestFlag = 0xC0; //充电允许0x80,放电允许0x40,不强充~0x20 if(chg_forbidFlg == 1) { RequestFlag &= 0x7F; //禁充 } if(dsg_forbidFlg == 1) { RequestFlag &= 0xBF; //禁放 } if(chg_forceFlg == 1) { RequestFlag |= 0x20; //强充 } data[0] = RequestFlag; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0X00; data[5] = 0x00; data[6] = 0x00; data[7] = 0X00; CAN1_SendData(0x35C, &data[0]); } if(CAN_SendCount ==6) //0x35E { totalCapacity = fcc_Ah * OnlineNum; //单位1Ah data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0x00; data[5] = 0x00; data[6] = totalCapacity & 0xFF; data[7] = (totalCapacity >> 8) & 0xFF; CAN1_SendData(0x35E, &data[0]); } // if(CAN_SendCount ==7) // { // data[0] = 0xAA; // data[1] = 0xAA; // data[2] = 0xAA; // data[3] = 0xAA; // data[4] = 0xAA; // data[5] = 0xAA; // data[6] = 0xAA; // data[7] = 0xAA; // CAN1_SendData(0x305, &data[0]); // } if(CAN_SendCount>=7) { CAN_SendCount = 0; } } //MODBUS: //SRNE 硕日 void MOD_Protocol_SRNE(void) { uint8_t i; uint16_t protectByte = 0; //0x0000-0xFFFF uint16_t alarmByte = 0; uint16_t statusByte = 0; //保护 // //单体过压保护 // //cell_ov+pack_ov+pf // if(((canMem[0].status_byte1 & 0x0001) != 0) || ((canMem[0].status_byte1 & 0x0040) != 0)) // { // if(canMem[0].soc < 99) // { // alarmByte |= 0x0001; // } // else // { // alarmByte &= 0xFFFE; // } // } // else // { // alarmByte &= 0xFFFE; // } //单体欠压保护 //cell_uv+pack_uv+l0v if(((canMem[0].status_byte1 & 0x0002) != 0) || ((canMem[0].status_byte3 & 0x0008) != 0)) { alarmByte |= 0x0002; } else { alarmByte &= 0xFFFD; } // //总体过压保护 // if((canMem[0].status_byte1 & 0x0100) != 0) // { // alarmByte |= 0x0004; // } // else // { // alarmByte &= 0xFFFB; // } //总体欠压保护 if((canMem[0].status_byte1 & 0x0200) != 0) { alarmByte |= 0x0008; } else { alarmByte &= 0xFFF7; } //充电过流保护 //charge over current if( ((canMem[0].status_byte1 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0010) != 0)) { protectByte |= 0x0010; } else { protectByte &= 0xFFEF; } //放电过流保护 //discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x042c) != 0) || ((canMem[0].status_byte2 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0020) != 0)) { protectByte |= 0x0020; } else { protectByte &= 0xFFDF; } //充电高温保护 //charge over temp 高温 if( ((canMem[0].status_byte2 & 0x0002) !=0) || ((canMem[0].status_byte4 & 0x0101) !=0) ) { protectByte |= 0x0100; } else { protectByte &= 0xFEFF; } //放电高温保护 //discharge over temp if( ((canMem[0].status_byte2 & 0x0008) !=0) || ((canMem[0].status_byte4 & 0x0202) !=0) ) { protectByte |= 0x0200; } else { protectByte &= 0xFDFF; } //充电低温保护 //charge under temp 低温 if( ((canMem[0].status_byte2 & 0x0001) !=0) || ((canMem[0].status_byte4 & 0x0404) !=0) ) { protectByte |= 0x0400; } else { protectByte &= 0xFBFF; } //放电低温保护 //discharge under temp if( ((canMem[0].status_byte2 & 0x0004) !=0) || ((canMem[0].status_byte4 & 0x0808) !=0) ) { protectByte |= 0x0800; } else { protectByte &= 0xF7FF; } //环境低温保护 0x4000 if((canMem[0].status_byte4 & 0x0C00) !=0) //环境充放电低温 { protectByte |= 0x4000; } else { protectByte &= 0xBFFF; } //环境高温保护 0x2000 if((canMem[0].status_byte4 & 0x0300) !=0) //环境充放电高温 { protectByte |= 0x2000; } else { protectByte &= 0xDFFF; } //MOS高温保护 0x1000 if((canMem[0].status_byte2 & 0x0300) !=0) //MOS充放电高温 { protectByte |= 0x1000; } else { protectByte &= 0xEFFF; } //告警 // //单体过压告警 // //cell_ov+pack_ov+pf // if((canMem[0].status_byte3 & 0x0100) != 0) // { // if(canMem[0].soc < 99) // { // alarmByte |= 0x0001; // } // else // { // alarmByte &= 0xFFFE; // } // } // else // { // alarmByte &= 0xFFFE; // } //单体欠压告警 //cell_uv+pack_uv+l0v if((canMem[0].status_byte3 & 0x0200) != 0) { alarmByte |= 0x0002; } else { alarmByte &= 0xFFFD; } // //总体过压告警 // if((canMem[0].status_byte3 & 0x0400) != 0) // { // alarmByte |= 0x0004; // } // else // { // alarmByte &= 0xFFFB; // } //总体欠压告警 if((canMem[0].status_byte3 & 0x0800) != 0) { alarmByte |= 0x0008; } else { alarmByte &= 0xFFF7; } //充电过流告警 //charge over current if((canMem[0].status_byte3 & 0x1000) != 0) { alarmByte |= 0x0010; } else { alarmByte &= 0xFFEF; } //放电过流告警 //discharge over current,SC, OCD1, OCD2 if((canMem[0].status_byte3 & 0x0200) != 0) { alarmByte |= 0x0020; } else { alarmByte &= 0xFFDF; } //充电高温告警 //charge over temp 高温 if( ((canMem[0].status_byte2 & 0x1100) !=0) || ((canMem[0].status_byte4 & 0x1000) !=0) ) { alarmByte |= 0x0100; } else { alarmByte &= 0xFEFF; } //放电高温告警 //discharge over temp if( ((canMem[0].status_byte2 & 0x2200) !=0) || ((canMem[0].status_byte4 & 0x2000) !=0) ) { alarmByte |= 0x0200; } else { alarmByte &= 0xFDFF; } //充电低温告警 //charge under temp 低温 if( ((canMem[0].status_byte2 & 0x4400) !=0) || ((canMem[0].status_byte4 & 0x4000) !=0) ) { alarmByte |= 0x0400; } else { alarmByte &= 0xFBFF; } //放电低温告警 //discharge under temp if( ((canMem[0].status_byte2 & 0x8800) !=0) || ((canMem[0].status_byte4 & 0x8000) !=0) ) { alarmByte |= 0x0800; } else { alarmByte &= 0xF7FF; } //环境低温告警 0x4000 if((canMem[0].status_byte4 & 0xC000) !=0) //环境充放电低温 { alarmByte |= 0x4000; } else { alarmByte &= 0xBFFF; } //环境高温告警 0x2000 if((canMem[0].status_byte4 & 0x3000) !=0) //环境充放电高温 { alarmByte |= 0x2000; } else { alarmByte &= 0xDFFF; } //MOS高温告警 0x1000 if((canMem[0].status_byte2 & 0x3000) !=0) //MOS充放电高温 { alarmByte |= 0x1000; } else { alarmByte &= 0xEFFF; } SRNEMem.protect_byte = protectByte; //保护标志 Hex 2byte SRNEMem.alarm_byte = alarmByte; //告警标志 Hex 2byte //状态位赋值 if(bCHGING == 1) //充电 { statusByte |= 0x0100; } else { statusByte &= 0xFEFF; } if(bDSGING == 1) //放电 { statusByte |= 0x0200; } else { statusByte &= 0xFDFF; } if((canMem[0].status_byte3 & 0x02) !=0) //充电MOS状态 { statusByte |= 0x0400; } else { statusByte &= 0xFBFF; } if((canMem[0].status_byte3 & 0x01) !=0) //放电MOS状态 { statusByte |= 0x0800; } else { statusByte &= 0xF7FF; } SRNEMem.status_byte = statusByte; //状态/故障标志 Hex 2byte SRNEMem.balanceStatus = bmsMem.balanceStatus;//平衡状态 Hex 2byte SRNEMem.packCurrent = (int16_t)(canMem[0].cur); //电流 10mA 2byte SRNEMem.packVoltage = (uint16_t)(bmsMem.packVoltage/10); //电池组电压 10mA 2byte SRNEMem.soc = (uint8_t)canMem[0].soc; //SOC % 2byte SRNEMem.soh = (uint8_t)canMem[0].soh; //SOH % 2byte SRNEMem.fcc = 100 * ncc_Ah * OnlineNum; //满容量 10mAH 2byte SRNEMem.rcc = 100 * ncc_Ah * OnlineNum * SRNEMem.soc/100; //剩余容量 10mAH 2byte //电芯电压 for(i=0;i<16;i++) { SRNEMem.vCell[i] = bmsMem.vCell[i]; //电池电压 mV 32byte } //电芯温度 SRNEMem.Tcell[0] = (int16_t)(bmsMem.mcu_T1-2731); //电池温度 0.1℃ 8byte SRNEMem.Tcell[1] = (int16_t)(bmsMem.mcu_T2-2731); SRNEMem.Tcell[2] = (int16_t)(bmsMem.mcu_T3-2731); SRNEMem.Tcell[3] = (int16_t)(bmsMem.mcu_T4-2731); SRNEMem.afe_MOS = (int16_t)((bmsMem.afe_T1 + bmsMem.afe_T2)/2 - 2731); //MOS温度 0.1℃ 2byte 对应上下MOS的温度平均值 SRNEMem.afe_MCU = (int16_t)(bmsMem.afe_T3-2731); //环境温度 0.1℃ 2byte 对应MCU芯片温度 //充放电电流限制需要有符号区别吗? SRNEMem.chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V //SRNEMem.dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V if(chg_forbidFlg == 1) { SRNEMem.chgCurLimit = 0; //SRNE禁充 } else if(chg_curlimitFlg == 1) { SRNEMem.chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { SRNEMem.chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { SRNEMem.dsgCurLimit = 0; //SRNE禁放 } else { SRNEMem.dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } } //Voltronic 日月元 void MOD_Protocol_Voltronic(void) { uint8_t i; uint16_t chg_alarm_byte = 0; uint16_t dsg_alarm_byte = 0; uint16_t chg_protect1_byte = 0; uint16_t dsg_protect1_byte = 0; //充电告警 //充电过流告警 //charge over current if((canMem[0].status_byte3 & 0x1000) !=0) { chg_alarm_byte |= 0x0008; } else { chg_alarm_byte &= 0xFFF7; } //充电低温告警 //charge under temp if( ((canMem[0].status_byte2 & 0x4400) !=0) || ((canMem[0].status_byte4 & 0x4000) !=0) ) { chg_alarm_byte |= 0x0004; } else { chg_alarm_byte &= 0xFFFB; } // //过压告警 // if((canMem[0].status_byte3 & 0x0500) != 0) // { // if(canMem[0].soc < 99) // { // chg_alarm_byte |= 0x0002; // } // else // { // chg_alarm_byte &= 0xFFFD; // } // } // else // { // chg_alarm_byte &= 0xFFFD; // } //充电高温告警 //charge over temp if( ((canMem[0].status_byte2 & 0x1100) !=0) || ((canMem[0].status_byte4 & 0x1000) !=0) ) { chg_alarm_byte |= 0x0001; } else { chg_alarm_byte &= 0xFFFE; } //放电告警 //欠压告警 if((canMem[0].status_byte3 & 0x0A00) != 0) { dsg_alarm_byte |= 0x0008; } else { dsg_alarm_byte &= 0xFFF7; } //MOS高温告警 if((canMem[0].status_byte2 & 0x0200) != 0) { dsg_alarm_byte |= 0x0004; } else { dsg_alarm_byte &= 0xFFFB; } //放电低温告警 //discharge under temp if( ((canMem[0].status_byte2 & 0x8800) !=0) || ((canMem[0].status_byte4 & 0x8000) !=0) ) { dsg_alarm_byte |= 0x0002; } else { dsg_alarm_byte &= 0xFFFD; } //放电高温告警 //discharge over temp if( ((canMem[0].status_byte2 & 0x2200) !=0) || ((canMem[0].status_byte4 & 0x2000) !=0) ) { dsg_alarm_byte |= 0x0001; } else { dsg_alarm_byte &= 0xFFFE; } //保护 //充电保护1 //充电过流保护 //charge over current if( ((canMem[0].status_byte1 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0010) != 0)) { chg_protect1_byte |= 0x0800; } else { chg_protect1_byte &= 0xF7FF; } //过压保护 // //cell_ov+pack_ov+pf // if((canMem[0].status_byte1 & 0x0141) != 0) // { // if(canMem[0].soc < 99) // { // chg_protect1_byte |= 0x0400; // } // else // { // chg_protect1_byte &= 0xFBFF; // } // } // else // { // chg_protect1_byte &= 0xFBFF; // } //充电低温保护 //charge under temp if( ((canMem[0].status_byte2 & 0x0001) !=0) || ((canMem[0].status_byte4 & 0x0404) !=0) ) { chg_protect1_byte |= 0x0200; } else { chg_protect1_byte &= 0xFBFF; } //充电高温保护 //charge over temp if( ((canMem[0].status_byte2 & 0x0002) !=0) || ((canMem[0].status_byte4 & 0x0101) !=0) ) { chg_protect1_byte |= 0x0100; } else { chg_protect1_byte &= 0xFEFF; } //MOS高温保护 if((canMem[0].status_byte2 & 0x0100) != 0) { dsg_alarm_byte |= 0x0040; } else { dsg_alarm_byte &= 0xFFBF; } //放电保护1 //放电高温保护 //discharge over temp if( ((canMem[0].status_byte2 & 0x0008) !=0) || ((canMem[0].status_byte4 & 0x0202) !=0) ) { dsg_protect1_byte |= 0x4000; } else { dsg_protect1_byte &= 0xBFFF; } //放电低温保护 //discharge under temp if( ((canMem[0].status_byte2 & 0x0004) !=0) || ((canMem[0].status_byte4 & 0x0808) !=0) ) { dsg_protect1_byte |= 0x2000; } else { dsg_protect1_byte &= 0xBFFF; } //放电过流保护 //discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x042c) !=0) || ((canMem[0].status_byte2 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0020) !=0) ) { dsg_protect1_byte |= 0x1000; } else { dsg_protect1_byte &= 0xEFFF; } //欠压保护 //cell_uv+pack_uv+l0v if(((canMem[0].status_byte1 & 0x0202) != 0) || ((canMem[0].status_byte3 & 0x0008) != 0)) { dsg_protect1_byte |= 0x0800; } else { dsg_protect1_byte &= 0xF7FF; } RequestFlag = 0x00C0; //充电允许0x0080,放电允许0x0040,不强充~0x0020 if(chg_forbidFlg == 1)//Voltronic { RequestFlag &= 0xFF7F; //禁充 } if(dsg_forbidFlg == 1)//Voltronic { RequestFlag &= 0xFFBF; //禁放 } if(chg_forceFlg == 1)//Voltronic { RequestFlag |= 0x0020; //强充 } VoltronicMem.chg_alarm_byte = chg_alarm_byte; // 充电报警 VoltronicMem.dsg_alarm_byte = dsg_alarm_byte; // 放电报警 VoltronicMem.chg_protect1_byte = chg_protect1_byte; // 充电保护 VoltronicMem.dsg_protect1_byte = dsg_protect1_byte; // 放电保护 VoltronicMem.status_byte = RequestFlag; // 充放电允许 //常规数据填充 VoltronicMem.protocolType = 0x0000; VoltronicMem.protocolVer = 0x0100; VoltronicMem.SoftwareH = VersionMem.Software[0]<<8 | VersionMem.Software[1]; VoltronicMem.SoftwareL = VersionMem.Software[2]<<8 | VersionMem.Software[3]; VoltronicMem.HardwareH = VersionMem.Hardware[0]; VoltronicMem.HardwareL = VersionMem.Hardware[1]<<8 | VersionMem.Hardware[2]; //实时数据 VoltronicMem.packNum = OnlineNum; VoltronicMem.cellNum = bmsMem.ucCellNum; VoltronicMem.tempNum = 6; //电芯电压 for(i=0;i<16;i++) { VoltronicMem.cellVol[i] = bmsMem.vCell[i]/100; //电池电压 0.1V } //电芯温度 VoltronicMem.T[0] = bmsMem.mcu_T1; //电池温度 0.1K VoltronicMem.T[1] = bmsMem.mcu_T2; VoltronicMem.T[2] = bmsMem.mcu_T3; VoltronicMem.T[3] = bmsMem.mcu_T4; VoltronicMem.T[4] = bmsMem.afe_T3; VoltronicMem.T[5] = (bmsMem.afe_T1 + bmsMem.afe_T2)/2; if(bCHGING==1) { VoltronicMem.chg_packCurrent = (uint16_t)(canMem[0].cur/10); //充电电流 0.1A 2byte VoltronicMem.dsg_packCurrent = 0; } else { VoltronicMem.dsg_packCurrent = (uint16_t)(-canMem[0].cur/10); //放电电流 0.1A 2byte VoltronicMem.chg_packCurrent = 0; } VoltronicMem.packVoltage = (uint16_t)(bmsMem.packVoltage/100); //模块电压 0.1V 2byte //mAH /3600 VoltronicMem.soc = canMem[0].soc; //SOC % 2byte VoltronicMem.fccH = ((1000 * ncc_Ah * OnlineNum)>>16) & 0xFFFF; //满容量 mAH 4byte VoltronicMem.fccL = (1000 * ncc_Ah * OnlineNum) & 0xFFFF; VoltronicMem.rccH = ((1000 * ncc_Ah * OnlineNum * VoltronicMem.soc/100)>>16) & 0xFFFF; //剩余容量 mAH 4byte VoltronicMem.rccL = (1000 * ncc_Ah * OnlineNum * VoltronicMem.soc/100) & 0xFFFF; VoltronicMem.chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V VoltronicMem.dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V if(chg_forbidFlg == 1) { VoltronicMem.chgCurLimit = 0; //Voltronic禁充 } else if(chg_curlimitFlg == 1) { VoltronicMem.chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { VoltronicMem.chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { VoltronicMem.dsgCurLimit = 0; //Voltronic禁放 } else { VoltronicMem.dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } VoltronicMem.cellNum2 = bmsMem.ucCellNum; VoltronicMem.tempNum2 = 6; //各种状态位,0xF0表示未实现 for(i=0;i<10;i++) { VoltronicMem.Vol_status[i]=0xF0; } for(i=0;i<5;i++) { VoltronicMem.T_status[i]=0xF0; } for(i=0;i<10;i++) { VoltronicMem.other_status[i]=0xF0; } } //COSUPER 古顶 void MOD_Protocol_COSUPER(void) { uint8_t i; uint16_t protectByte = 0; //0x0000-0xFFFF uint16_t alarmByte = 0; uint16_t statusByte = 0; //保护 // //单体过压保护 // //cell_ov+pack_ov+pf // if(((canMem[0].status_byte1 & 0x0001) != 0) || ((canMem[0].status_byte1 & 0x0040) != 0)) // { // if(canMem[0].soc < 99) // { // alarmByte |= 0x0001; // } // else // { // alarmByte &= 0xFFFE; // } // } // else // { // alarmByte &= 0xFFFE; // } //单体欠压保护 //cell_uv+pack_uv+l0v if(((canMem[0].status_byte1 & 0x0002) != 0) || ((canMem[0].status_byte3 & 0x0008) != 0)) { alarmByte |= 0x0002; } else { alarmByte &= 0xFFFD; } // //总体过压保护 // if((canMem[0].status_byte1 & 0x0100) != 0) // { // alarmByte |= 0x0004; // } // else // { // alarmByte &= 0xFFFB; // } //总体欠压保护 if((canMem[0].status_byte1 & 0x0200) != 0) { alarmByte |= 0x0008; } else { alarmByte &= 0xFFF7; } //充电过流保护 //charge over current if( ((canMem[0].status_byte1 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0010) != 0)) { protectByte |= 0x0010; } else { protectByte &= 0xFFEF; } //放电过流保护 //discharge over current,SC, OCD1, OCD2 if( ((canMem[0].status_byte1 & 0x042c) != 0) || ((canMem[0].status_byte2 & 0x0010) != 0) || ((canMem[0].status_byte4 & 0x0020) != 0)) { protectByte |= 0x0020; } else { protectByte &= 0xFFDF; } //充电高温保护 //charge over temp 高温 if( ((canMem[0].status_byte2 & 0x0002) !=0) || ((canMem[0].status_byte4 & 0x0101) !=0) ) { protectByte |= 0x0100; } else { protectByte &= 0xFEFF; } //放电高温保护 //discharge over temp if( ((canMem[0].status_byte2 & 0x0008) !=0) || ((canMem[0].status_byte4 & 0x0202) !=0) ) { protectByte |= 0x0200; } else { protectByte &= 0xFDFF; } //充电低温保护 //charge under temp 低温 if( ((canMem[0].status_byte2 & 0x0001) !=0) || ((canMem[0].status_byte4 & 0x0404) !=0) ) { protectByte |= 0x0400; } else { protectByte &= 0xFBFF; } //放电低温保护 //discharge under temp if( ((canMem[0].status_byte2 & 0x0004) !=0) || ((canMem[0].status_byte4 & 0x0808) !=0) ) { protectByte |= 0x0800; } else { protectByte &= 0xF7FF; } //环境低温保护 0x4000 if((canMem[0].status_byte4 & 0x0C00) !=0) //环境充放电低温 { protectByte |= 0x4000; } else { protectByte &= 0xBFFF; } //环境高温保护 0x2000 if((canMem[0].status_byte4 & 0x0300) !=0) //环境充放电高温 { protectByte |= 0x2000; } else { protectByte &= 0xDFFF; } //MOS高温保护 0x1000 if((canMem[0].status_byte2 & 0x0300) !=0) //MOS充放电高温 { protectByte |= 0x1000; } else { protectByte &= 0xEFFF; } //告警 // //单体过压告警 // //cell_ov+pack_ov+pf // if((canMem[0].status_byte3 & 0x0100) != 0) // { // if(canMem[0].soc < 99) // { // alarmByte |= 0x0001; // } // else // { // alarmByte &= 0xFFFE; // } // } // else // { // alarmByte &= 0xFFFE; // } //单体欠压告警 //cell_uv+pack_uv+l0v if((canMem[0].status_byte3 & 0x0200) != 0) { alarmByte |= 0x0002; } else { alarmByte &= 0xFFFD; } // //总体过压告警 // if((canMem[0].status_byte3 & 0x0400) != 0) // { // alarmByte |= 0x0004; // } // else // { // alarmByte &= 0xFFFB; // } //总体欠压告警 if((canMem[0].status_byte3 & 0x0800) != 0) { alarmByte |= 0x0008; } else { alarmByte &= 0xFFF7; } //充电过流告警 //charge over current if((canMem[0].status_byte3 & 0x1000) != 0) { alarmByte |= 0x0010; } else { alarmByte &= 0xFFEF; } //放电过流告警 //discharge over current,SC, OCD1, OCD2 if((canMem[0].status_byte3 & 0x0200) != 0) { alarmByte |= 0x0020; } else { alarmByte &= 0xFFDF; } //充电高温告警 //charge over temp 高温 if( ((canMem[0].status_byte2 & 0x1100) !=0) || ((canMem[0].status_byte4 & 0x1000) !=0) ) { alarmByte |= 0x0100; } else { alarmByte &= 0xFEFF; } //放电高温告警 //discharge over temp if( ((canMem[0].status_byte2 & 0x2200) !=0) || ((canMem[0].status_byte4 & 0x2000) !=0) ) { alarmByte |= 0x0200; } else { alarmByte &= 0xFDFF; } //充电低温告警 //charge under temp 低温 if( ((canMem[0].status_byte2 & 0x4400) !=0) || ((canMem[0].status_byte4 & 0x4000) !=0) ) { alarmByte |= 0x0400; } else { alarmByte &= 0xFBFF; } //放电低温告警 //discharge under temp if( ((canMem[0].status_byte2 & 0x8800) !=0) || ((canMem[0].status_byte4 & 0x8000) !=0) ) { alarmByte |= 0x0800; } else { alarmByte &= 0xF7FF; } //环境低温告警 0x4000 if((canMem[0].status_byte4 & 0xC000) !=0) //环境充放电低温 { alarmByte |= 0x4000; } else { alarmByte &= 0xBFFF; } //环境高温告警 0x2000 if((canMem[0].status_byte4 & 0x3000) !=0) //环境充放电高温 { alarmByte |= 0x2000; } else { alarmByte &= 0xDFFF; } //MOS高温告警 0x1000 if((canMem[0].status_byte2 & 0x3000) !=0) //MOS充放电高温 { alarmByte |= 0x1000; } else { alarmByte &= 0xEFFF; } SRNEMem.protect_byte = protectByte; //保护标志 Hex 2byte SRNEMem.alarm_byte = alarmByte; //告警标志 Hex 2byte //状态位赋值 if(bCHGING == 1) //充电 { statusByte |= 0x0100; } else { statusByte &= 0xFEFF; } if(bDSGING == 1) //放电 { statusByte |= 0x0200; } else { statusByte &= 0xFDFF; } if((canMem[0].status_byte3 & 0x02) !=0) //充电MOS状态 { statusByte |= 0x0400; } else { statusByte &= 0xFBFF; } if((canMem[0].status_byte3 & 0x01) !=0) //放电MOS状态 { statusByte |= 0x0800; } else { statusByte &= 0xF7FF; } SRNEMem.status_byte = statusByte; //状态/故障标志 Hex 2byte SRNEMem.balanceStatus = bmsMem.balanceStatus;//平衡状态 Hex 2byte SRNEMem.packCurrent = (int16_t)(canMem[0].cur); //电流 10mA 2byte SRNEMem.packVoltage = (uint16_t)(bmsMem.packVoltage/10); //电池组电压 10mA 2byte SRNEMem.soc = (uint8_t)canMem[0].soc; //SOC % 2byte SRNEMem.soh = (uint8_t)canMem[0].soh; //SOH % 2byte SRNEMem.fcc = 100 * ncc_Ah * OnlineNum; //满容量 10mAH 2byte SRNEMem.rcc = 100 * ncc_Ah * OnlineNum * SRNEMem.soc/100; //剩余容量 10mAH 2byte //电芯电压 if( bmsMem.ucCellNum == 8) //板子设定为8串 { for(i=0;i<8;i++) { SRNEMem.vCell[i] = bmsMem.vCell[i]; //电池电压 mV 32byte } for(i=0;i<8;i++) { SRNEMem.vCell[8+i] = bmsMem.vCell[i]; //电池电压 mV 32byte } } else //其他默认为16串 { for(i=0;i<16;i++) { SRNEMem.vCell[i] = bmsMem.vCell[i]; //电池电压 mV 32byte } } //电芯温度 SRNEMem.Tcell[0] = (int16_t)(bmsMem.mcu_T1-2731); //电池温度 0.1℃ 8byte SRNEMem.Tcell[1] = (int16_t)(bmsMem.mcu_T2-2731); SRNEMem.Tcell[2] = (int16_t)(bmsMem.mcu_T3-2731); SRNEMem.Tcell[3] = (int16_t)(bmsMem.mcu_T4-2731); SRNEMem.afe_MOS = (int16_t)((bmsMem.afe_T1 + bmsMem.afe_T2)/2 - 2731); //MOS温度 0.1℃ 2byte 对应上下MOS的温度平均值 SRNEMem.afe_MCU = (int16_t)(bmsMem.afe_T3-2731); //环境温度 0.1℃ 2byte 对应MCU芯片温度 //充放电电流限制需要有符号区别吗? SRNEMem.chgVolLimit = bmsMem.inverter_chgVolLimit; //充电电压限制,上位机配置,默认值57.6V //SRNEMem.dsgVolLimit = bmsMem.inverter_dsgVolLimit; //放电电压限制,上位机配置,默认值41.6V if(chg_forbidFlg == 1) { SRNEMem.chgCurLimit = 0; //COSUPER禁充 } else if(chg_curlimitFlg == 1) { SRNEMem.chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { SRNEMem.chgCurLimit = bmsMem.inverter_chgCurLimit * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { SRNEMem.dsgCurLimit = 0; //COSUPER禁放 } else { SRNEMem.dsgCurLimit = bmsMem.inverter_dsgCurLimit * (OnlineNum-dsg_curLimitNum); //放电电流限制,上位机配置,默认值100A } } //SMK void MOD_Protocol_SMK(void) { RequestFlag = 0x0060; //充电允许0x0040,放电允许0x0020,不强充~0x1000 if(chg_forbidFlg == 1)//SMK { RequestFlag &= 0xFFBF; //禁充 } if(dsg_forbidFlg == 1)//SMK { RequestFlag &= 0xFFDF; //禁放 } if(chg_forceFlg == 1)//SMK { RequestFlag |= 0x1000; //强充 } SMKMem.status_byte = RequestFlag; //状态:bit6充电禁止bit5放电禁止 SMKMem.soc = (uint8_t)canMem[0].soc; //SOC % 2byte SMKMem.rcc = 100 * ncc_Ah * OnlineNum * SMKMem.soc/100;//剩余容量 10mAH 2byte SMKMem.fcc = 100 * ncc_Ah * OnlineNum; //额定容量 10mAH 2byte SMKMem.packVoltage = (int16_t)(bmsMem.packVoltage/10); //模块电压 10mV 2byte SMKMem.packCurrent = (int16_t)(canMem[0].cur); //模块电流 10mA 2byte SMKMem.chgVolLimit = bmsMem.inverter_chgVolLimit * 10; //充电电压限制,上位机配置,默认值57.6V if(chg_forbidFlg == 1) { SMKMem.chgCurLimit = 0; //SMK禁充 } else if(chg_curlimitFlg == 1) { SMKMem.chgCurLimit = Inv_curlimit * (OnlineNum-chg_cur0Num); //限流40A*未保护个数 } else { SMKMem.chgCurLimit = (bmsMem.inverter_chgCurLimit * 10) * (OnlineNum-chg_curLimitNum); //充电电流限制,上位机配置,默认值100A } if(dsg_forbidFlg == 1) { SMKMem.dcsCurLimit = 0; //SMK禁放 } else { SMKMem.dcsCurLimit = (bmsMem.inverter_dsgCurLimit * 10) * (OnlineNum-chg_curLimitNum); //放电电流限制,上位机配置,默认值100A } } //SAKO 三科 void MOD_Protocol_SAKO(void) { MOD_Protocol_Voltronic(); } //SNADI 佛山斯奈特 void MOD_Protocol_SNADI(void) { } //invt 英威腾 void MOD_Protocol_invt(void) { }