Intel:起始位是 LSB
位从字节 0 的最低位开始编号,信号向高位生长,一个字节填满后进入下一个字节。即小端。
粘贴一段报文数据,按 DBC 的写法描述各个信号,就能看到每个信号的原始值、物理值,以及它占用的具体位。改动任意一个数值,报文数据会跟着变。
字节之间用空格隔开,例如 00 00 40 1F
原始值范围 0 到 65535
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
|---|---|---|---|---|---|---|---|---|
| 0 | ||||||||
| 1 | ||||||||
| 2 | ||||||||
| 3 | ||||||||
| 4 | ||||||||
| 5 | ||||||||
| 6 | ||||||||
| 7 |
| 信号 | 原始值 | 十六进制 | 物理值 | 单位 |
|---|---|---|---|---|
| Engine_Speed | 1F40h | rpm | ||
| Coolant_Temp | 5Ah | °C | ||
| Throttle_Pos | 80h | % | ||
| Gear | 5h |
四步完成,数据不会离开你的浏览器。
选好字节序和数值类型,再按 DBC 里的写法填入起始位、长度、系数、偏移和单位。
以十六进制输入一帧的数据字节。空格、逗号和 0x 前缀都可以,CAN FD 最多 64 字节也支持。
表格给出每个信号的原始值、十六进制和物理值,位布局显示它们各自占用哪些位。
输入新的原始值或物理值,或者直接点击某一位,报文数据会随之更新。添加更多信号,就能一次看清整条报文。
一帧 CAN 报文里只有字节。信号定义告诉你该取哪些位、按什么顺序取,以及怎样把得到的整数换算成工程值。
起始位、长度和字节序在报文数据里选定一段位。bit 0 是字节 0 的最低位。
选中的位被读成一个整数。有符号信号的最高位是符号位,整数按二进制补码解读。
原始整数乘以系数再加上偏移,得到以该信号单位表示的值。
# 0x1F40, factor 0.25, offset 0
raw = 0x1F40 # 8000
physical = raw * 0.25 + 0 # 2000# 3000 rpm back to bytes
raw = round((3000 - 0) / 0.25) # 12000
bytes = 0x2EE0 # E0 2E, Intel12 位有符号信号的范围是 -2048 到 2047。最高位为 1 时,要从无符号读数里减去 2^12:0xF9C 按无符号是 3996,3996 - 4096 得到 -100。
同一个 DBC 起始位,在两种字节序下含义不同。解码结果不对时,多半就是这两者搞混了。
位从字节 0 的最低位开始编号,信号向高位生长,一个字节填满后进入下一个字节。即小端。
起始位是最高有效位。信号沿着所在字节往 bit 0 方向走,再跳到下一个字节的 bit 7。即大端,在 DBC 里写作 @0。
读 DBC 文件和使用 CAN 工具时会遇到的词。
每个信号对应一行 SG_。从左往右读,就得到计算器需要的全部输入。
BO_ 416 EngineData: 8 ECU
SG_ Engine_Speed : 16|16@1+ (0.25,0) [0|16383.75] "rpm" Gateway| 部分 | 含义 |
|---|---|
| Engine_Speed | 信号名 |
| 16|16 | 起始位 | 位数 |
| @1 | 字节序:1 是 Intel,0 是 Motorola |
| + | 数值类型:+ 为无符号,- 为有符号 |
| (0.25,0) | 系数和偏移 |
| [0|16383.75] | 物理值的最小值和最大值,仅作说明,不参与计算 |
| "rpm" | 单位 |
| Gateway | 接收节点 |
信号上方的 BO_ 行给出报文 ID 和长度,例如 BO_ 416 EngineData: 8 ECU。DBC 用十进制存 ID,所以 416 就是 0x1A0。
把它们载入计算器,就能对照着看每一步。
@1+ 16|16 (0.25,0)
00 00 40 1F 00 00 00 00
Intel,起始位 16,16 位。字节 40 1F 读作 0x1F40,也就是原始值 8000。系数 0.25,结果是 2000。
@0+ 7|12 (0.1,0)
12 34 00 00 00 00 00 00
Motorola,起始位 7,12 位。字节 0 整个(12)加上字节 1 的高半字节(3),组成 0x123,即 291。系数 0.1,结果是 29.1。
@1- 0|12 (0.1,0)
9C FF 00 00 00 00 00 00
Intel,起始位 0,12 位,有符号。字节 9C FF 得到 0xF9C,按无符号是 3996。最高位为 1,所以减去 4096 得到 -100,系数 0.1 时就是 -10.0。
几乎所有算错的值,都能追到下面这几条之一。
Motorola 的起始位指向最高有效位,Intel 的起始位指向最低有效位。把 Motorola 信号当成 Intel 输入,会选中别的位,得到一个看似合理却错误的数。
Motorola 的位号在每个字节内部编号,而信号按网络顺序跨字节延伸。只给出一维位序号的工具,可能和 DBC 的起始位对不上,请用位布局核对。
把有符号信号按无符号读,-100 会变成 3996。数值突然跳到量程顶端时,先检查数值类型。
温度常常存成实际值加 40。不加偏移,每个读数都会高出 40 度。
用到第 9 个字节的信号没法从 8 字节的数据里读出。请核对 DLC,这条报文可能是 CAN FD 帧。
原始值是位里存放的整数。物理值等于 原始值 × 系数 + 偏移,是 DBC 对外给出的工程值,比如转速或摄氏度。
最常见的原因是字节序选错了。Motorola 的起始位指向 MSB,Intel 的起始位指向 LSB,同一个数字选中的位并不相同。还要看有没有符号:有符号信号最高位为 1 就是负数。
按 DBC 选字节序(@1 是 Intel,@0 是 Motorola),起始位原样照抄。位布局会显示每个字节用了哪些位,可以确认信号覆盖的字节是不是你预期的。
支持,最多可以粘贴 64 字节。最长 64 位的信号都按精确整数处理,包括超过 2^53、普通 JavaScript 数字会取整的数值。
可以。修改物理值,计算器会把最接近的原始值写进报文数据,其他位保持不变。如果数值超出该信号能表示的范围,会取边界值并提示你。
不会。计算都在浏览器里完成,报文数据和信号定义不会离开页面。
暂时不支持。每个信号都按始终存在来解码。对于多路复用的报文,只填写当前复用值下生效的那些信号。
先减去偏移,再除以系数,最后取最接近的整数:原始值 = round((物理值 - 偏移) / 系数)。在表格里修改物理值就是这样算的,并且会把位写进报文数据。
按 DBC 格式,1 到 64 位。原始值按精确整数处理,所以 64 位信号也不会丢精度。
做完这一步之后常见的下一步,每个都有独立页面。