3. CAN帧结构与储能报文解析

在储能站中,BMS、PCS、EMS、消防主机、空调控制器等设备通过CAN总线交换数据。要真正读懂一条储能报文,不能只停留在“ID是多少、数据是什么”,而必须理解CAN帧的字段结构,以及每个场在储能通信中的实际作用。CAN 2.0B定义了标准帧和扩展帧两种格式,二者最核心的区别在于仲裁场中的标识符长度:标准帧为11位ID,扩展帧为29位ID(11位基本ID + 18位扩展ID)。储能设备中,BMS与PCS之间常使用标准帧,因为设备数量有限、信号类型固定;而EMS汇聚多簇电池、多台PCS时,往往使用扩展帧,以便在ID中编码“设备类型 + 簇号 + 设备地址 + 信号类型”。

一条CAN数据帧从仲裁场开始,依次经过控制场、数据场、CRC场、ACK场,最后到帧结束。仲裁场决定谁先占用总线,也承载了报文的“身份”。在储能系统中,ID通常不是随机分配的,而是按通信协议表约定。例如某储能站协议规定:0x180表示BMS总电压电流,0x181表示BMS SOC/SOH,0x200表示PCS有功无功,0x300表示EMS调度指令。当多个节点同时发送时,ID数值越小,优先级越高。因此,涉及保护动作、故障告警的报文应分配更小的ID,确保在总线繁忙时优先发送。

CAN数据帧结构对比与储能报文映射 标准帧(11位ID) SOF 仲裁场 11位ID + RTR 控制场 IDE + DLC 数据场 0~8字节 CRC场 15位 + 界定符 ACK场 ACK + 界定符 扩展帧(29位ID) SOF 仲裁场 11位基本ID + SRR + IDE + 18位扩展ID + RTR 控制场 r1 + r0 + DLC 数据场 0~8字节 CRC场 15位 ACK场 ACK 储能报文映射示例 BMS → PCS 标准帧 ID: 0x180(11位) DLC: 8 Data[0-1]: 总电压 0.1V/bit Data[2-3]: 总电流 0.1A/bit EMS → 多簇BMS 扩展帧 ID: 0x18FF50E5(29位) DLC: 8 Data[0]: 簇号 Data[1-2]: 调度功率 0.1kW/bit PCS → EMS 状态帧 ID: 0x200(11位) DLC: 8 Data[0-1]: 有功功率 0.1kW/bit Data[2-3]: 无功功率 0.1kVar/bit 各场在储能通信中的实际含义 仲裁场 ID决定优先级与设备身份 控制场 DLC声明数据字节数 数据场 承载电压/电流/SOC等 CRC场 校验传输错误 ACK场 接收确认

控制场中的DLC(数据长度码)看似简单,却直接影响解析。DLC为4位,取值0~8,表示数据场实际字节数。储能协议中,BMS总电压电流通常用8字节,PCS功率指令用8字节,而某些告警帧可能只用2字节。如果DLC声明为8但实际只发了4字节,接收端会按8字节解析,导致后续字节被误读为其他信号。因此,在编写解析代码时,必须先读取DLC,再按DLC截取数据场,不能固定按8字节处理。

数据场是储能报文的核心载荷。以BMS上报总电压电流为例,假设协议规定:Data[0]和Data[1]组成16位无符号整数,表示总电压,分辨率0.1V,偏移量0;Data[2]和Data[3]组成16位有符号整数,表示总电流,分辨率0.1A,偏移量-3000A。若收到数据场为 0x0E 0x74 0x1F 0xA0 0x00 0x00 0x00 0x00,则总电压为 0x0E74 = 3700,乘以0.1V得370.0V;总电流为 0x1FA0 = 8096,按有符号数解释为8096,乘以0.1A得809.6A,再减偏移3000A,实际电流为-2190.4A,表示充电方向。这里必须注意字节序:CAN协议通常采用大端序(Motorola格式),即高字节在前。若协议规定小端序(Intel格式),则需先交换字节再计算。

CRC场用于检测传输错误。发送节点根据帧头到数据场的所有位计算15位CRC,接收节点重新计算并比对。若不一致,接收节点会在ACK场之后发送错误帧,通知总线上的所有节点丢弃该报文。在储能站中,CRC错误通常由线缆过长、终端电阻不匹配、电磁干扰或波特率偏差引起。例如,当CAN_H与CAN_L之间的终端电阻缺失或阻值偏离120Ω时,信号反射会导致CRC错误率上升。此时应检查总线两端是否各有一个120Ω电阻,并用示波器观察差分信号幅值是否在1.5V~3.0V之间。

ACK场是接收节点对发送节点的确认。发送节点在ACK槽发送隐性位,接收节点若正确接收,则发送显性位覆盖它。发送节点检测到显性位,就知道至少有一个节点正确接收。若发送节点在ACK槽检测到隐性位,说明没有节点接收成功,会触发ACK错误。在储能调试中,如果PCS一直收不到BMS报文,而BMS发送无ACK错误,则可能是PCS的CAN控制器未使能接收,或过滤器设置错误,把BMS的ID过滤掉了。此时应检查PCS的CAN接收过滤器配置,确认是否允许0x180通过。

远程帧(RTR=1)在储能系统中使用较少,但并非没有。某些EMS会发送远程帧请求BMS上报数据,BMS收到后回复对应数据帧。远程帧的仲裁场与数据帧相同,但RTR位为隐性,且没有数据场。DLC表示请求的数据长度。如果EMS发送ID为0x180的远程帧,BMS应回复ID为0x180的数据帧。但实际项目中,多数储能协议采用周期上报而非请求应答,因此远程帧更多出现在调试工具或特定厂商的私有协议中。

错误帧由检测到错误的节点主动发送,由错误标志和错误界定符组成。错误标志分为主动错误标志(6个显性位)和被动错误标志(6个隐性位)。节点处于主动错误状态时,发送主动错误标志,会破坏总线上的当前帧;处于被动错误状态时,发送被动错误标志,不影响总线。储能站中,若某个节点频繁进入被动错误状态,说明其错误计数器已超过127,应检查该节点的CAN收发器、供电和接地是否正常。错误计数器分为发送错误计数器(TEC)和接收错误计数器(REC),可通过CAN控制器的寄存器读取。当TEC或REC超过255时,节点进入总线关闭状态,必须重新初始化才能恢复通信。

在储能报文解析中,建议先建立一张“ID—信号—字节—分辨率—偏移量—单位”的协议映射表,再编写解析函数。每次收到报文,先校验DLC与协议是否一致,再按字节序提取原始值,最后套用分辨率与偏移量得到工程值。这样即使协议升级,也只需修改映射表,不必重写解析逻辑。

下面给出一个储能报文解析的参考映射表,用于BMS总电压电流和PCS功率指令的快速对照。表中参数为教学示例,实际项目应以设备协议文档为准。

报文ID 帧类型 信号名称 起始字节 长度 字节序 分辨率 偏移量 单位
0x180 标准帧 总电压 0 2 大端 0.1 0 V
0x180 标准帧 总电流 2 2 大端 0.1 -3000 A
0x181 标准帧 SOC 0 1 — 0.5 0 %
0x200 标准帧 有功功率 0 2 大端 0.1 -5000 kW
0x18FF50E5 扩展帧 调度功率 1 2 大端 0.1 -5000 kW

以0x200为例,若收到数据场 0x13 0x88 0x00 0x00 0x00 0x00 0x00 0x00,则原始值为 0x1388 = 5000,乘以0.1得500.0,再减偏移5000,实际有功功率为-4500.0kW,表示充电方向。若偏移量设置错误,比如误设为0,则会得到500.0kW,方向完全相反。因此,偏移量的正负和数值必须与协议严格一致。

最后需要强调,标准帧与扩展帧不能混用同一ID空间。标准帧的11位ID和扩展帧的29位ID在仲裁时,标准帧的IDE位为显性,扩展帧的IDE位为隐性。当标准帧和扩展帧同时竞争总线时,标准帧优先。因此,在储能站中,若BMS使用标准帧0x180,EMS使用扩展帧0x18FF50E5,二者不会冲突,但EMS的扩展帧优先级低于标准帧。若希望EMS调度指令优先于BMS周期上报,则应将EMS指令配置为标准帧,并分配更小的ID,如0x080。理解这些细节,才能在储能站CAN通信集成中正确设计报文优先级、解析数据和排查故障。