用周立功CAN分析仪抓包解析电动汽车充电握手报文(BMS/充电机通信实战)
电动汽车充电握手报文解析实战:从CAN抓包到BMS通信全解密
电动汽车充电过程中,BMS(电池管理系统)与充电机之间的通信就像两个陌生人在初次见面时的握手——需要确认身份、交换基本信息,并达成充电协议。而这一切,都通过CAN总线上的数据报文完成。本文将带你用周立功CAN分析仪(或类似工具)亲自动手抓取并解析这些关键报文,揭开充电握手过程的神秘面纱。
1. 环境搭建与工具准备
工欲善其事,必先利其器。在开始抓包前,我们需要确保硬件连接正确,软件配置到位。不同于简单的OBD-II诊断,电动汽车充电通信对CAN总线的配置有特定要求。
1.1 硬件连接要点
- CAN分析仪选择:周立功CAN分析仪(如USBCAN-II)是常见选择,其他兼容设备如PCAN、Kvaser等同样适用
- 接口定义:充电通信通常使用CAN2.0B(扩展帧),波特率多为250kbps或500kbps
- 物理连接:
- 充电枪CC/CP信号触发通信启动
- CAN_H和CAN_L需正确接入车辆接口(注意与动力CAN区分)
- 推荐使用隔离型CAN接口避免地环路干扰
注意:不同车型的CAN接口位置可能差异较大,比亚迪、特斯拉等品牌的充电通信接口定义需参考具体车型技术文档
1.2 软件配置关键参数
以周立功CANTest软件为例,基本配置步骤如下:
# 典型配置代码示例(伪代码) can = CANAnalyzer() can.set_mode('normal') # 非监听模式 can.set_baudrate(250000) # 250kbps can.set_filter( id_range=(0x1800F456, 0x18FFF456), # 典型充电通信ID范围 extended=True # 扩展帧 ) can.start_capture()常见配置误区:
- 波特率不匹配(充电通信通常不是常见的500kbps)
- 未正确设置扩展帧过滤
- 忽略时间戳记录(报文时序分析至关重要)
2. 充电握手流程深度解析
电动汽车充电握手不是简单的"一问一答",而是包含多个阶段的精密对话。根据GB/T 27930标准,完整流程包括握手辨识、参数配置、充电阶段和结束阶段。我们重点关注前两个阶段的报文交互。
2.1 握手辨识阶段:CHM与BHM报文
当充电枪插入车辆接口后,充电机首先发送CHM(充电机握手报文),这相当于充电机说:"你好,我是充电桩,版本是XX"。典型CHM报文结构如下:
| 字节偏移 | 字段说明 | 示例值 | 解析 |
|---|---|---|---|
| 0 | 协议小版本号 | 0x01 | V1.x |
| 1-2 | 协议大版本号 | 0x0001 | 小端存储,实际为0x0100 |
| 3-7 | 保留字段 | 全0 | 必须为0 |
BMS收到CHM后回应BHM(车辆握手报文),携带车辆最高允许充电电压等关键参数:
// BHM报文数据结构示例 #pragma pack(1) typedef struct { uint16_t max_charge_voltage; // 单位0.1V,小端序 uint8_t reserved[6]; // 保留字段 } BHM_Message;实战技巧:
- 使用Wireshark的CAN插件可以自定义解析模板
- 电压值需注意单位换算(通常为0.1V/bit)
- 版本号字段的小端存储特性容易误读
2.2 参数配置阶段:CRM与BRM报文
握手确认后进入更复杂的参数交换阶段。充电机发送CRM(充电机辨识报文),其中SPN2560字段尤为关键:
| SPN2560值 | 含义 | 后续动作 |
|---|---|---|
| 0x00 | 初始辨识 | 等待BMS回复BRM |
| 0xAA | 确认辨识 | 进入充电准备 |
BMS回复的**BRM(车辆辨识报文)**通常超过8字节,需要多包传输协议(TP协议)。这是最容易出问题的环节,解析时需要特别注意:
- RTS/CTS握手:BMS先发RTS(请求发送),充电机回复CTS(清除发送)
- 数据分片:遵循连续编号(1-7),每帧首字节为分片序号
- 校验确认:最终以EOF或EOM帧结束
典型BRM数据结构:
# BRM多包传输示例 packets = [ b'\x01\x01\x00\x01\x03\x20\x0e\x42', # 包1:版本号+电池类型+容量+电压 b'\x02\xff\xff\xff\xff\xff\xff\xff', # 包2:电池信息 b'\x03\xff\xff\xff\xff\xff\xff\xff', # 包3:VIN码部分 # ...更多数据包 ]3. 常见问题排查与实战技巧
即使按照标准流程操作,实际抓包过程中仍会遇到各种意外情况。以下是几个典型问题及解决方案:
3.1 报文顺序错乱
由于CAN总线特性,抓包工具可能无法完全保持原始时序。建议:
- 启用硬件时间戳功能
- 按ID和DLC字段二次排序
- 特别注意TP协议中的流控帧顺序
诊断命令示例:
# 使用can-utils工具排序 candump -t a can0 | sort -k 1.10,1.163.2 多包传输解析
当遇到分片报文时,可按以下步骤重组:
- 识别TP协议控制帧(0x10/0x11/0x13)
- 提取总数据长度和分片数
- 按序号拼接数据部分
- 验证校验和(如有)
重组算法伪代码:
def reassemble_tp(packets): first_frame = packets[0] total_length = first_frame[1] chunks = [None] * first_frame[3] # 初始化分片数组 for p in packets[1:]: if p[0] & 0xF0 == 0x00: # 数据帧 chunk_num = p[0] & 0x0F chunks[chunk_num-1] = p[1:] return b''.join(filter(None, chunks))3.3 特殊ID处理
某些车型会使用私有PGN进行预通信,例如:
- 0x61开头的ID可能是BMS状态预告文
- 0x7E4/0x7EC常用于UDS诊断覆盖
- 充电准备阶段的0x108报文可能携带充电桩能力信息
重要提示:遇到未在标准中定义的ID时,建议先记录原始数据,再结合充电状态机分析其作用
4. 数据解析高级技巧
原始十六进制数据到有意义信息的转换需要综合运用多种技术。下面介绍几个提升解析效率的方法。
4.1 自动化解析脚本
使用Python-can库可以快速构建解析工具:
import can from can.interface import Bus bus = Bus(interface='seeedstudio', channel='COM3', bitrate=250000) for msg in bus: if msg.arbitration_id == 0x1826F456: # CHM ID version = f"V{msg.data[1]}.{msg.data[0]}" print(f"充电机协议版本: {version}") elif msg.arbitration_id == 0x182756F4: # BHM ID voltage = int.from_bytes(msg.data[0:2], 'little') / 10 print(f"车辆最高充电电压: {voltage}V")4.2 信号数据库应用
创建DBC文件可以标准化解析规则:
BO_ 2560 CRM: 8 Charger SG_ SPN2560 : 0|8@1+ (1,0) [0|255] "" Vector__XXX SG_ ChargerID : 8|32@1+ (1,0) [0|4294967295] "" Vector__XXX SG_ AreaCode : 40|24@1+ (1,0) [0|16777215] "" Vector__XXX BO_ 2561 BRM: 64 BMS SG_ ProtocolVersion : 0|24@1+ (0.01,0) [0|16777215] "" Vector__XXX SG_ BatteryType : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ Capacity : 32|16@1+ (0.1,0) [0|65535] "Ah" Vector__XXX4.3 可视化分析技术
结合PyQtGraph或Matplotlib实现数据可视化:
import matplotlib.pyplot as plt voltage_readings = [...] # 从BHM报文提取的数据 current_readings = [...] # 从BCP报文提取的数据 plt.figure(figsize=(10,4)) plt.plot(voltage_readings, label='电压(V)') plt.plot(current_readings, label='电流(A)') plt.title('充电参数趋势图') plt.legend() plt.grid(True) plt.show()5. 安全规范与最佳实践
在进行充电通信分析时,安全永远是第一考虑因素。以下是必须遵守的防护措施:
硬件层面:
- 使用隔离型CAN接口卡
- 在CAN线上串联120Ω终端电阻
- 避免带电插拔连接器
软件层面:
- 禁止发送未经确认的写指令
- 监控总线负载率(建议<30%)
- 实现异常报文过滤机制
操作流程:
- 先连接好所有线缆再上电
- 开始记录后再插入充电枪
- 完整记录整个充电会话
- 保存原始数据时包含时间戳
在最近的一个实际项目中,我们发现某车型的BMS会在充电结束前发送特殊的0x7F报文,如果不正确处理会导致充电桩异常终止。这种边缘情况正是需要实际抓包才能发现的宝贵经验。
