can-bus
2025-10-03 15:58:00

结构

  1. 闭环(高速CAN)
    闭环CAN

CAN总线网络由ISO 11898标准定义,是高速、短距离的CAN网络,通信速率为125kbit/s到1Mbit/s。在1Mbit/s通讯速率时,总线长度最长达40m。

  1. 开环(低速CAN)
    开环CAN

两根信号线独立,各自串联一个2.2k欧的电阻。这种CAN总线网络由ISO11519-2标准定义,是低速、远距离的CAN网络,通信速率最高125kbit/s。在40kbit/s速率时,总线最长距离可达1000m。

基本

CAN总线有两条信号线,CANH和CANL,没有时钟同步信号线,是一种半双工异步通信,类似于UART。两根信号线通常使用双绞线,传输差分信号(有效抑制外部电磁干扰)。

下面只讨论高速CAN。
以CANH和CANL间的电压差代表总线电平,与逻辑信号1或0对应。

  • 隐性电平(Recessive)对应于逻辑1
  • 显性电平(Dominant)对应于逻辑0
    总线电平
  • 高速CAN中隐性电平在电压差0附近,显性电平主要在电压差2V附近。

在高速和低速CAN中,从隐性信号向显性信号过渡的速度更快,因为此时CAN线缆被主动积极地驱动。显性向隐性的过渡速度主要取决于CAN网络的长度和导线的电容。

CAN总线采用不归零码位填充技术(NRZ),发送器只要检测到位流里有5个连续相同值的位,便自动在位流里插入补充位。(后续说明)

CAN总线上的一个终端设备称为一个节点(Node),没有主设备从设备的区别。一个CAN节点的硬件部分一般由两部分组成:

  • CAN控制器:实现CAN协议逻辑层功能,构建符合CAN协议的数据帧等,仲裁等等。
  • CAN收发器:实现MCU逻辑电平与物理CAN总线电平之间的转换。
  • 例如发送数据流程:
    • 微控制器将数据传送给CAN控制器
    • CAN控制器构建符合协议的数据帧
    • CAN控制器将逻辑电平信号发送给收发器
    • 收发器将逻辑信号转换为CAN总线差分信号

仲裁机制: CAN总线采用非破坏性仲裁机制,通过比较消息标识符的优先级来决定哪个节点有权继续发送数据。这种机制确保了总线上数据传输的有序性,避免了冲突。

广播通信: CAN总线采用广播通信方式,即发送的数据帧可以被总线上的所有节点接收。这种特性有助于信息的共享和同步,同时减少了系统的复杂性。

CAN位时序和波特率

一个CAN网络需要规定一个通信的波特率,各节点都以相同的波特率进行数据通信。
为了实现位同步,CAN 协议把每一个数据位的时序分解成如图所示的SS 段、PTS 段、PBS1 段、PBS2段,这四段的长度加起来即为一个CAN数据位的长度。分解后最小的时间单位是Tq(time quantum,时间量子),而一个完整的位由8~25个Tq组成。

Tq:tq由CAN控制器的时钟频率fcan决定。在STM32F407中,两个CAN控制器在APB1总线上,CAN控制器有预分频器,APB1总线的时钟信号PCLK1经分频后得到fcan。

位时序
(总线电平并没有在一个位时序内发生数次电平变化!!!图有误导性)

发送节点产生跳变沿的物理过程

  • 总线空闲状态:当总线空闲时,所有节点都不驱动总线,总线处于隐性状态(高电平,逻辑1)。
    CAN使用差分信号,空闲时CAN_H与CAN_L之间的电位差约为0V
  • 发送开始:
    当控制器准备发送时,首先发送SOF(起始帧)位,这是一个显性位(低电平,逻辑0)。
    发送节点通过驱动其收发器输出级,使CAN_H线变为约3.5V,CAN_L线变为约1.5V,这产生了约2V的电位差,代表显性位(0)
  • 关键跳变沿:从空闲(隐性,1)到SOF(显性,0)的转变产生了一个从高到低的跳变沿,这个下降沿是CAN帧传输开始的标志,也是所有接收节点开始同步的触发点

该图中表示的CAN通讯信号每一个数据位的长度为19Tq,其中SS段占1Tq,PTS段占6Tq,PBS1段占5Tq,PBS2段占7Tq。信号的采样点位于PBS1段与PBS2段之间,通过控制各段的长度,可以对采样点的位置进行偏移,以便准确地采样。

  • SS段(SYNC SEG)同步段
    若通讯节点检测到总线上信号的跳变沿被包含在 SS 段的范围之内,则表示节点与总线的时序是同步的,当节点与总线同步时,采样点采集到的总线电平即可被确定为该位的电平。SS 段的大小固定为 1Tq。

  • PTS段(PROP SEG)传播时间段
    用于补偿网络的物理延时时间。是总线上输入比较器延时和输出驱动器延时总和的两倍。PTS 段的大小可以为 1~8Tq。
    如果没有PTS段,当发送节点刚开始发送位的时候,远端接收节点还没有收到信号,可能会错过重要的边沿信息,导致同步失败。

  • PBS1段(PHASE SEG1)相位缓冲段
    用来补偿边沿阶段的误差,它的时间长度在重新同步的时候可以加长。PBS1 段的初始大小可以为 1~8Tq。

  • PBS2段(PHASE SEG2)相位缓冲段
    用来补偿边沿阶段误差的,它的时间长度在重新同步时可以缩短。PBS2 段的初始大小可以为 2~8Tq。

当节点检测到边沿不在预期的SS段时,启动再同步:
如果边沿提前到来,PBS2段会被缩短,
如果边沿延后到来,PBS1段会被延长,
调整量受SJW(同步跳跃宽度)限制

  • SJW(resynchronization Jump Width)再同步跳转宽度
    决定了相位缓冲段加长或缩短的上限,通常为1~4个tq。

如果检测到边沿在SS段后3Tq出现,受SJW(2Tq)限制,只能延长PBS1段2Tq,仍存在偏差,怎么办?
CAN不试图在单次重新同步中完全纠正所有偏差,而是通过多个位的连续重新同步来逐渐达到更好的同步状态,随后的位传输中会继续执行重新同步,逐步减小累积偏差。
采样点通常设置在位时间的70%-80%处,即使有1Tq的残余偏差,采样点仍能落在信号稳定区域。只要残余偏差不导致采样点跨越位边界,通信仍然可靠

通过位时序的控制,CAN总线可以进行位同步,以吸收节点时钟差异产生的波特率误差,保证接收数据的准确性。

波特率:总线上的各个通讯节点只要约定好 1 个 Tq 的时间长度以及每一个数据位占据多少个 Tq,就可以确定 CAN 通讯的波特率。

虽然严格来说同步调整确实会暂时改变位时长(影响瞬时波特率),但系统的整体通信速率仍由配置的波特率决定。

同步方法

硬同步

硬同步是接收单元在总线空闲状态检测出帧起始时进行的同步调整。硬同步仅在消息帧的开头(SOF位)执行。 在空闲时段(帧间间隔(INTERFRAME SPACING)中的总线空闲)之后,网络上的每个CAN控制器都会在SYNC_SEG的第一个接收隐性到显性边沿时初始化其当前位周期时序。 随后在每个接收到的隐性到显性边沿的整个消息的剩余部分中执行一次重新同步。

硬同步调整宽度不限。经过硬同步后,无论边沿相位误差如何,位时序都会在 Sync_Seg 结束时重新启动。因此,硬同步迫使硬同步的边沿位于重新启动的位时间的同步段内。

hard sync

根据 CAN 规范,当总线空闲时总线为隐性电平。此时,节点 A 发送数据,在出现 SOF 时,总线上的其他节点(如节点 B)也会监控到该变化。但是,节点 B 会发现,自己当前位的 SS 段和发送节点 SOF 位的 SS 段不同步。此时,节点 B 将强制将自己 SOF 位的 SS 段拉到与节点 A 的 SOF 位的 SS 段同步。

重新同步

在接收过程中检测出总线上的电平变化时进行的同步调整。 每当检测出1->0边沿时,根据 SJW 值通过加长 PBS1 段,或缩短 PBS2 段,以调整同步。但如果发生了超出 SJW 值的误差时,最大调整量不能超过 SJW 值。

re-sync

只用隐性→显性(1→0)这类边沿做同步锚点
同一个位内至多做一次重新同步(硬件会忽略该位里的后续边沿,以免过度调整)

避免长时间没有同步锚点,can采用位填充规则

为什么会在“同一个位”(以接收端本地时钟划的位窗口)里看到边沿:

  1. 发射端与接收端的位边界不完全对齐:
    真正的电平翻转都发生在发射端的位边界上,但由于两端时钟误差与总线传播延时,这个翻转到达接收端时,可能落在接收端当前位的 PTS/PBS1/PBS2 内,而不是它期望的 SS 段里。从接收端视角,这就是“位内部出现了一个 1→0 边沿”,因此需要在“当前位内”做一次重新同步去追齐它。
    物理层非理想导致“多次过阈” :
  2. 反射/震荡:终端不匹配、支路过长、走线不当会引起振铃,差分电压在阈值附近来回晃,比较器可能先后多次从隐性判到显性、又回去。
    EMI/噪声脉冲:外部干扰或地弹跳让总线瞬时叠加毛刺,短暂越过比较阈值,形成伪边沿。
    缓慢边沿+噪声:上升/下降沿过慢时,叠加噪声更容易造成阈值抖动,出现“抖边”。

帧格式

CAN2.0 Part B 规定了两种格式的帧,它们的 IDENTIFIER 域长度不同。带有 11 个比特位长的 IDENTIFIER 的帧被称为 标准帧(Standard Frames);带有 29 个比特位长的 IDENTIFIER 的帧被称为 扩展帧(Extended Frames)。

数据帧 DATA FRAME

用于将数据发送到节点

数据帧

DATA FRAME 由 7 个不同的位域组成:帧起始(START OF FRAME)、ARBITRATION FIELD、CONTROL FIELD、DATA FIELD、CRC FIELD、ACK FIELD、END OF FRAME。 其中,DATA FIELD 长度可以为 0。

帧起始

标志着数据帧和遥控帧的开始。占一个字节,必须为显性电平。
只在总线空闲(处于显性电平)时允许开始传输。硬同步调整依据。

仲裁域

  • 标注格式
    标注格式数据帧
    解释

仲裁域由 11 个比特位的 IDENTIFIER 和 1 个比特位的 RTR-BIT 组成。IDENTIFIER 位表示为 ID28 ~ ID18。
- IDENTIFIER: 长度为 11 个比特位, 对应于扩展格式的基本ID。 这些位按照从 ID28 ~ ID-18 的顺序发送。 最低位是 ID18。 7 个最重要的位(ID28 ~ ID22)不能全部为“隐性电平”。
- RTR BIT: 全称 Remote Transmission Request BIT。占 1 个比特位。在DATA FRAME中,RTR BIT 必须是显性电平。 在REMOTE FRAME内RTR BIT必须是隐性电平。

  • 扩展格式
    扩展格式数据帧
    解释
    ARBITRATION FIELD由 29 个比特位的IDENTIFIER,1 个比特位的 SRR-Bit,1 个比特位的 IDE-Bit和 1 个比特位的RTR-BIT组成。 IDENTIFIER 位表示为ID28 ~ ID0。
  • IDENTIFIER:由 29 个比特位组成。格式包括两部分:
    • Base ID: 由 11 个比特位组成。 它按照从 ID28 ~ ID18 的顺序传输。 它等同于标准标识符的格式。 Base ID 定义扩展帧的基本优先级。
    • Extended ID: 由 18 个比特位组成。 它以 ID17 ~ ID0 的顺序发送。
  • SRR BIT: 全称 Substitute Remote Request BIT。占 1 个比特位隐性电平。此位的位置正好对应于标准格式的 RTR-BIT。对于数据帧,标准格式的 RTR-BIT 位为显性电平 。因此,标准格式的帧优先级高于扩展格式的帧(仲裁机制)!
  • IDE BIT: 全称 Identifier Extension BIT。相对于标准格式的帧,该位正好对应于原来的 Control Field 的 第 1 个保留位。标准格式的 IDE 位传输为显性电平 (见下文说明),而在扩展格式中,IDE 位是隐性电平 。
  • RTR BIT: 全称 Remote Transmission Request BIT。占 1 个比特位。在 DATA FRAME 中,RTR BIT 必须是 显性电平。 在 REMOTE FRAME 内 RTR BIT 必须是 隐性电平。与标准格式相同!

控制域

由6个比特位组成
控制位
标准格式的帧包括 DATA LENGTH CODE,一个比特位的 IDE (必须为显性电平 ),以及一个比特位的保留位 r0。 扩展格式的帧包括 DATA LENGTH CODE 和 2 个比特位保留位 r1 和 r0。
保留位必须发送“显性”,但接收器在所有组合中接受“显性”和“隐性”位。

发送端规则(必须发显性0):要求所有当前兼容设备在发送时把保留位固定为 0,避免未定义用法流入网络、引发兼容性问题。这是“保守发送”的做法:现在没有定义的位,不要随便置 1。
接收端规则(接受 0 或 1):接收时不要因为保留位看到 1 就判错或丢帧,而是“宽松接收”。这样未来如果标准把这些位赋予新意义(可能为 1),老设备也不会立刻用“形式错误”打断总线。
这是典型的“发送要保守、接收要宽松”(Postel’s Law)原则,目的就是前向/后向兼容

DATA LENGTH CODE指示了数据域中字节数。4个比特位。
data length

数据域

数据,包含0~8个字节。MSB传输。

CRC域

由 CRC SEQUENCE 和 CRC DELIMITER 两者组成。共占 16 个比特位(15 + 1)。
CRC

  • CRC SEQUENCE: 多项式为 X15 + X14 + X10 + X8 + X7 + X4 + X3 + 1。计算范围:帧起始,仲裁字段,控制字段,数据字段(如果存在)
  • CRC DELIMITER:必须为一个比特位的隐性电平

应答域

2个比特位。ACK SLOT和ACK DELIMITER各占一个。
ACK-field

  • ACK SLOT: 发送器发送数据时,必须发送隐性电平。当接收器正确接收到数据(已经接收到匹配的 CRC SEQUENCE)后,接收器将 ACK SLOT 置为显性电平,将此情况报告给发送器
  • ACK DELIMITER:必须一直是1个比特的隐性电平。

帧结束

每个 DATA FRAME 和 REMOTE FRAME 由一个由 7 个比特位的隐性电平位组成的标志序列分隔。

远程帧

通过发送 REMOTE FRAME,需要数据的节点可以请求另一节点发送相应的 DATA FRAME。
通常,数据传输是在数据源节点(例如传感器)发出数据帧的情况下自主执行的。但是,目标节点也可以通过发送远程帧来从信息源请求数据。

remote-frame
REMOTE FRAME 也分为标准格式 和 扩展格式,两者的区别与 DATA FRAME 完全相同。
与 DATA FRAME 相反,REMOTE FRAME 的 RTR 位是 1 个比特位的隐性电平。 没有 DATA FIELD、CONTROL FIELD 中的 DATA LENGTH CODE 字段表示所请求的消息的数据长度(可以是0 ~ 8),而不是发送的数据长度。

错误帧

CAN 网络具有严格的错误诊断功能,该功能都是直接在 CAN 芯片中集成的,硬件直接处理整个过程。一旦错误被检测,正在传送的数据帧将会立即停止而待总线空闲时再次重发直至发送成功,该过程并不需要 CPU 的干涉除非错误累计该发送器退隐(Bus Off)。

在发送或者接收报文时,总线上的节点如果检测出了错误,那么该节点就会发送 ERROR FRAME,以通知总线上的其他节点。ERROR FRAME 由 Error Flag 和 Error Delimiter 两个不同的位域组成。长度为 6 ~ 12个比特位的显性电平或者是隐性电平。

错误节点状态
错误主动(Error Active)

  • 默认状态(上线即如此)
  • TEC/REC(发送/接收错误计数器)都小于128
  • 行为:检测到错误时可发送"主动错误标志"(6个显性位)强制中断当前帧;可正常参与仲裁与发送,不需要额外等待

错误被动(Error Passive)

  • 当TEC或REC ≥ 128时进入
  • 行为变化:
    • 检测到错误时只能发送"被动错误标志"(6个隐性位),自身无法强制拉低总线中断帧
    • 发送新帧前需要额外等待一段"挂起发送(Suspend Transmission)"隐性时间(常见为在帧间隔之后再等8个隐性位),以减少对总线的打扰
    • 仍然需要对正确帧发送ACK

总线关闭(Bus-Off)

  • 当TEC ≥ 256时进入Bus-Off,节点退出总线,不再发送/ACK
  • 恢复条件由协议栈/芯片策略决定(如等待足够多次空闲段或软件复位)

错误标志类型
主动错误标志(Active Error Flag)

  • 6个连续显性位(0)
  • 作用:利用"显性覆盖隐性"和"位填充规则(5同位后必须插反位)"制造非法比特模式,强制全网同时感知错误并中止正在传输的帧
  • 谁能发:仅"错误主动"状态的节点

被动错误标志(Passive Error Flag)

  • 6个连续隐性位(1)
  • 作用:仅表明"我检测到错误",但不拉低总线,不能保证形成非法模式,因此不能单独中断帧;需要有至少一个错误主动节点同时发主动错误标志才能真正打断
  • 谁会发:处于"错误被动"的节点

error frame

  • Error Flag: 是不同节点提供的错误标志(ERROR FLAG)的叠加。错误标志分为两种:
    • 主动错误标志(ACTIVE ERROR FLAG): 6 个比特位的显性电平,这将破坏“位填充”原则。由总线上错误状态为“主动错误”的出错的节点传送
    • 被动错误标志(PASSIVE ERROR FLAG):6个比特位的隐性电平,由总线上错误状态为“被动错误”的出错的节点传送
    • Error Delimiter:是错误界定符。8个比特位的隐性电平。在传输ERROR FLAG后,每个节点先发送1个比特位的隐性电平,然后监视总线,直到它检测到隐性电平之后(说明所有节点都完成了错误标志的发送),它开始传输剩余7个比特位的隐性电平。

过载帧

过载帧是用于接收单元通知其尚未完成接收准备的帧。
overload frame

  • OVERLOAD FRAME:6个比特的显性电平
  • OVERLOAD DELIMITER:8个比特的隐性电平

触发条件:

  1. 接收节点需要延迟下一个数据帧或远程帧的传输(内部条件)
  2. 在帧间空间(Interframe Space)的第一个或第二个比特位检测到显性电平
  3. 接收节点在最后一个帧的EOF(End Of Frame)或另一个过载帧的过载界定符后检测到显性电平

帧间间隔

DATA FRAME 和 REMOTE FRAME 与前面的帧(数据帧、远程帧、错误帧、过载帧)通过一个称为 INTERFRAME SPACING 的位字段分隔开。

interframe space

  • INTERMISSION: 3 个比特位的隐性电平。在 INTERMISSION 期间,不允许任何节点发起 DATA FRAME 或 REMOTE FRAME 传输。 唯一可做的就是发出 OVERLOAD 条件。
  • BUS IDLE: 可以是任意长度个比特位的隐性电平。总线被认为是空闲的时候,任何有东西要传输的节点都可以访问总线。如果在其他消息传输期间挂起了本消息,那么被挂起的消息必须在 INTERMISSION 的后一个比特位开始传输。总线上检测到的显性电平 的位可被解释为帧的起始。
  • SUSPEND TRANSMISSION: “错误被动”节点发送消息后,在开始发送另一条消息或识别总线空闲之前,b必须发送 8 个比特位的隐性电平。如果与此同时另一节点开始发送消息,则错误被动节点转换为接受模式。

错误类型

error-type