CAN报文解析
可知 byte0的数据为0x02,也就是bit7~0依次为 0 0 0 0 0 0 1 0,其中bit0 = 0,bit1=1。如下图框选区域信号为例,Intel小端按照LSB在低字节的低位:Byte1的Bit0;根据帧ID长度的不同,分为标准帧(11位,0x000~0x7FF)和扩展帧(29位,0x0000 0000~0x1FFF FFFF),帧ID越小优先级高。:表示数据的字节数及保留位的段,
CAN报文解析
1.CAN报文种类
报文传输过程中有:数据帧、远程帧、错误帧、过载帧和帧间隔。另外,数据帧和远程帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(Identifier: 以下简称 ID), 扩展格式有 29 个位的 ID。
| 帧类型 | 帧用途 |
|---|---|
| 数据帧 | 用于发送单元向接收单元传送数据的帧 |
| 远程帧 | 用于接收单元向具有相同ID的发送单元请求数据的帧 |
| 错误帧 | 用于当检测出错误时向其它单元通知错误的帧 |
| 过载帧 | 用于接收单元通知其尚未做好接收准备的帧 |
| 帧间隔 | 用于将数据帧及远程帧与前面的帧分离开来的帧 |
1.1 数据帧
数据帧由7个段构成,图解说明如下所示:
-
帧起始和帧结束:
- 帧起始:由单个显性位组成,总线空闲时,发送节点发送帧起始,其他接收节点同步于该帧起始位。
- 帧结束:由7个连续的隐形位组成。

-
仲裁段:表示该帧优先级的段;根据帧ID长度的不同,分为标准帧(11位,0x000~0x7FF)和扩展帧(29位,0x0000 0000~0x1FFF FFFF),帧ID越小优先级高

-
控制段:表示数据的字节数及保留位的段,控制段共6位,标准帧的控制段由扩展帧标志位IDE、保留位r0和数据长度代码DLC组成;扩展帧控制段则由IDE、r1、r0和DLC组成如图所示:

-
数据段:数据的内容,可发送0~8个字节的数据;
-
CRC段:检查帧的传输错误的段;使用CRC校验进行数据检错,CRC校验值存放于CRC段。 CRC校验段由15位CRC值和1位CRC界定符构成:

-
ACK段:表示确认正常接收的段;当一个接收节点接收的帧起始到CRC段之间的内容没发生错误时,它将在ACK段发送一个显性电平如图所示:

| 域段 | 域段名 | bit | 描述 |
|---|---|---|---|
| 帧起始 | SOF(Start Of Frame) | 1 | 数据帧起始标志,固定为1bit显性('b0) |
| ID | Identify(ID) | 11 | 本数据帧的 ID 信息, ID 信息的作用:① 如果同时有多个节点发送数据时,作为优先级依据(仲裁机制);② 目标节点通过 ID 信息来接受数据(验收滤波技术) |
| RTR | Remote Transmission Request BIT | 1 | RTR标识是否是远程帧(0,数据帧;1,远程帧),在数据帧里这一位为显性('b0) |
| IDE | Identifier Extension Bit | 1 | IDE用于区分标准格式与扩展格式,在标准格式中 IDE 位为显性('b0),在扩展格式里 IDE 位为隐性('b1) |
| r0 | 保留位 | 1 | 1bit保留位,固定为1’b0 |
| DLC | data length | 4 | 由 4 位组成,MSB 先行(高位先行),它的二进制编码用于表示本报文中的数据段含有多少个字节,DLC 段表示的数字为0到8,若接收方接收到 9~15 的时候并不认为是错误,默认是8 |
| Data | data数据 | 0~64 | 数据帧的核心内容,它由 0~8 个字节(0 ~ 64位)组成,MSB 先行 |
| CRC段 | CRC | 15 | CRC段用于检查帧传输错误,发送方以一定的方法计算包括:帧起始、仲裁段、控制段、数据段;接收方以同样的算法计算 CRC 值并进行比较,如果不同则会向发送端反馈出错信息,重新发送;计算和出错处理一般由 CAN 控制器硬件完成或由软件控制最大重发数 |
| CRC界定符 | CRC | 1 | CRC 界定符(用于分隔的位),为隐性位(1’b1),主要作用是把CRC 校验码与后面的 ACK 段间隔起来 |
| ACK 槽 | ACK slot | 1 | 在 ACK 槽位中,发送端发送的为隐性位,而接收端则在这一位中发送显性位以示应答;发送 ACK/返回 ACK这个过程使用到回读机制,即发送方先在 ACK 槽发送隐性位后,回读到的总线上的电平为显性0,发送方才知道它发送成功了,不用重发 |
| ACK界定符 | 1 | 在 ACK 槽和帧结束之间由 ACK 界定符间隔开,为隐性位 | |
| 帧结束 | EOF | 7 | 由发送端发送 7 个隐性位表示结束 |
1.2 远程帧
与数据帧相比,远程帧结构中无数据段,由6个段组成,同理分为标准格式和扩展格式,且RTR位为1(隐性电平)如图所示。
数据帧与远程帧的区别:
1.3 错误帧
尽管CAN-bus是可靠性很高的总线,但依然可能出现错误;CAN-bus的错误类型共有5种:
当出现5种错误类型之一时,发送或接收节点将发送错误帧。错误帧的结构如下,其中错误标识分为主动错误标识和被动错误标识如图所示:
1.4 过载帧
当某个接收节点没有做好接收下一帧数据的准备时,将发送过载帧以通知发送节点;过载帧由过载标志和过载帧界定符组成如图所示:
由于存在多个节点同时过载且过载帧发送有时间差问题,可能出现过载标志叠加后超过6个位的现象如图所示:
1.5 帧间隔
帧间隔用于将数据帧或远程帧和他们之前的帧分离开,但过载帧和错误帧前面不会插入帧间隔
帧间隔过后,如果无节点发送帧,则总线进入空闲。
帧间隔过后,如果被动错误节点要发送帧,则先发送8个隐性电平的传输延迟,再发送帧。
1.6 CAN总线发送总流程
CAN-bus整个链路层处理数据的流程是如图所示:
2.CAN报文字节序Intel和Motorola
2.1 基本概念
LSB:Least Significant Bit最低有效位,MSB:Most Significant Bit最高有效位,两者并不代表传输顺序,只是二进制数的两个bit位。从标准UART数据传输格式的字节域中可以明显看到LSB和MSB仅代表两个bit,至于具体的信号传输方式,就是接下来要讲的Intel和Motorola格式,又称小端和大端格式。
2.2 Intel小端传输
要点:LSB在低字节的低位,MSB在高字节的高位。
1.信号不跨字节
如下图框选区域信号为例,Intel小端按照LSB在低字节的低位:Byte1的Bit0; MSB在高字节的高位:Byte1的Bit7。读取信号二进制值为01000110(十六进制:0x46)。
2.信号跨字节
如下图,Intel小端按照LSB在低字节的低位:Byte4的Bit0; MSB在高字节的高位:Byte5的Bit7。读取信号二进制值为01000110 10010111(十六进制:0x4697)。
2.3 Motorola大端传输
要点:LSB在高字节的低位,MSB在低字节的高位。
1.信号不跨字节
如下图框选区域,Motorola大端按照LSB在高字节的低位:Byte1的Bit0; MSB在低字节的高位:Byte1的Bit7。读取信号二进制值为01000110(十六进制:0x46)。
2.信号跨字节
如下图框选区域,Motorola大端按照LSB在高字节的低位:Byte5的Bit0; MSB在低字节的高位:Byte4的Bit7。读取信号二进制值为01000110 10010111(十六进制:0x4697)。
2.4 注意点
上述两种方式有什么区别呢?大端小端读出来不都是01000110 10010111(十六进制:0x4697)吗?但是请注意字节在内存中的排列方式完全不同。
Motorola大端:低位10010111(0x97)在内存的高地址区(byte5);高位01000110(0x46)在内存的低地址区(byte4)。
Intel小端:低位10010111(0x97)在内存的低地址区(byte4);高位01000110(0x46)在内存的高地址区(byte5)。
小结:
- 不管是Intel模式,还是Motorola模式,起始位都是该信号的LSB。
- 信号不跨字节的情况下,Intel和Motorola格式编码结果没有区别。注意是不跨字节,而不是小于8个bit,即使信号只有2个bit,也可能存在跨字节的情况。
3.CAN报文解析
3.1 通信协议(通信矩阵)
当我们想要解析这一帧报文时,我们需要先获取发送方制定的CAN报文解析规则。如果收发双方没有按照双方约定规则去填充或解析CAN报文,那么收发双方的数据交互一定会出问题的。CAN报文在发送和接收前,我们都会按收发双方约定好的规则去填充数据与接收解析数据。约定好的这个规则我们一般称之为CAN通信协议(也称为CAN通信矩阵)。
3.2 示例一
通常接收到的CAN报文由很多部分组成,解析报文时用到的主要是帧ID和数据两部分。
根据需要收到CAN报文之后,需要根据具体的通信协议解析(需要内部拟定),然后分析解析出的数据是否正确。下面进行报文实例解析,数据类型定义如表所示:
数据段一般由1 ~ 8个字节(Byte)组成,来代表通信协议中相应的含义。每个字节有2个字符,分为高4位和低4位。有的数据需要相邻的2个字节组合才能表示,则需要分为高字节和低字节。
例如 ,收到报文:
ID:1818D0F3
数据:ce 0d 00 7d 00 6d 11 00 。
第 1 个字节ce中的c为高 4 位,e为低 4 位。第 1 、 2字节表示总电压,而且注明Byte 1 为低字节,Byte 2 为高字节,那么解析时就应该为: 0dce。
帧ID:1818D0F3 数据:ce 0d 00 7d 00 6d 11 00
- 协议中规定报文的第一、二字节表示总电压,高字节在前,低字节在后(Intel格式)。又总电压的单位为0.1 V。所以在上面的数据中 0d ce 代表总电压,转为十进制为 3534,乘以0.1V的单位,则得到总电压值为353.4 V。
- 协议中规定报文的第三、四字节表示总电流,又总电流的单位为 0.1A,偏移量为 -32000 。所以在上面的数据中 7d00 代表总电流,转为十进制为32000 ,乘以 0.1 再减去 3200 的偏移量等于0 ,则说明此时电池组没有被充电或放电,电流为 0 。
3.3 示例二(Intel小端传输)
报文Id是0x01,数据域为 02 00 00 C8 00 D0 07 01。
通信协议:
根据通信协议可知,报文ID 0x01,这一帧报文是电池组控制参数,它是由VCU(整车控制器)发给BMS(电池管理系统)的。
我们接收到的报文信号 id:0x01,data:02 00 00 C8 00 D0 07 01。可知 byte0的数据为0x02,也就是bit7~0依次为 0 0 0 0 0 0 1 0,其中bit0 = 0,bit1=1。
- 数据域的第0位,也就是byte0的第0位为主继电器吸合的使能信号,此时bit0=0,说明此时主继电器吸合的使能信号为Disable;
- 数据域的第1位,也就是byte0的第1位为低压电上电使能信号,此时bit1=1,说明此时低压电上电使能信号为Enable;
- 数据域的第8-23位,也就是byte1-byte2为母线电压请求值,byte1和byte2组合起来为0x0000,是母线电压请求值的总线值,换算为物理值为0。母线电压请求值=0V;
- 数据域的第24-39位,也就是byte3-byte4为低压电压请求值,因为此通信协议遵循Intel格式解析数据。byte3= C8,byte4=00,按照Intel格式(LSB)组合起来就是 0x00C8,其物理值= 0x00C8 * 0.1 + 0 = 20。低压电压请求值=20V;
- 数据域的第40-55位,也就是byte5-byte6为母线电流限制值,因为此通信协议遵循Intel格式解析数据。byte5= D0,byte6=07,按照Intel格式(LSB)组合起来就是 0x07D0,其物理值= 0x07D0 * 0.1 - 2000 = -1800。母线电流限制值为-1800A;
- 数据域的第56-57位,也就是byte7为消息计数器的值,因为处于同一个byte,所以不需要区分motorola和Intel格式,Count值为1。
3.4 车企CAN报文示例(Motorola大端传输)
在数据段中,我们需要自己规定协议,主机厂指定在“信号矩阵表”里面,比如:有几个信号、每个信号里的01怎么解释、报文ID、起始位在哪里、长度是多少、系数、偏移量等等,物理量=原始量*系数+偏移量
如何把数据变成报文:

参考网址
CAN总线协议报文浅析_iot_Best_Ccc-2048 AI社区
更多推荐



所有评论(0)