☰
CAN通信——数据帧、CAN仲裁机制解析
2026/10/23 5:03:23 网站建设 项目流程

1.CAN简介

CAN 的全称是 Controller Area Network,即控制器局域网。

经典高速 CAN 通常采用 CAN_H 和 CAN_L 两根差分信号线传递数据。接收器主要根据两根线之间的差分电压判断总线状态,而不只是判断某一根线对地的电压,这也决定了它具有较强的抗干扰能力。

CAN 的一个重要特点是:一个设备发送报文后,总线上的其他设备原则上都能接收到该报文,再根据 ID 过滤或决定是否处理它。CAN 标识符主要用来区分报文类型和仲裁优先级,而不是简单地表示“这条数据只发给哪个设备”。

2.CAN的两种总线状态:

2.1显性位

典型高速 CAN:CAN_H 约 3.5 V,CAN_L 约 1.5 V,差分电压约 2 V。

2.2 隐性位

典型高速 CAN:CAN_H、CAN_L 都约为 2.5 V,两线差分电压接近 0 V。

CAN 总线采用一种类似“线与”的仲裁逻辑:只要有一个节点发送显性位0,总线就呈现显性状态;只有所有正在参与的节点都发送隐性位1时,总线才呈现隐性状态。

节点A发送节点B发送总线实际状态
000
010
100
111

3.一个CAN数据帧的组成

CAN 总线不是简单地把几个字节直接发送出去,而是由 CAN 控制器按照协议,把 ID、控制信息、数据、校验位等组合成一个完整的帧(Frame)。

经典 CAN 主要定义四种帧:数据帧、远程帧、错误帧和过载帧。其中日常通信最常用的是数据帧。

CAN的数据帧又分为:CAN数据帧——标准帧和CAN数据帧——拓展帧

  • 标准格式数据帧(Standard Frame):标识符 ID 为 11 位。

  • 扩展格式数据帧(Extended Frame):标识符 ID 为 29 位。

  • 两者都包含帧起始、仲裁字段、控制字段、数据字段、CRC 字段、ACK 字段和帧结束,但仲裁字段和控制字段的具体结构有所不同。

3.1CAN数据帧——标准帧

标准格式数据帧

SOF11位IDRTRIDE(0)r0DLCDATACRCACKEOF

3.1.1 SOF:帧起始位(1 位)

  • SOF 全称是Start of Frame,用于标识一帧报文的起始

  • 固定为显性位0。

  • 总线上的其他节点通过观察总线状态和位时间进行接收、同步。

  • 示例:

    总线空闲:1111
    开始发送:0

    总线上连续出现的隐性位不表示报文开始,真正的 SOF 是显性位。

3.1.2 仲裁字段(12位)

CAN标准帧的仲裁字段包含11位ID和1位RTR。

ID(11位)

ID是 CAN 最重要的字段之一,具有两个核心用途:

用途1:标识这条报文的类别或含义。

例如通过不同的ID标识电机的不同参数:

ID约定的含义
0x100电机状态
0x101电机目标转速
0x200温度数据
0x300故障状态

重点:CAN ID 并不自动表示目标设备地址。 总线上的设备都能接收到帧,再通过硬件过滤器或软件判断是否需要处理它。

用途2:在多个设备同时申请发送时,决定哪条报文优先发送。

ID 以最高有效位在前的顺序发送。通常在相同帧格式中,ID 数值越小,仲裁优先级越高。这个结论后面会结合逐位仲裁详细解释。

RTR(1位)

(Remote Transmission Request)即远程传输请求,用于标识当前帧是数据帧还是远程帧。

RTR含义
0数据帧
1远程帧

数据帧是发送实际数据的帧。远程帧则用于请求其他节点发送具有指定 ID 的数据帧,本身不携带数据字段。

例如,某节点希望请求 ID 为0x200的数据,可以发送对应 ID 的远程帧。但现代 CAN 网络的应用层协议通常使用更明确的请求报文或服务机制,而不是大量依赖远程帧。

有一个与仲裁有关的重要结论:如果相同 ID 的数据帧和远程帧同时竞争总线,数据帧的 RTR 为0,远程帧的 RTR 为1,所以数据帧优先。

CAN FD 不支持经典 CAN 的远程帧格式,因此不要将这个机制照搬到 CAN FD。

3.1.3 控制字段(6位)

控制字段包含1位IDE、1位r0、4位DLC

IDE(1位)

IDE 的英文为 Identifier Extension,用于标识当前帧是标准帧还是拓展帧。

IDE帧类型
0标准帧(11位ID)
1拓展帧(29位ID)
r0(1位)

保留位

在经典 CAN 格式下,保留位应按照标准发送为显性位0。

DLC(4位)

DLC 的英文是 Data Length Code,用来指示数据字段的长度。

经典 CAN 每帧最多传输 8 字节数据,因此常用 DLC 与字节数的对应关系如下:

DLC数据长度
00000字节
00011字节
00102字节
00113字节
01004字节
01015字节
01106字节
01117字节
10008字节

普通经典 CAN 数据帧应使用 0~8 对应的有效数据长度。不要把 DLC 的 4 位理解成“数据最多 15 字节”:它虽然有 16 种二进制组合,但经典 CAN 的数据字段仍然最多只有 8 字节。CAN FD 则对 DLC 使用了不同的长度映射,后面会介绍。

3.1.4数据字段(0~64位)

Data 字段才是应用真正要传输的数据。例如:

CAN_ID0x100
DLC4
DATA01 02 03 04

这表示 ID 为0x100、数据长度为 4 字节、数据内容为01 02 03 04的报文。

但需要注意,CAN 标准只规定怎样传输这些字节,并不自动规定它们的物理意义。如果数据01 02 03 04代表温度、转速、故障码还是其他数值,必须由上层通信协议或项目自身的数据定义来解释。

数据位也按照协议规定的位顺序发送。多字节变量如何排列、整数采用什么字节序、数据如何缩放,都需要通信双方事先约定。

3.1.5 CRC字段(16位)

CRC 的英文为 Cyclic Redundancy Check,作用是检测报文在传输过程中是否出现了数据错误。

发送端按照协议规定的算法计算 CRC;接收端根据收到的报文重新计算并进行比较。如果结果不匹配,接收端会检测到 CRC 错误,并按照 CAN 错误处理机制采取相应动作。

CRC 序列之后还有一个单独的 CRC 分隔符,在经典 CAN 中该位必须为隐性位1。

3.1.6 ACK字段(2位)

ACK是应答字段包含两个不同的位:

字段位数含义
ACK Slot(ACK 槽)1位接收节点确认收到有效报文的位置
ACK Delimiter(ACK 分隔符)1位固定格式的分隔位,必须为隐性位

ACK 槽有一个特别重要的设计:

  • 发送端在 ACK 槽发送隐性位1。

  • 至少一个能够正确接收该帧的节点会在 ACK 槽驱动显性位0。

  • 发送端观察到显性位,便知道至少有节点正确接收了该报文。

但是,ACK 不是应用层的“业务处理成功”回复。它只代表有节点接收成功,不证明特定目标设备已经执行了命令。

3.1.7 EOF(7位)

EOF 的英文为 End of Frame。经典 CAN 帧的 EOF 是连续 7 个隐性位1,用于标明当前帧结束。

EOF 之后通常还需要 3 个隐性位的帧间隔(Intermission),以便总线按协议进入下一帧的发送时机。

帧间隔不属于前一帧的 EOF 本身。

至此,经典 CAN 数据帧的主要字段就完整了:从 SOF 开始,经过 ID、控制、数据和 CRC,再通过 ACK 确认接收情况,最后用 EOF 结束帧。

3.2 CAN数据帧——拓展帧

拓展格式数据帧

SOF11位基础IDSRRIDE(1)18位拓展IDRTRr1r0DLCDATACRCACKEOF

数据帧拓展帧与数据帧标准帧的区别在于仲裁字段和控制字段,其他部分都一样。

拓展帧中出现的新标识:SRR和r1

SRR

SRR 的英文为 Substitute Remote Request,用于在扩展帧中的替代原来在标准帧中的远程请求位。

它出现在扩展帧的 ID-A 与 IDE 之间,通常发送隐性位1。它的一个重要作用是保证标准帧和扩展帧在具有相同的 11 位基本标识符时,可以按照协议正确完成仲裁。

r1

在经典 CAN 格式下,r1和r0属于保留位。保留位应按照标准发送为显性位0。

  • 标准帧的控制字段含有r0。

  • 扩展帧的控制字段含有r1和r0。

在 CAN FD 中,一些原有的保留位位置被赋予了新的协议用途,所以学习经典 CAN 时,应以经典 CAN 的定义为准,不能混用两种格式。

注意:标准格式中IDE属于控制字段;拓展格式中IDE属于仲裁字段。IDE位不仅用于标识帧格式,他在两种帧中的位置也不同。

对于扩展格式数据帧:

  • SRR =1(隐性位)

  • IDE =1(隐性位)(1标识拓展帧)

  • RTR =0(显性位)(0标识数据帧)

注意:SRR 和 IDE 都不属于 29 位 ID。 它们是独立的协议控制位,只是出现在扩展格式的仲裁字段中。

在经典 CAN 2.0 中:

  • 标准格式数据帧:IDE =0(显性位),表示 11 位标准标识符。

  • 扩展格式数据帧:IDE =1(隐性位),表示 29 位扩展标识符。

  • 标准格式的控制字段有IDE(0)、r0、DLC

  • 拓展格式的控制字段有r1、r0、DLC

  • 因为扩展格式的 IDE 已经放进了仲裁字段,所以控制字段不再包含 IDE。

4. CAN仲裁机制

这是 CAN 协议最有特色的部分,用于解决多个设备同时发送的问题。

假设总线上有三个设备:

  • 节点 A:发送电机转速报文,ID 为0x100。

  • 节点 B:发送温度报文,ID 为0x200。

  • 节点 C:发送故障状态报文,ID 为0x080。

如果三个节点恰好同时准备发送,谁先发送?

普通串口往往需要通过软件或额外的控制机制协调发送时间。而 CAN 利用标识符的优先级和显性、隐性位的电气特性,直接在总线上完成逐位仲裁。

4.1 仲裁的基本规则

先记住三条规则:

  • 总线空闲时,节点可以申请发送。

  • 节点逐位发送仲裁字段,同时读取总线上的实际电平。

  • 如果某个节点发送隐性位1,却发现总线上是显性位0,它就输掉本次仲裁,并停止发送自己的报文。

正常的仲裁失败不是通信错误。失败节点不会故意发送错误帧去打断获胜节点,而是退出竞争,转为接收总线上的报文。获胜节点继续发送,不需要因为这次仲裁失败而重新发送整帧。

4.2 用一个真实的 ID 示例理解仲裁

假设节点 A、B 同时发送两个标准数据帧:

参数节点A节点B
CAN ID0x1230x124
11位ID的二进制表示001 0010 0011001 0010 0100

两个ID从最高位开始比较:

位序列ID10ID9ID8ID7ID6ID5ID4ID3ID2ID1ID0
节点A00100100011
节点B00100100100

首次出现差异的位置是ID2

前面的位完全相同,两个节点一直同时参与仲裁。当发送到ID2时:

节点 A 发送 0,令总线进入显性状态;

节点 B 发送 1,却读到总线为 0,判断自己失去仲裁,立即退出竞争。

节点 A 获得总线使用权

节点 A 继续把这一帧发送完,节点 B 等待适当时机再发送自己的报文。

这就是无损仲裁。多个节点同时开始发送并不一定造成冲突;只要它们在仲裁字段中能区分出优先级,失败节点就会自动退出,而获胜节点的报文不会被破坏。

4.3 为什么 ID 越小,优先级通常越高?

在同样的经典 CAN 帧格式下,标识符按照最高位优先的顺序发送。

较小的 ID 通常在更靠前的位置出现显性位0。当两个 ID 首次出现差异时,发送0的节点会胜过发送1的节点。因此,较小的数字一般具有更高的仲裁优先级。

这里的“优先级”是总线访问优先级,不是 CPU 中断优先级,也不意味着 ID 数值小的节点永久独占总线。当高优先级报文没有待发送数据时,其他节点仍然可以发送。

需要注意三个细节:

  • 优先级主要由仲裁字段决定,而不是由数据内容决定。

  • 标准帧与扩展帧具有额外的格式区分位,不能在所有格式组合中只看十进制 ID 就判断。

  • 如果两个节点使用相同的仲裁信息,却要发送不同的数据,它们就可能在仲裁结束后出现位错误。这种设计通常应避免。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询