1. CAN总线基础:从物理层到仲裁机制

大家好,我是老张。做汽车电子这行十几年了,CAN总线就像我的老朋友。今天咱们聊聊CAN总线的基础知识。别小看这些基础,我见过太多工程师因为忽略细节,在实车上栽跟头。

1.1 CAN协议概述

CAN,全称Controller Area Network,控制器局域网。上世纪80年代由德国Bosch公司开发,初衷是为了解决汽车内部电子设备之间的通信问题。

说白了,就是让车上的各个ECU(电子控制单元)能互相说话。发动机、变速箱、ABS、气囊、仪表盘……这些家伙都得通过CAN总线交换信息。

我个人习惯把CAN总线比作一个会议室。所有ECU都坐在会议室里,谁想发言就抢话筒。但有个规矩——优先级高的先讲。这就是后面要说的仲裁机制。

核心特点:

  • 多主站通信:任何节点都可以主动发消息
  • 实时性强:优先级高的消息延迟可控
  • 可靠性高:有完善的错误检测机制
  • 成本低:只需要两根线(CAN_H和CAN_L)

1.2 CAN物理层

物理层,就是实实在在的硬件。CAN总线用两根差分信号线:CAN_H(高)和CAN_L(低)。

为什么用差分信号?抗干扰啊!我在一个项目中遇到过,某款车在电磁干扰强的环境下,单端信号全乱了,但CAN总线纹丝不动。差分信号就是有这个好处——两根线受到的干扰几乎一样,相减之后干扰就被抵消了。

CAN总线的电平状态有两种:

状态 CAN_H电压 CAN_L电压 说明
显性(Dominant) 3.5V 1.5V 逻辑0,优先级高
隐性(Recessive) 2.5V 2.5V 逻辑1,优先级低

嗯,这里要注意:显性电平会覆盖隐性电平。也就是说,只要有一个节点发送显性位,总线上就是显性状态。这个特性是仲裁机制的基础。

实战经验:终端电阻一定要加!标准是120Ω,在总线两端各接一个。我见过有人偷懒不加,结果信号反射严重,通信时好时坏。排查了整整两天才找到原因。

1.3 CAN数据链路层

数据链路层,负责把物理层的信号组织成有意义的报文。CAN的报文帧结构是核心中的核心。

你想想看,总线上那么多节点,怎么知道哪条消息是发给自己的?靠的就是报文中的标识符(ID)。每个报文都有一个唯一的ID,接收节点根据ID决定是否接收。

1.4 CAN报文帧结构

CAN有四种帧类型:数据帧、远程帧、错误帧、过载帧。咱们重点说数据帧,因为平时用得最多。

数据帧

数据帧是干活的主力。它由7个段组成:

  1. 帧起始(SOF):1个显性位,告诉所有节点"我要发消息了"
  2. 仲裁段:包含ID和RTR位。ID决定优先级,RTR区分数据帧和远程帧
  3. 控制段:包含IDE位和DLC(数据长度码)。DLC告诉接收方数据有多少字节
  4. 数据段:0-8字节,真正要传的数据
  5. CRC段:15位CRC校验码+1位CRC界定符。用来检查数据有没有传错
  6. ACK段:接收节点在这里回应"我收到了"
  7. 帧结束(EOF):7个隐性位,表示帧结束

标准帧 vs 扩展帧:

  • 标准帧:11位ID,仲裁段共12位
  • 扩展帧:29位ID,仲裁段共32位

我建议能用标准帧就别用扩展帧。扩展帧虽然ID多,但帧长增加,总线利用率降低。除非你的系统节点特别多,ID不够用。

远程帧

远程帧是用来请求数据的。比如ECU A想知道ECU B的某个参数,就发一个远程帧,ID填上想要的数据ID。ECU B收到后,就会发送对应的数据帧。

说白了,远程帧就是"我要数据,你发给我"。

错误帧

错误帧是CAN总线的"警察"。当节点检测到错误时,就会发送错误帧,通知所有节点"刚才那条消息有问题,别用"。错误帧由6个显性位组成,会破坏当前帧的填充规则,让所有节点都发现错误。

注意:错误帧有主动错误和被动错误之分。主动错误节点发送6个显性位,被动错误节点发送6个隐性位。如果一个节点频繁发送错误帧,它可能会从主动错误变成被动错误,甚至进入总线关闭状态。我曾经调试过一个项目,某个节点因为硬件问题一直发错误帧,最后把自己"踢出群聊"了。

过载帧

过载帧用来告诉发送方"我忙不过来,慢点发"。它和错误帧结构类似,但用途不同。过载帧在两种情况下触发:

  • 接收节点内部条件未准备好
  • 检测到位填充规则违规

1.5 CAN总线仲裁机制

仲裁机制是CAN总线的精髓。多个节点同时发送时,谁优先级高谁先发。

怎么判断优先级?看ID。ID越小,优先级越高。仲裁过程是这样的:

  1. 所有想发送的节点同时发送仲裁段的第一位
  2. 每个节点发送一位后,读取总线电平
  3. 如果自己发送的是隐性位(1),但总线上是显性位(0),说明有更高优先级的节点在发,自己退出
  4. 重复这个过程,直到只剩一个节点

举个例子:节点A的ID是0x100,节点B的ID是0x200。二进制分别是:

  • A: 001 0000 0000
  • B: 010 0000 0000

发送第一位时,A发0(显性),B发0(显性),总线是0,都继续。发送第二位时,A发0(显性),B发1(隐性),总线是0(显性覆盖隐性)。B发现总线和自己发的不一样,就知道自己输了,乖乖退出。A继续发送剩余位。

你想想看,这个过程完全在硬件层面完成,不需要软件干预。这就是CAN总线实时性好的原因之一。

避坑指南:我曾经设计一个系统,把两个关键消息的ID设成了0x100和0x101。结果发现0x100的消息总是先发,0x101的消息经常被延迟。后来我把0x101改成了0x200,问题解决了。记住:ID分配要合理,关键消息用小的ID。

1.6 知识体系总览

下面这张图总结了CAN总线基础的核心内容,我习惯用这种图来梳理知识结构:

CAN总线基础知识体系 CAN总线基础 协议概述 物理层 数据链路层 仲裁机制 差分信号:CAN_H / CAN_L 显性/隐性电平 终端电阻120Ω 数据帧(7个段) 远程帧 / 错误帧 / 过载帧 标准帧(11位ID)vs 扩展帧(29位ID) ID越小优先级越高 显性位覆盖隐性位 无损逐位仲裁 多主站通信 实时性强 可靠性高 / 成本低 核心:物理层是基础,数据链路层是规则,仲裁机制是灵魂 理解这三层,CAN总线就掌握了80%

这张图把CAN总线基础分成了四个模块。我个人习惯先讲物理层,因为它是基础。然后是数据链路层,理解报文结构。最后是仲裁机制,这是CAN总线的灵魂。协议概述作为开篇,让大家有个整体认识。

好了,CAN总线的基础就聊到这儿。记住:物理层是骨架,数据链路层是血肉,仲裁机制是灵魂。三者缺一不可。


可可精品资料库