← 返回科普中心

DBC 信号字节序:Intel 与 Motorola、起始位与换算

一条 SG_ 行如何把 CAN 载荷里的位映射为工程量数值。

更新于 2026-11-05

DBC 是 Vector 提出的纯文本数据库格式,用来描述 CAN 网络。它并不承载报文本身,而是说明如何解释报文。报文用 BO_ 声明,后跟标识符、名称、DLC 和发送节点;信号挂在报文下,用 SG_ 行描述。CM_ 添加注释,BA_ 挂属性(例如周期时间 GenMsgCycleTime),VAL_ 定义枚举值表,BO_TX_BU_ 列出附加发送节点。真实项目里的文件常以 Windows-1252 或 GBK 编码保存,只按 UTF-8 读取的解析器会悄悄弄坏信号名和注释,因此宽容的编码回退是可靠读取 DBC 的一部分。

一条 SG_ 行几乎包含提取数值所需的全部信息:信号名、起始位、位长度、字节序标记、符号标记、factor 与 offset、最小值与最大值、单位以及接收节点列表。标记只有两种,@1 表示 Intel(小端),@0 表示 Motorola(大端);长度后面跟一个减号表示原始整数有符号,换算前必须先做符号扩展。圆括号里是 factor 与 offset,方括号里是显示范围。其余都是元数据:方便人阅读,但不会改变线上传输的位。

SG_ 行逐项拆解

BO_ 256 EngineData: 8 ECU
 SG_ EngSpeed : 3|16@1+ (0.25,0) [0|16383] "rpm" Dashboard

把示例读成:信号 EngSpeed 从第 3 位开始,长度 16 位,Intel 字节序,无符号,用 factor 0.25、offset 0 换算成 rpm。物理值永远等于「原始值 × factor + offset」,而且是在原始整数提取(必要时符号扩展)之后才应用。因为起始位指的是载荷内部的某个位置,它的含义取决于字节序:@1 从字节 0 的低位向高位、跨字节继续递增;@0 则从起始位置的最高位开始,向下延伸并跨到下一个字节。所以把标记写反会得到完全不同的数值,而不是简单的字节交换。

为什么字节序决定一切

对比同一个 16 位信号在 Intel 与 Motorola 布局下占用的位

同一个从第 3 位开始的 16 位信号,在不同字节序下占用的物理位不同。Intel(@1,小端)从字节 0 的最低位开始向字节 1 延续;Motorola(@0,大端)从最高位开始向跨字节的下方延伸。因此起始位在两种布局里含义不同;只有正确提取原始整数,才能再套用 factor 与 offset 换算物理值。
同一个从第 3 位开始的 16 位信号,在不同字节序下占用的物理位不同。Intel(@1,小端)从字节 0 的最低位开始向字节 1 延续;Motorola(@0,大端)从最高位开始向跨字节的下方延伸。因此起始位在两种布局里含义不同;只有正确提取原始整数,才能再套用 factor 与 offset 换算物理值。

以从第 3 位开始的 16 位信号为例。Intel 布局下,前 5 位落在字节 0 的高半部分,接着 8 位填满字节 1,最后 3 位落在字节 2 的低半部分。Motorola 布局下,信号先占字节 0 的第 3 位到第 0 位,然后跳到字节 1 的第 7 位一路向下到第 0 位,再取字节 2 的第 7 位到第 4 位。两种描述都得到 16 位,但指向的是不同的物理格子。这是手工移植数据库时最常见的错误来源,也是为什么查看器最好同时展示原始整数与换算后的物理值——一写错就能立刻看出来。

DBC 常见关键字

  • BO_ —— 报文(标识符、名称、DLC、发送节点)
  • SG_ —— 信号(起始位、长度、字节序、符号、换算、单位)
  • CM_ —— 挂在报文、信号或节点上的注释
  • BA_ / BA_DEF_ —— 属性值及其定义
  • VAL_ —— 符号值表,例如 0 关闭、1 打开
  • BO_TX_BU_ —— 报文的附加发送节点

真实数据库往往很脏:重复的标识符、缺失的 BA_DEF_ 定义、非 ASCII 注释、声明长度超过 DLC 的信号,以及混用编码的行。好用的查看器会把这些报告成诊断信息,而不是拒绝打开整个文件,因为工程师通常需要先用上有效的那 95%。把解析结果导出成 CSV 或 XLSX 后,每条信号占一行,列出报文 ID、名称、起始位、长度、字节序、factor、offset、单位、注释和值表——这是一份可以评审、可以和下一版数据库做 diff 的产物。

记住:字节序是数据库的属性,不是总线的属性。CAN 控制器只搬运八个字节,解释方式完全写在 DBC 文件里。

在查看器里试一试

打开示例文件,或拖入自己的 DBC/A2L 文件。解析完全在本浏览器进行,不会上传任何内容。

打开查看器

常见问题

SG_ 行里的 @1 和 @0 是什么?

@1 是 Intel 小端,@0 是 Motorola 大端;两者的差别在于跨字节时位如何延续。

factor 和 offset 用在哪一步?

先提取原始整数,再计算 物理值 = 原始值 × factor + offset;单位、最小值、最大值只是显示用元数据。

相关文章

下一个主题写什么?发一封简短邮件告诉我们——没有表单,也没有追踪。

lei_xu@163.com