本文将以一个结构化的方式,带您逐步入门控制器局域网(CAN)协议。学习路径如下:
-
物理层:硬件组成与连接 - 协议运行的物理基础。
-
信号层:比特的编码与同步 - 如何在无时钟线上可靠地传输比特。
-
协议层:帧格式与通信逻辑 - 比特如何组成有意义的报文。
一、CAN的硬件组成与连接
CAN总线硬件主要由三部分构成:
-
总线本身(CAN_H, CAN_L与终端电阻):
-
采用双绞线,使用差分信号传输,具有优异的抗共模干扰能力。
-
高速CAN(ISO 11898-2) :如图所示,在总线两端 各有一个120Ω的终端电阻,将CAN_H和CAN_L连接起来,形成闭环。这种设计使总线在空闲时,通过电阻将差分电压拉至0V(隐性电平)。
-
低速/容错CAN(ISO 11898-3) :如图所示,其拓扑更为灵活。每个节点内部通常都有上拉/下拉电阻,主动地在空闲时将CAN_H偏置到高电压(如~1.75V),CAN_L偏置到低电压(如~3.25V),从而产生一个稳定的差分隐性电平(-1.5V)。这种设计允许单根导线故障时仍能通信。
-
-
CAN收发器:
-
位于MCU和物理总线之间,充当"翻译官"。
-
发送端:将MCU的TTL数字信号(0/1)转换为总线上的差分电压信号(显性/隐性)。
-
接收端:将总线上的差分电压信号还原为TTL数字信号给MCU。
-
-
MCU与CAN控制器:
-
CAN控制器(可能集成在MCU内部或作为外部芯片)实现协议的核心逻辑。
-
功能:组帧、解帧、CRC校验、错误处理、波特率控制、总线仲裁等。
-

二、信号在总线上的体现(比特时序与同步)
CAN总线没有独立的时钟线,所有节点必须预先设定相同的通信波特率(如500kbps)。
-
比特的表示:
-
显性电平(Dominant,逻辑0):CAN_H与CAN_L电压差明显(高速CAN典型值为+2V)。优先级高,可覆盖隐性电平。
-
隐性电平(Recessive,逻辑1):CAN_H与CAN_L电压差近似为0(高速CAN)或为负(低速CAN)。优先级低。
-
这种"线与"特性是实现非破坏性仲裁的硬件基础。
-

左边的高速can因为硬件连接为闭环,在所有控制器不对总线进行操作的状态下,会自动收缩为一致的电平状态,即canh=canl。而右边的低速can的总线是非闭环的,在空闲状态下需要各个收发器同时进行有源偏执来管理总线的空闲电平。
规定在空闲状态下的电平为1,并命名为隐性电平。这里隐形的含义在于它是弱电平,是优先级低的空闲电平,同时也是在can总线没有信号差分的状态。而非空闲且canh-canl的电平差分大于一定数值时,即为0,被称为显性电平。具体的总线信号0或1的定义如下图。

三、协议的具体内容(帧格式)
CAN协议定义了5种帧类型来管理通信。
数据帧:用于节点向总线发送数据。
-
图上,灰色表示显性电平,紫色表示可变化部分、由程序决定,白色表示隐形电平。
SOF(帧起始,1bit,显性):标志帧开始,通知所有节点并用于硬同步。
-
仲裁场(Identifier + RTR + IDE):
-
标识符(ID,11bit或29bit) :决定报文的优先级(值越小,优先级越高),并标识数据内容,而非发送节点地址。
-
RTR(远程传输请求,1bit) :隐性 表示此为数据帧。
-
IDE(标识符扩展,1bit):显性表示标准帧(11位ID),隐性表示扩展帧(29位ID)。
-
-
控制场(r0, r1, DLC):
- DLC(数据长度码,4bit):指明数据场中的字节数(0-8)。
-
数据场(0-64bit):实际传输的数据。
-
CRC场(15bit + 1bit界定符):循环冗余校验码,用于接收方检测传输错误。界定符为隐性,标志CRC场结束。
-
ACK场(ACK Slot + ACK Delimiter):
-
ACK槽(1bit) :发送器在此位发送隐性 电平。所有正确接收到 帧的节点(无论ID是否匹配)会在此位覆盖为显性电平作为应答。若发送器未读到显性电平,则知传输失败并重发。
-
ACK界定符(1bit,隐性):标志ACK场结束。
-
-
EOF(帧结束,7bit,隐性):标志数据帧/远程帧的结束。
遥控帧:用于主动请求具有特定ID的数据帧。

-
帧结构与数据帧相似,但有两大区别:
-
RTR位为显性。
-
没有数据场。
-
-
工作原理:节点A发送ID为X的遥控帧。负责生产ID为X数据的节点B收到后,会立即响应一个ID为X的数据帧
错误帧:当任何节点检测到错误时,会立即发送错误帧,意味着可能是主动发送方,也可能是被动接收方。中断当前传输,迫使发送方重发。
-
结构 :由错误标志 (6个连续显性位,或6-12个连续显性位的叠加)和错误界定符(8个隐性位)组成。
-
关键点 :错误帧通常由发送方自己发起(如通过位监控发现错误),从而实现快速自我纠正和全网状态同步。

过载帧 :由接收节点在帧间隔期间发出,表示其内部尚未准备好接收下一帧数据,请求延迟。
-
结构:与错误帧类似(过载标志+过载界定符)。
-
触发时机:仅在帧间隔的间歇场期间发送。它"重置"了帧间隔计时,为请求节点争取了额外的处理时间。
-
用于接收方发送,有且只能在间歇场发送。表示接受处理处于过载状态。其实过载帧没有接收方,它的作用类似于强行占用总线,使得大家无法交流来拖延下一帧说话的时间。

帧间隔:
-
它不是一种帧 ,而是分隔数据帧/远程帧的强制规则。
-
由间歇场(3个隐性位) 和其后的总线空闲(任意长隐性位) 组成。
-
作用:
-
间歇场:为接收节点提供固定的处理时间。此期间只允许发送过载帧。
-
总线空闲:间歇场结束后,总线进入空闲状态,任何节点均可开始仲裁以发送新帧。
-
