锂电池改用 BCU-MBMS CAN 协议按节点解析 + bcu_node 解析数据落库 + 板卡对时脚本
- pCCU/CanBms:按《04KT38电池BCU-MBMS通信(CAN)定义》重写解码, BmsStatus 单状态模型改为 BcuNodeStatus 多节点模型(0x10XX00YY, 节点地址 01~36h),支持 0x0000 电压/电流/SOC/告警码、0x0001 单体 电压、0x0002 单体温度、0x0003 继电器、0x0006 绝缘/端口电压、 0x0010 告警位(附录1 中文码表)六类报文 - 平均单体温度偏移修正:协议文档 BYTE5 写"偏移0"有误,实测固件与 最高/最低一致均带 -40℃ 偏移(实车 0x10020002 原始 68/69 减 40 后 为 28/29℃,落在最低28~最高30区间内,按文档直读则超出物理范围) - pCCU/DbStore:新增 bcu_node 解析数据表,锂电池 BMS 报文每帧落一行 节点合成状态(原 comm_log 仅原始帧,BMS/CAN 帧此前不落 pCCU 库), buildReport 增加 BMS 记录数 - 快照/网页:BCU 按节点分组展示(告警位解析中文含义、数据 age), PM 状态报文锂电池/应急电池卡片 - pPowerManger:新增 iport 本地输入端口配置(UDP bind 延迟到 OnStartUp 读取配置后执行,保证 iport/ccuhost/ccuport 生效), 各 mission 文件补充注释 - test:CAN BCU 解码用例按新协议/新偏移更新(实车抓包 + 文档示例值), 133 项全部通过 - docs:删除旧 BMS 协议(xlsx/20230324docx),归档 04KT38 BCU-MBMS CAN 定义、配电控制器通信协议 20260824、配电系统 CAN 通讯协议 - scripts:新增 sync-board-time.sh,223 板卡(RK3588)时间校正 (本机为基准 + RTT 折半补偿对时,尽力写 RTC,支持 status/--time)
This commit is contained in:
+124
-41
@@ -6,58 +6,141 @@
|
||||
namespace ccu {
|
||||
|
||||
//============================================================================
|
||||
// CAN BMS 协议(锂电池 BMS 报文,经 USBCAN-8E-U/CANET 上 CAN 总线)
|
||||
// 依据:docs/BMS_协议字段定义.xlsx
|
||||
// 锂电池 BCU-MBMS CAN 协议(docs/04KT38电池BCU-MBMS通信(CAN)定义.docx)
|
||||
//
|
||||
// 数据来源:pCanBridge 透传的 MOOS 消息
|
||||
// 变量名 CAN_0x%08X = CAN ID(扩展帧),m_sVal = 二进制数据域,
|
||||
// m_dfVal2 = 原始帧信息字节。本模块只负责按报文 ID 解析数据域字段。
|
||||
//
|
||||
// 报文(均为扩展帧,字段大端,起始字节相对 8 字节数据域):
|
||||
// 0x10010000 总电压 u16@0 ÷10 V
|
||||
// SOC u16@4 ÷10 %
|
||||
// 故障码 u8 @6 ×1
|
||||
// 状态位 u8 @7 ×1
|
||||
// 0x10010005 最大电流限制 u16@0 ÷10 A
|
||||
// 总电流 s16@2 ÷10 A(补码,放电为正;xlsx 表标注
|
||||
// 3 字节与其示例/实测冲突,按 2 字节实现,
|
||||
// 详见 CanBms.cpp 注释)
|
||||
// 最高单体电压 u16@4 ÷1000 V
|
||||
// 0x10010006 总电压(校验) u16@4 ÷10 V
|
||||
// 【节点地址】一个 MBMS 下最多挂 54 个 BCU,CAN ID 中间的 XX(01h~36h)
|
||||
// 为 BCU 节点地址编号,其余位固定:
|
||||
// 0x10XX00YY BCU 主动上报消息(YY=功能码 00/01/02/03/06/10)
|
||||
// 0x10XX81FF MBMS 下发指令(继电器控制,pCCU 只收不发,不解析)
|
||||
//
|
||||
// 【上报报文】均为扩展帧,字段大端,BYTE1~8 对应数据域 byte0~7:
|
||||
// 0x10XX0000 (200ms) 累加电压 u16@0 ÷10 V
|
||||
// 回路电流 s16@2 ÷10-600 A(偏移 -600A,放电为正)
|
||||
// SOC u16@4 ÷10 %
|
||||
// 告警码 u8 @6(循环上报,协议未附码表,原样显示)
|
||||
// 自检状态 u8 @7
|
||||
// 0x10XX0001 (200ms) 最高单体电压 u16@0 mV,编号 u8@2
|
||||
// 最低单体电压 u16@3 mV,编号 u8@5
|
||||
// 单体平均电压 u16@6 mV
|
||||
// 0x10XX0002 (1000ms) 最高单体温度 s8@0(偏移 -40℃),编号 u8@1
|
||||
// 最低单体温度 s8@2(偏移 -40℃),编号 u8@3
|
||||
// 单体平均温度 s8@4(偏移 -40℃,协议文档写"偏移0"
|
||||
// 有误:实测原始值减 40 后才落在最低~最高区间内)
|
||||
// 0x10XX0003 (200ms) 正极继电器状态 u8@0(1 闭合 / 0 断开)
|
||||
// 负极继电器状态 u8@1(1 闭合 / 0 断开)
|
||||
// 0x10XX0006 (200ms) 正极绝缘阻抗 u16@0 kΩ
|
||||
// 负极绝缘阻抗 u16@2 kΩ
|
||||
// 正负极端口电压 u16@4 ÷10 V
|
||||
// 正极继电器外侧电压 u16@6 ÷10 V
|
||||
// 0x10XX0010 (200ms) byte0~5 告警位(bit 定义见附录1,
|
||||
// kBcuAlarmTable,可经 bcuAlarmTexts() 取告警描述)
|
||||
// 0x10XX0004/0005 Reserve(调试预留,不解析)
|
||||
//============================================================================
|
||||
|
||||
// BMS 报文 ID(扩展帧 CAN ID)
|
||||
enum CanBmsId : uint32_t {
|
||||
CAN_BMS_ID_STATUS = 0x10010000, // 总电压 / SOC / 故障码 / 状态位
|
||||
CAN_BMS_ID_CURRENT = 0x10010005, // 最大电流限制 / 总电流 / 最高单体电压
|
||||
CAN_BMS_ID_VOLT_CHK = 0x10010006, // 总电压(校验)
|
||||
// BCU 节点地址范围:01h~36h(1~54)
|
||||
static const int kBcuAddrMin = 0x01;
|
||||
static const int kBcuAddrMax = 0x36;
|
||||
static const int kBcuNodeCount = kBcuAddrMax - kBcuAddrMin + 1;
|
||||
|
||||
// BCU 上报报文功能码(CAN ID 低字节 YY)
|
||||
enum BcuFunc : uint8_t {
|
||||
BCU_FUNC_BASE = 0x00, // 0x10XX0000 电压 / 电流 / SOC / 告警码 / 自检
|
||||
BCU_FUNC_CELL_V = 0x01, // 0x10XX0001 单体电压
|
||||
BCU_FUNC_CELL_T = 0x02, // 0x10XX0002 单体温度
|
||||
BCU_FUNC_RELAY = 0x03, // 0x10XX0003 继电器状态
|
||||
BCU_FUNC_ISU = 0x06, // 0x10XX0006 绝缘阻值 / 端口电压
|
||||
BCU_FUNC_ALARM = 0x10, // 0x10XX0010 告警位(附录1)
|
||||
};
|
||||
|
||||
// BMS 最新状态(各报文字段按 ID 部分更新,最终合成完整快照)
|
||||
struct BmsStatusValue {
|
||||
double totalVoltage = 0; // 总电压 V(0x10010000)
|
||||
double soc = 0; // SOC %(0x10010000)
|
||||
int faultCode = 0; // 故障码(0x10010000 @6)
|
||||
int statusBits = 0; // 状态位(0x10010000 @7)
|
||||
double maxCurrentLimit = 0; // 最大电流限制 A(0x10010005)
|
||||
double totalCurrent = 0; // 总电流 A,放电为正(0x10010005,s24 补码)
|
||||
double maxCellVoltage = 0; // 最高单体电压 V(0x10010005)
|
||||
double totalVoltageChk = 0; // 总电压校验 V(0x10010006)
|
||||
double lastRxTime = 0; // 最近收到任一 BMS 报文的时刻(MOOSTime)
|
||||
bool valid = false; // 是否收到过 BMS 报文
|
||||
};
|
||||
|
||||
// 解析一帧 CAN 数据域;命中 BMS 报文 ID 返回 true 并把字段合并进 v
|
||||
// (部分更新语义:每个 ID 只更新自己的字段)。
|
||||
// data 为数据域首指针(有效长度 dlc 字节),data/dlc 非法或非 BMS ID 返回 false。
|
||||
bool decodeCanBmsFrame(uint32_t canId, const uint8_t* data, int dlc, BmsStatusValue& v);
|
||||
|
||||
// 是否为 BMS 报文 ID
|
||||
inline bool isCanBmsId(uint32_t canId) {
|
||||
return canId == CAN_BMS_ID_STATUS || canId == CAN_BMS_ID_CURRENT ||
|
||||
canId == CAN_BMS_ID_VOLT_CHK;
|
||||
// 从 CAN ID 提取 BCU 节点地址(0x10XX00YY -> XX);非 BCU 报文格式返回 0
|
||||
inline uint8_t bcuAddrOf(uint32_t canId) {
|
||||
if ((canId & 0xFF00FF00u) != 0x10000000u) return 0;
|
||||
uint8_t addr = static_cast<uint8_t>((canId >> 16) & 0xFF);
|
||||
return (addr >= kBcuAddrMin && addr <= kBcuAddrMax) ? addr : 0;
|
||||
}
|
||||
|
||||
// 从 CAN ID 提取功能码(0x10XX00YY -> YY)
|
||||
inline uint8_t bcuFuncOf(uint32_t canId) {
|
||||
return static_cast<uint8_t>(canId & 0xFF);
|
||||
}
|
||||
|
||||
// 是否为 BCU 主动上报报文 ID(0x10XX00YY,YY 为已定义功能码)
|
||||
inline bool isCanBcuId(uint32_t canId) {
|
||||
uint8_t addr = bcuAddrOf(canId);
|
||||
if (!addr) return false;
|
||||
switch (bcuFuncOf(canId)) {
|
||||
case BCU_FUNC_BASE:
|
||||
case BCU_FUNC_CELL_V:
|
||||
case BCU_FUNC_CELL_T:
|
||||
case BCU_FUNC_RELAY:
|
||||
case BCU_FUNC_ISU:
|
||||
case BCU_FUNC_ALARM:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 单个 BCU 节点最新状态(各报文字段按功能码部分更新,最终合成完整快照)
|
||||
struct BcuNodeStatus {
|
||||
// 0x10XX0000 基本信息
|
||||
double totalVoltage = 0; // 累加电压 V
|
||||
double current = 0; // 回路电流 A(放电为正,偏移 -600A 已折算)
|
||||
double soc = 0; // SOC %
|
||||
int alarmCode = 0; // 告警码(原始值,协议未附码表)
|
||||
int selfCheck = 0; // 自检状态(原始值)
|
||||
// 0x10XX0001 单体电压
|
||||
double maxCellVoltage = 0; // 最高单体电压 V
|
||||
int maxCellVoltageNo = 0; // 最高单体电压编号
|
||||
double minCellVoltage = 0; // 最低单体电压 V
|
||||
int minCellVoltageNo = 0; // 最低单体电压编号
|
||||
double avgCellVoltage = 0; // 单体平均电压 V
|
||||
// 0x10XX0002 单体温度
|
||||
double maxCellTemp = 0; // 最高单体温度 ℃
|
||||
int maxCellTempNo = 0; // 最高单体温度编号
|
||||
double minCellTemp = 0; // 最低单体温度 ℃
|
||||
int minCellTempNo = 0; // 最低单体温度编号
|
||||
double avgCellTemp = 0; // 单体平均温度 ℃
|
||||
// 0x10XX0003 继电器(1 闭合 / 0 断开)
|
||||
int posRelay = 0;
|
||||
int negRelay = 0;
|
||||
// 0x10XX0006 绝缘 / 端口电压
|
||||
double posInsulationKohm = 0; // 正极绝缘阻抗 kΩ
|
||||
double negInsulationKohm = 0; // 负极绝缘阻抗 kΩ
|
||||
double portVoltage = 0; // 正负极端口电压 V
|
||||
double posRelayOuterVoltage = 0; // 正极继电器外侧电压 V
|
||||
// 0x10XX0010 告警位(附录1,byte0~5)
|
||||
uint8_t alarmBits[6] = {0, 0, 0, 0, 0, 0};
|
||||
// 0x10XX0010 附加字节(协议未详列,原样保留)
|
||||
int alarmExtraByte6 = 0;
|
||||
int alarmExtraByte7 = 0;
|
||||
|
||||
// 元数据
|
||||
uint32_t rxMask = 0; // 收到过的功能码位图(bit = BcuFunc)
|
||||
double lastRxTime = 0; // 最近收到该节点任一报文的时刻(MOOSTime)
|
||||
bool valid = false; // 是否收到过该节点报文
|
||||
};
|
||||
|
||||
// 解析一帧 CAN 数据域;命中 BCU 上报报文返回 true,nodeAddr 为节点地址(1~54),
|
||||
// 字段按功能码部分更新合并进 node。data/dlc 非法或非 BCU 报文返回 false。
|
||||
bool decodeCanBcuFrame(uint32_t canId, const uint8_t* data, int dlc,
|
||||
uint8_t& nodeAddr, BcuNodeStatus& node);
|
||||
|
||||
// 附录1:0x10XX0010 告警位定义表(byteIdx/bitIdx -> 告警描述),表尾以 byteIdx=0xFF 结束
|
||||
struct BcuAlarmDesc {
|
||||
uint8_t byteIdx;
|
||||
uint8_t bitIdx;
|
||||
const char* text;
|
||||
};
|
||||
extern const BcuAlarmDesc kBcuAlarmTable[];
|
||||
|
||||
// 收集节点当前置位的告警描述;返回条数(不超过 cap,texts 填描述指针)
|
||||
int bcuAlarmTexts(const BcuNodeStatus& node, const char* texts[], int cap);
|
||||
|
||||
} // namespace ccu
|
||||
|
||||
#endif // PCCU_CAN_BMS_H
|
||||
|
||||
Reference in New Issue
Block a user