学习笔记之CAN/CANFD详解
本文为对于b站视频BV1TXn465ENv的学习笔记
原视频:Everything About CAN Bus | CAN Protocol Explained: Arbitration, Frames, CAN FD, STM32 & DBC
原作者:Inside Embedded | Polezero
发布日期:2026-10-20
视频链接:https://www.youtube.com/watch?v=aAR7xyTaXIo
1. CAN总线基础
只记录自己觉得没听说过的部分
1.1. 概述
车联网中分为中,低高速,之间用网关进行连接
1.1.1. 主要车载网络协议
| 名称 | 概要 | 最大速度 | 推动单位 |
|---|---|---|---|
| CAN | 车身控制用,LAN协议 | 1 Mbit/s | Bosch ISO11898 |
| LIN | 车身控制用,LAN协议 | 20 Kbit/s | LIN协议会 |
| FlexRay | 重视安全的,按用途划分的,LAN协议 | 10/20 Mbit/s | BMW |
| MOST | 信息通讯协议 | 22.5 Mbit/s | MOST合作组织 |
| IDB-C | 以CAN为基础的LAN协议 | 250 Kbit/s | IDM论坛 |
1.2. CAN节点
■一个节点内部由三个部分组成
- 处理数据的软件部分
- CanController
- 组帧,发送bit位,竞争CANBUS的使用权,故障检测
- CAN收发器
- 把逻辑信号和电压信号进行互相转换
■为了防止不同节点之间的电位有偏移导致只读一个电平时信息被误解,CAN采用读CAN H和L的差值来进行判断。使用差分信号也能够更好地消除噪声。
为什么0是显性,1是隐性?多个节点同时通信的情况
1.3. 终端电阻
在CAN总线的两端各有一个120Ω的电阻,这就是终端电阻。
终端电阻的作用:
- 防止信号反射
当信号到达线路末端,而末端又是开路时,信号会反射回来,与原始信号重叠。CAN通信使用的双绞线阻抗为120Ω,用120Ω的电阻可以将两端的CAN信号吸收掉。 - 帮助总线从显性位切换到隐性位时,让查分电压快速下降
在显性状态下,收发器会抬高CAN HIGH的电压,降低CAN LOW的电压
当从显性状态切换到隐性状态时,收发器会释放差分驱动,CANH和CANL的电压差通过终端电阻进行衰减,当电压差小到一定范围,接收端就识别到了隐性状态。
1.4. 显性和隐性的转换
CAN收发器中有一个偏置电路,CANH连接VCC,CANL连接GND。
■当收发器要发送显性电压时,开关会闭合(形成差分电压),使得CANH的电压拉高,CANL的电压降低,让两条CAN线产生电压差
■当收发器要发送隐性电压时,开关会断开(释放差分驱动),回路中的终端电阻会使得两条CAN线上的电压趋于一致
1.4.0.1. 多个节点同时通信的情况
当总线上任意节点送显性(0)bit时,那个节点的偏置电路会闭合,导致整条的CANH和CANL电压都会趋于一致,此时,即使别的节点在送1,总线上实际在传输的也是0。只有总线上所有节点都送1的时候总线上传输的才会是1,这就是线路中的与(&)特性。
1.4.1. 信号的反射问题
典型CAN收发器从显性切到隐性时,会导致总线上的阻抗急剧升高,如果布线阻抗不连续,或者分支线路较长,信号反射可能会引起电压波动。尤其是在CANFD高速传输时,电压波动对通信可靠性的影响更大
信号反射:信号感受到瞬态阻抗改变→部分反射,部分失真,继续传播
1.5. frame发送的优先级仲裁(非破坏性仲裁)
当CAN总线上的节点想要发送CAN frame,它们会直接开始送信,从SOF开始。CAN控制器在发送每一位时都会检测CAN总线上的数据是否与自己发送的一致,由于SOF位都是0,所以所有的CAN控制器都认为自己发送成功
接着它们一起发送frame ID的第一位,由于送的也都是0,所以它们发出的的CAN总线上的数据依然一致。
当有一个节点开始发送1,由于线与特性,总线上依然是0,那个发1的节点的CAN控制器会判断自己失去了仲裁权,立刻停止发送,然后切换到接收模式。
失去仲裁权的节点会在等到获得仲裁权的节点将一帧发送完毕,且总线空闲之后再次尝试发送
1.6. 帧结构
根据传统CAN帧的结构,一个数据帧总长为111bit,但是实际传输数据的部分只有最大8个byte(64bit), 数据传输效率其实不足60%,这种效率低下也是后来促使CANFD诞生的原因之一。
1.7. 故障处理
当发送节点检测到ACK故障,它会开始发送错误帧(6个0),这个错误帧由于全部由0组成,所以它可以破坏别的帧的结构,使得总线上其他节点检测到帧错误故障。这样是为了防止总线上一部分节点收到数据而另一部分没有收到的情况。
发完错误帧之后的CAN控制器会紧接着发错误分隔符(8个1),然后重新发送没有被收到的那一帧。
1.7.1. error counter
为了防止有控制器一直发送错误帧妨碍通信,CAN控制器用error counter管理自身状态。
当送信error时,TEC+8,当受信error时,REC通常+1
当送信成功时,TEC-1,当受信成功时,REC-1
1.7.2. error active和error passive
当CAN控制器处于error active状态,它送出的错误帧全部由0组成,这种错误帧会主动地破坏其他节点的通信
当CAN控制器处于error passive状态,它送出的错误帧全部由1组成,就不会破坏其他节点的通信了,并且在发送完一帧之后,需要等待8bit再进行发送。
当TEC>255,节点进入BUSOFF状态,并且不参与总线的任何活动,也不发任何消息。
1.7.3. error复归
由于正常数据帧都是以11个bit的1来结尾,所以想要BUSOFF的节点复归,就需要节点收到至少128次11个bit的1。
对于TEC=255引起的故障来说,是单个节点的故障,对于CAN线OPEN或者H/L短接的情况来说,是对于整个CAN线的瘫痪
1.7.4. NOACK时的TEC加算
当总线上只有一个节点,并且由于NOACK达到Error Passive状态,并且仍然NOACK时,TEC将不会增加。因为独自占据总线且未检测到ACK,并不意味着该节点有故障。
这个节点不会BUSOFF,会一直保持尝试送信的状态
1.8. Bit Timing
CAN没有时钟线,每个节点都必须预先配置成相同的波特率。
每个节点都用自己的时钟生成位时序。
当波特率被设置成500kbit/s那意味着每个bit的传输时间为2μs
但是CAN控制器会把时间切分成更小的单位时间量子(tq)
把一个bit分为20个tq,每个tq的时长为2μs / 20 = 100ns
在这20个tq中,可以分为四个segment:
- Sync同步段
通常情况下,信号边就发生在这个段里。信号的上升沿/下降沿
- Prop传播段
用于补偿信号在总线上往返传输的物理延迟 - Phase 1/2相位段1和2
用于决定采样点
CAN为什么要在位的后半部分采样?
为了仲裁。
对于位于CAN总线两端的节点A和节点B,在它们参与仲裁时,需要互相发信号再互相接收对方发过来的信号进行仲裁。
信号从节点A发到节点B,再从节点B回到节点A,这段时间叫做往返延迟。
采样点必须落在完整的往返延迟之后。只有这样,两个节点才能在同一个位时间内对比相同的总线电平。
波特率和总线长度之间的关系
波特率⬆️ 单个bit的时间⬇️
往返延迟由总线长度和收发器决定,是不变的
所以想要提高波特率又保证仲裁时的采样点准确的话,就必须减小往返延迟,缩短总线长度。
1.8.1. 波特率同步
CAN总线会在每个下降沿对各个节点进行同步
如果检测到边沿晚于预期,就延长相位段1(Segment phase 1)
如果检测到边沿早于预期,就缩短相位段2(Segment phase 2)
单次同步所能修正的最大tq数,称为同步跳转宽度(SJW)
CAN的填充位机制(每连续5个0就会填充一个1)不仅能用于判断帧结构,也帮助波特率同步提供了1→0的下降沿
2. CANFD
FD=FlexibleData-rate,代表数据阶段的比特率可以改变
2.1. CAN总线的局限性
- 每个帧最多只能传输8byte的数据,传输效率太低
- 最大传输速度只能到1 Mbit/s,不够快
CAN的往返延迟加仲裁机制也限制了CAN的通信速率
2.2. CANFD的做法
由于传统CAN中通信速率受到限制的地方只有在仲裁和ACK这样多个节点都要参与收发的时候
所以在仲裁和ACK阶段,CANFD会保持现有的波特率,来保证符合往返延迟的时间
在这两个时间段以外,就只有发送节点在发送了,就没有往返延迟这种情况了,CANFD会切换为更高的比特率进行发送。
比特率切换区间为BRS(比特率切换位)到CRC
2.3. CANFD的帧结构
经典CAN中的RTR位置变成了称为RRS的保留位
CANFD没有远程帧,所以这个位始终发送为0经典CAN中的r0位变成了FDF位
这个位上的隐性(1)表示这是一个CANFD帧FDF位后面多出了一个叫RES的保留位
BRS位后面多出了一个叫BRS的位
如果BRS=1,比特率将从该位的采样点开始切换到数据阶段速率BRS位后面多出了一个ESI位
用于表示发送节点是Error Active还是Error Passive状态
从ESI开始到后面的CRC为止,都用更高的比特率发送
2.3.1. DLC的算法
CANFD中DLC数据对应的实际byte数和传统CAN有区别
超过8byte长度的数据只能以对应的数据长度发送
2.3.2. CRC的算法
如果数据在16byte或以下,则使用17位CRC
如果超过16byte,则使用21位CRC
2.3.2.1. CRC的填充位去除算法
CANFD帧在CRC前面加入了新的SC(stuff count)位=填充计数位
保存了直到数据字段末尾为止插入的填充位的数量,对8取模
这个值以格雷码加一个校验位(parity bit)的形式发送
在传统CAN当中,当bit error发生在填充位附近时,CRC的计算有可能误判定一个bit是不是填充位,从而导致CRC计算出错(虽然这是极少数情况)
而在CANFD中CRC的计算直接包含填充位,并且ISO规定要将填充位数放在帧里发送,让接收方执行额外的填充位检查(填充位数要求参照ISO11898-1:2015)
■在SC位+CRC位这一段中,还会在每4个bit的固定位置插入一个填充位
2.4. CANFD的波特率
CANFD的控制器中有两种时序
- 用于仲裁阶段的名义位时序NBTP(Normal Bit Timing)
- 用于数据阶段的数据位时序DBTP(Data Bit Timing)
对于仲裁阶段和数据阶段,保持tq长度不变,通过给每个bit分配不同数量的tq来控制传输速率的快慢。
2.4.1. 回环延迟导致的波特率限制问题
2.4.1.1. 问题介绍
CAN总线传输中,CAN控制器从Tx端口输出bit,送到总线,再从Rx端口收回bit跟送出去的bit进行比较,这个流程执行需要的时间称为回环延迟。
CANFD的收发器允许的回环延迟最高为255ns,也就是说,从bit的Sync Segment到采样点Sample Point,至少需要255ns的时间。
但是5Mbit/s的速率下,每个bit的传输时间只有200ns,时间根本不够
在2Mbit/s的速率下,80%采样率的情况下,也只比255ns多了145ns的容错时间
如果在CANFD回路中增加数字隔离器或者电平转换器,这个回环延迟的时间还会增大,145ns的容错也是不够用的。
2.4.1.2. CANFD的解决办法
CANFD控制器有一项名为发送器延迟补偿(TDC)的功能
控制器利用FDF位和RES位之间的边沿来测量实际的回环延迟
在传送数据bit的阶段,控制器会在一个次级采样点(Secondary Sample Point)检查发送的位
次级采样点的设置是由1中测量得到的实际回环延迟+一个偏移量计算得到
只有发送节点的控制器会进行延迟补偿的检测,受信节点不会。
当数据阶段的比特率设置超过1Mbit/s时,通常会启用此功能。
2.5. CANFD注意事项
- 如果CANFD总线上接入了一个传统CAN节点,它会把CANFD帧当成帧错误,而进入error active状态,往CANFD总线上发送错误帧,从而毁了整个总线。
所以CANFD总线上的每个节点都要支持CANFD,至少收到CANFD帧的时候不能往总线上发错误信息。 - 但是CANFD控制器是兼容传统CAN帧的。
- 国际标准ISO11898-1:2024提供了一种更长的CANXL标准,支持最长数据2048字节