BMS 与充电桩通信协议:GB/T 27930 解析
直流快充(DC Fast Charging)能否顺利完成,取决于车辆 BMS 与充电桩之间那套”握手—参数配置—充电—结束”的完整交互流程。而主导这段交互的语言,正是国家标准 GB/T 27930-2015《电动汽车非车载传导式充电机与电池管理系统之间的通信协议》。本文从协议框架、报文格式、充电时序、核心参数与典型故障入手,系统拆解 BMS 在直流充电链路中的角色与实现要点,并附上解析代码与联调避坑清单。
1. 引言
交流慢充(AC)本质上是由车载充电机(OBC)完成整流与充电控制,充电桩只负责提供交流电源与基本的 PWM 占空比信号。而直流快充则完全不同:充电桩本身就是一台大功率整流/DC-DC 电源,直接向动力电池输出直流电。这就带来一个核心问题——充电桩并不了解电池的状态(SOC、允许电压、允许电流、温度等),而电池的允许充放电边界又直接决定桩该怎么输出。
解决这一矛盾的方式,就是让 BMS 成为直流充电过程的主导者:BMS 实时监测电池状态、计算允许充电参数(需求电流/电压),并把这些参数通过 CAN 总线发送给充电桩;充电桩作为”执行者”,严格按照 BMS 给定的参数输出。这套对话的语言规范,就是 GB/T 27930。
一句话定位:GB/T 27930 是”非车载充电机 ↔ BMS”之间的应用层 CAN 通信协议,与定义物理/链路层的 SAE J1939 一脉相承,是直流快充互操作的基石。
2. 协议框架与物理连接
2.1 物理层与链路层
GB/T 27930 建立在 CAN 2.0B(扩展帧)之上,主要参数如下:
| 参数 | 取值 |
|---|---|
| 波特率 | 250 kbit/s(默认) |
| 报文格式 | CAN 扩展帧(29-bit ID) |
| 数据长度 | 8 字节 |
| 传输层 | 遵循 ISO 15765-2 / SAE J1939-21 的多帧传输(TP) |
| 网络层 | PG(Parameter Group)参数组模型 |
在充电模式中,车辆端与充电桩端通过充电插座中的 CAN 通信引脚(CC2/CP 之外的通信线对 CAN_H/CAN_L)建立连接,通常采用 250kbps。这一波特率是充电桩与 BMS 双方约定好的,多数桩端已固化。
2.2 参数组(PGN)与报文集合
GB/T 27930 定义了一组固定 PGN 的报文,按功能可分为四大阶段。核心报文概览如下:
| PGN | 名称 | 方向 | 周期 | 说明 |
|---|---|---|---|---|
| 0x000001F4 (BCL) | 电池充电需求 | BMS→桩 | 50ms | 需求电压/电流、充电模式 |
| 0x0000020C (BCS) | 电池充电总状态 | BMS→桩 | 250ms | 电压/电流/SOC/剩余时间 |
| 0x0000023A (CCS) | 充电机充电状态 | 桩→BMS | 50ms | 桩输出电压/电流、累计时间 |
| 0x00000241 (CRM) | 充电机辨识 | 桩→BMS | 250ms | 桩编号、区域 |
| 0x00000248 (BRM) | BMS 辨识 | BMS→桩 | 250ms | 电池类型、容量、电压上限 |
| 0x0000024C (BST) | BMS 时间同步 | BMS→桩 | 500ms | 对时 |
| 0x00000251 (CST) | 充电机时间同步 | 桩→BMS | 500ms | 对时 |
| 0x00000252 (CPT) | 充电结束报文 | BMS→桩 | 事件 | 结束原因 |
| 0x00000253 (CST/CPT) | 充电机结束/统计 | 桩→BMS | 事件 | 统计信息 |
| 0x0000026B (BEM) | BMS 错误报文 | BMS→桩 | 事件 | 故障码 |
| 0x0000026C (CEM) | 充电机错误报文 | 桩→BMS | 事件 | 故障码 |
注意:以上 PGN 与报文名称(如 BCL、BCS、CCS、CRM、BRM、BEM、CEM 等)为 GB/T 27930 及行业通用的缩写,工程实现时应以标准原文的分组与信号定义为准,避免仅凭经验值硬编码。
3. 充电全流程时序(握手 → 结束)
直流充电流程可划分为四个阶段,每个阶段都伴随严格的超时与握手确认。整体时序如下:
车辆插入充电枪
│
▼
[1] 握手阶段 (Handshake)
CCS(0x23A) ── 充电机辨识 ──────────────────▶
CRM(0x241) ◀── 充电机型号/编号 ────────────
BRM(0x248) ── BMS 辨识 ───────────────────▶
│ 双方确认,进入参数配置
▼
[2] 参数配置阶段 (Parameter Configuration)
BCL(0x1F4) ── 电池充电需求 ───────────────▶
BCP(0x100/标准定义) ◀── 充电机能力 ───────
BSM(0x2xxxxxxxx) ── 电池状态/就绪 ───────▶
│ 校验电压等级、就绪标志
▼
[3] 充电阶段 (Charging)
BCL(0x1F4) ── 实时需求电压/电流 ── 50ms ─▶
BCS(0x20C) ── 电压/电流/SOC ── 250ms ────▶
CCS(0x23A) ◀── 桩输出状态 ── 50ms ───────
│ 循环监测,直到充电结束或异常
▼
[4] 充电结束阶段 (End)
BST/CST(0x251) ── 结束报文 ───────────────▶
│ 断开接触器,断开充电枪
▼
充电完成
3.1 握手阶段的关键细节
- CRM(充电机辨识):充电桩在上电后周期性发送,包含充电机编号与所在区域编码,用于桩端身份识别与后台计费关联。
- BRM(BMS 辨识):BMS 回复自身识别信息,包含电池类型(磷酸铁锂/三元等编码)、额定容量、厂商代码、最高允许充电电压等。
- 超时控制:若在规定的握手时间内(典型 5s~10s,依车辆策略)未收到对方的辨识报文,则判定握手失败,进入充电结束流程并上报”通信超时”故障。
握手阶段一旦通过,BMS 与桩就完成了”身份互认”与”参数对齐”,这是后续所有动作的前提。
3.2 参数配置与充电阶段
- BCL(电池充电需求) 是整个协议中最重要的报文,BMS 每 50ms 发送一次,内容包含:
- 需求电压(Target Voltage,即当前允许的最高充电电压)
- 需求电流(Target Current,允许的最大充电电流)
- 充电模式(恒压/恒流等)
- CCS(充电机充电状态) 由桩端每 50ms 回报,包含桩实际输出电压、输出电流以及累计充电时间,BMS 据此判断桩是否”听话”、是否需要纠偏。
充电过程中,BMS 的核心职责是一个实时闭环:
- 采样单体电压、温度、母线电流,估算 SOC;
- 结合 SOC、温度、当前寿命(SOH)计算允许充电电流上限;
- 把需求电压/电流写入 BCL,周期性下发;
- 对比桩回报的实际输出与需求值,偏差过大则触发故障或降额。
4. 核心报文信号解析(BCL 示例)
以最核心的 BCL(电池充电需求,PGN 0x000001F4) 为例,展示其 8 字节数据场的布局(示意,实际以标准为准):
| 字节 | 信号 | 分辨率/偏移 | 说明 |
|---|---|---|---|
| 1-2 | 需求电压 (V) | 0.1 V/bit,偏移 0 | BMS 要求的充电输出电压 |
| 3-4 | 需求电流 (A) | 0.1 A/bit,偏移 -400 | BMS 允许的最大充电电流 |
| 5 | 充电模式 | —— | 0x01 恒压 / 0x02 恒流 等 |
| 6 | 预留/就绪标志 | —— | 状态位 |
| 7-8 | 预留 | —— | —— |
需求电流的偏移量(offset)是常见坑点:为兼容放电与充电,电流信号常采用负偏移编码。解析时若忽略 offset,会出现”充电电流偏大 400A”的离谱结果。
4.1 BCL 解析代码示例
下面给出一个基于 Python 的 BCL 报文解析函数,模拟从 CAN 数据帧还原需求电压/电流的过程:
# bcl_parser.py —— GB/T 27930 BCL 报文解析示例
import struct
def parse_bcl(data: bytes):
"""解析 BCL (PGN 0x000001F4) 报文
data: 8 字节 CAN 数据场
返回 dict: {'target_voltage': float, 'target_current': float, 'mode': int}
"""
assert len(data) == 8, "BCL 数据场必须为 8 字节"
# 字节 0-1: 需求电压, 0.1 V/bit, 无符号
vol_raw = (data[1] << 8) | data[0]
target_voltage = vol_raw * 0.1
# 字节 2-3: 需求电流, 0.1 A/bit, 偏移 -400 (有符号物理量)
cur_raw = (data[3] << 8) | data[2]
cur_signed = cur_raw if cur_raw < 0x8000 else cur_raw - 0x10000
target_current = cur_signed * 0.1 - 400.0
# 字节 4: 充电模式
mode = data[4]
return {
"target_voltage": round(target_voltage, 1),
"target_current": round(target_current, 1),
"mode": mode,
}
if __name__ == "__main__":
# 示例: 需求电压 400.0V, 需求电流 120.0A, 恒压模式
# 电压原始值 = 4000 → 0x0FA0; 电流原始值 = (120+400)*10 = 5200 → 0x1450
sample = bytes([0xA0, 0x0F, 0x50, 0x14, 0x01, 0x00, 0x00, 0x00])
print(parse_bcl(sample))
# 输出: {'target_voltage': 400.0, 'target_current': 120.0, 'mode': 1}
实际工程中,CAN 帧往往经由 Vector/cando 等工具采集,再结合 DBC 文件(CAN 数据库)做信号级解析,上面的”手工拼字节”仅用于理解编码原理。
5. 故障处理与结束报文
5.1 错误报文(BEM / CEM)
当检测到异常时,BMS 通过 BEM(BMS 错误报文)、充电桩通过 CEM(充电机错误报文) 上报故障。常见故障码包括:
| 故障类别 | 典型触发条件 | 处理 |
|---|---|---|
| 过温 | 单体/系统温度超阈值 | 降额或停止充电 |
| 过压/欠压 | 单体电压越界 | 立即停止充电 |
| 绝缘故障 | 绝缘电阻低于限值 | 断开接触器,禁止充电(见上一篇文章) |
| 通信超时 | 规定周期内未收到对方报文 | 判定通信中断,进入结束流程 |
| SOC 满/不平衡 | 达到截止条件 | 正常结束充电 |
5.2 充电结束报文(CPT / 桩端统计)
充电结束后,BMS 发送 CPT(充电结束报文),携带终止原因(正常充满/故障/手动停止/通信中断等);充电桩回复统计报文,包含本次充电的累计电量、累计时间、最大电压/电流,供后台计费与数据归档。
结束流程的规范执行至关重要:如果 BMS 直接断开接触器而不发送结束报文,充电桩可能判定为”异常离线”,产生误计费或不完整的充电记录。
6. 联调实战避坑清单
基于工程实践,直流充电联调中最容易踩的坑总结如下:
- 波特率不匹配:车辆端与桩端 CAN 波特率不一致是”握手都过不了”的头号原因,务必确认 250kbps。
- 电流偏移忽略:解析 BCL 需求电流时忘记 -400A 偏移,导致电流值异常,桩输出与需求严重不符。
- 周期不满足:BCL 若发送周期远超 50ms,桩端可能判定 BMS 离线而中断充电;同理桩端 CCS 的 50ms 周期也需保证。
- 多帧传输(TP)处理:部分辨识报文超过 8 字节,需正确实现 ISO 15765-2 多帧传输,否则数据被截断导致辨识失败。
- 结束报文缺失:BMS 直接断接触器会诱发桩端异常离线,务必先发结束报文再断开。
- 电压等级校验:握手阶段 BMS 上报的最高允许电压与桩的输出能力不匹配时,应在参数配置阶段就中止,而非到充电阶段才发现。
- 绝缘故障联动:充电场景下的绝缘故障必须优先切断充电接触器并禁止后续快充(与绝缘检测策略闭环,参见本专栏相关文章)。
7. BMS 工程师的落地建议
- 优先用 DBC 化管理:把 GB/T 27930 的报文与信号固化为 DBC 文件,既便于信号级解析,也便于与桩端、第三方测试工具对齐。
- 建立协议状态机:将握手、参数配置、充电、结束四阶段建模为清晰的状态机,超时、故障、结束条件统一在状态机内处理,避免散落在代码各处。
- 做好容错与降额:通信异常时不应”一刀切”停机,可先降额运行、超时后再安全停止,兼顾可用性与安全性。
- 完整记录充电数据:把 BCL/BCS/CCS 全过程的电压、电流、SOC、温度记录下来,既便于故障定位,也是售后与电池质保的重要依据。
- 对齐最新版本:GB/T 27930 会随行业发展修订,务必关注其与 Chademo、CCS(Combined Charging System)等国际协议在互操作与安全策略上的演进,确保产品兼容性。
8. 结语
GB/T 27930 看似只是一套 CAN 报文协议,实则是直流快充安全与互操作的”宪法”。BMS 在其中扮演的不是被动的”被充电者”,而是整个充电过程的主导者——它决定”能不能充、充多快、何时停”。
掌握这套协议的框架、时序与信号解析,是 BMS 工程师打通”车—桩—网”充电链路的关键能力。随着大功率快充、超充(如 800V 平台 + 液冷超充桩)的普及,协议的高频实时性、故障快速响应与跨协议互操作将变得更加重要,值得每一位从业者深入研读并持续跟踪标准演进。
发表回复