Files
2026-08-25 17:30:40 +08:00

2941 lines
62 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @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 currentSC, 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 currentSC, 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 currentSC, 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 currentSC, 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 currentSC, 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 currentSC, 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 currentSC, 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 currentSC, 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 currentSC, 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 currentSC, 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)
{
}