结论:SAM 项目车是一台 125 kbit/s、11 位标准帧的小型电动车,其 CAN 数据档案的价值不在「抓到多少」,而在「修正了多少」:源文档的 DBC 共 37 条消息、161 个信号,并对早期手工整理的布局逐条做了修正——多处把原本当成无符号的字段改正为有符号,还把两个电压刻度由「1」改为实测拟合值。源文档同时明确区分「该车的总线」与「另一台装原厂 BMS 的车」。以下所有结论仅限源文档记录的车辆。
车辆与适用范围
本文数据来自第三方开源项目对 SAM 项目车的 CAN 记录与 DBC 修正。项目用某类商业 CAN 记录仪采集 trace,并开发了一个查看器来浏览器与逐帧回放;DBC 的修正以注释形式叠加在文件内。
| 项 | 内容 |
|---|---|
| 车型 | 源文档以 SAM 指代的一台项目车;具体量产车型未确认 |
| 年款 / 市场版本 | 源文档未确认 |
| 电控与改装 | 车上装有自研仪表(STM32)与自研 BMS;源文档同时对照另一台仍装原厂 BMS 的车(在参考日志中的那台) |
| 采集跨度 | 两种记录格式(某类商业 CAN 记录工具导出的 `.trc` v2.0 文件,与 SAM 侧记录器导出的纯文本),覆盖行驶、充电与静置场景 |
| 适用范围 | 仅限源文档记录的这两台车;两车的 BMS 变体不同,报文与周期存在差异 |
总线与寻址
这是一条相对「干净」的台架总线:速率不高、ID 位宽是标准 11 位,车的电控又是自己开发的,因此信号的字节布局大体可从自身设计反推——但仍有多处需要靠实测数据才能定标。
| 项 | 内容 |
|---|---|
| 速率 / 帧格式 | 125 kbit/s;11 位标准帧 |
| DBC 规模 | 37 条消息(`BO_`)、161 个信号(`SG_`) |
| 修正方式 | 修正以 `CM_` 注释形式叠加在 DBC 内,逐条标注依据与是否已确认 |
| 多路复用 | 存在被多路复用的消息(如充电机信息与仪表时间同步共用同一 ID) |
| 对照来源 | 除实车 trace 外,还用车辆仪表的报文处理逻辑做交叉对照 |
已解码信号
下表从源文档的修正记录中抽取。项目把依据分成几类:与仪表固件一致(可认为已确认)、与另一条可信信号比值拟合(已确认)、以及仅从原始数据推断、尚无固件旁证(标注为推断)。本文原样保留这些标注。
| 信号 | 位置(ID / DID / 字节) | 解码 | 证据 |
|---|---|---|---|
| 电池电压 | 0x186(消息 390) | 每计数 0.0625 V | 已确认 |
| 电池电流 | 0x386(消息 902) | 有符号;10 Hz | 已确认(由无符号改为有符号) |
| 电机转速 | 0x390(消息 912) | 有符号 | 已确认(由无符号改为有符号) |
| 电机扭矩(实际,skai_torque) | 0x290(消息 656)内的 int16 字段 | 刻度为推断 | 非固件确认(源文档明确标注) |
| 直流母线电压 | 0x290(消息 656) | 因子由 1 改为 0.1 | 已确认(与电池电压比值 0.0997±0.002) |
| 12 V 电压 | 0x291(消息 657) | 无符号 | 已确认(由有符号改为无符号;读数约 13.8 V) |
| 充电机高压 VoltageHV | 0x1C0(消息 448) | 因子由 1 改为 0.0625 | 已确认(比值 0.06211±0.00001) |
| 充电机温度 / 散热器温度 | 0x1C0(消息 448) | 有符号修正 | 已确认 |
| 电芯电压 | 0x406,轮转槽位 | mV | 标定记录(新 BMS 轮转 37 槽,原 BMS 以 cell 0 作填充) |
| 电芯温度 | 0x406 | 摄氏度 | 标定记录 |
| BMS 状态 / 剩余能量 | 0x306(消息 774) | — | 标定记录(新 BMS 变体下为占位值,原 BMS 为真实值) |
| FECU 故障位掩码 | 0x292(消息 658)B5:B7 | 位掩码,需按仪表固件的字节序重建 | 已确认(与仪表报文处理逻辑交叉核对) |
| 请求扭矩 requested_torque | 0x191(消息 401) | — | 未固件确认 |
读取方法与注意事项
第一条是字节序与符号位。源文档对若干字段做了符号修正:电池电流、电机转速原本被当成无符号,实际是有符号;而 12 V 电压则相反,原本当成有符号,实际是无符号。这类错误不会让程序报错,只会让数值在某个区间里「看起来合理、其实错位」,所以必须逐字段核对。
第二条是多路复用。源文档指出有消息在仪表侧被复用于多个子报文,例如充电机信息与仪表时间同步共享同一 ID;解析时必须先按子报文的标志位区分,否则会把时间同步的字节当成充电机参数读。项目对涉及掩码的字段做了专门的屏蔽处理。
第三条是校验和字节序重建。故障位掩码所在的字段不是简单的 24 位小端,源文档依据仪表固件的处理逻辑做了字节序重建,并用一条实车记录验证了修正前后的差异(修正后的取值与预期一致)。这说明「字段看起来是连续的」并不等于「可以直接按小端读」。
证据等级与边界
源文档把修正依据分层:与仪表固件一致、或与另一条可信信号做比值拟合的,标为已确认;仅从原始数据推断、没有固件旁证的,明确标注为推断。例如电机扭矩的刻度就是推断值——虽然原始 int16 字段的位置确定,但「一计数等于多少牛米」尚未被固件证实。
另一条重要边界是「BMS 变体」。源文档把车分成两类:一台装新开发的 BMS(参照原厂设计但不完全相同),另一台在参考日志里仍装原厂 BMS。两者在若干报文上的行为不同——例如电芯电压轮转的填充槽位、某些报文的周期(1 Hz 与 10 Hz)。因此同一辆车的档案也要先确认 BMS 变体。
边界上必须强调:以上信号位置与刻度都限定在源文档记录的这些车辆与这一版 DBC。不同 BMS 变体、不同固件之间差异明显,跨车使用前必须重新核对。
常见问题
为什么这辆车的 DBC 要反复修正?
因为早期 DBC 是手工整理的,存在真实错误:多个字段被错判符号(电池电流、电机转速被当成无符号;12 V 电压被当成有符号),两个电压的刻度也不对(由 1 改为实测拟合值)。源文档逐条记录了修正依据,并区分「已确认」与「推断」。
电机扭矩的刻度为什么只标「推断」?
因为该字段的位置是确定的原始 int16,但「一计数等于多少牛米」没有得到仪表固件的证实,只能从数据推断。源文档没有把它当作已确认值,使用时应保留这一不确定性。
同一车系为什么会有两套 BMS 行为?
因为源文档对照了两台车:一台装新开发的 BMS,另一台仍装原厂 BMS。两者在报文周期与电芯电压轮转的填充方式上都不同(例如新 BMS 轮转 37 槽而原 BMS 以 cell 0 填充)。解析前必须先确认 BMS 变体。
这些修正能直接套到别的车上吗?
不能。源文档的结论限定在被记录的车辆与 DBC 版本上,不同 BMS 变体与固件之间的差异已被证实存在。跨车使用前必须重新核对。
延伸阅读
- CAN 报文解析的「健康位」在说什么 —— 校验、计数器与总线空窗,与本文的故障位掩码和字节序重建直接相关
- 车载信号为什么会说谎:TTL、源时间与 500 ms 新鲜度阈值 —— 与本文「字段看似合理其实错位」是同一类陷阱
- 同一个「转向灯」在三家车厂是三种实现 —— 与本文「同一字段需先确认 BMS 变体」思路相通
- Mazda MX-5 ND2:HS-CAN 开放字段与逐字节标定 —— 同批另一篇车型档案,对照两篇各自的「标定/修正」方法
参考资料
- 项目 06 ——
public-can-dbc-datasets/additional/janniksteiner-sam-can/PROJECT_NOTES.md(本项目车型档案主来源:DBC 修正项、BMS 变体与效率图方法) - 项目 06 ——
public-can-dbc-datasets/additional/janniksteiner-sam-can/README.md(查看器与记录格式说明) - 项目 06 ——
public-can-dbc-datasets/additional/janniksteiner-sam-can/SOURCE.md(DBC 规模与来源说明)
说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11
发表回复