CAN 2.0 与 CAN-FD:从经典到灵活
说实话,我刚入行那会儿,CAN 总线就是铁律。8 个字节的数据场,1Mbps 的速率,谁也别想多传。后来上了个新项目,ECU 要刷写大固件,那叫一个痛苦——一个报文拆成几十帧,总线被塞得满满当当。直到 CAN-FD 出现,我才松了口气。
CAN-FD 不是推翻重来,它保留了 CAN 2.0 的物理层和仲裁机制。说白了,它只是在数据段做了两件事:提速和扩容。下面这张图能帮你快速建立整体认知。
报文格式:ID、DLC 与 Data Field
先看 CAN 2.0 的经典格式。一个标准数据帧,开头是 11 位 ID,后面跟着控制段、数据段、CRC 和应答。ID 决定了这条报文在总线上的优先级——数字越小,优先级越高。
CAN-FD 的帧结构基本一样,但有两个关键变化:
- DLC 编码变了:CAN 2.0 的 DLC 只能编码 0~8,CAN-FD 用 4 位 DLC 编码了 0~8、12、16、20、24、32、48、64 共 12 种长度。我刚开始用的时候,老记混这个映射表。
- Data Field 最大 64 字节:这是最直观的升级。以前传一个 50 字节的刷写块,得拆 7 帧;现在一帧搞定,总线负载直接降一半。
| 特性 | CAN 2.0 | CAN-FD |
|---|---|---|
| ID 长度 | 11 位(标准)/ 29 位(扩展) | 同左 |
| DLC 编码 | 0~8 字节 | 0~8, 12, 16, 20, 24, 32, 48, 64 字节 |
| 数据场最大 | 8 字节 | 64 字节 |
| CRC 长度 | 15 位 | 17 位(≤16 字节)/ 21 位(>16 字节) |
| 位填充 | 全帧(SOF~CRC 段) | 仅仲裁段,数据段取消填充 |
位填充机制:为什么 CAN-FD 要改这个?
位填充是 CAN 总线保证时钟同步的老规矩。连续 5 个相同电平后,发送方自动插入一个反向位。接收方收到后把它丢掉,恢复原始数据。
CAN 2.0 对整个帧(从 SOF 到 CRC 段)都做位填充。这在 1Mbps 下没问题,但 CAN-FD 的数据段跑到 5Mbps 甚至更高时,问题就来了——填充位太多,有效带宽被吃掉不少。
所以 CAN-FD 做了个聪明的决定:数据段取消位填充。仲裁段还是 1Mbps,保留填充;数据段提速后,用 NRZ 编码直接传,不再插填充位。这样一来,有效数据率提升了 20%~30%。
仲裁机制:我踩过的坑
仲裁是 CAN 总线的灵魂。多个节点同时发送时,谁先发 0(显性电平),谁就赢。这个机制在 CAN 2.0 和 CAN-FD 里完全一样。
但实际项目中,我遇到过两个典型问题:
- ID 分配不合理:有个项目,动力 CAN 上挂了 30 多个节点,ID 从 0x100 到 0x7FF 乱排。结果高优先级报文(比如扭矩请求)被低优先级报文堵住,导致响应延迟。后来我重新规划了 ID 分区:0x000~0x1FF 给实时控制,0x200~0x3FF 给诊断,0x400 以上给信息类。仲裁冲突明显减少。
- CAN-FD 混合仲裁:CAN-FD 和 CAN 2.0 节点混跑时,仲裁规则不变。但 CAN-FD 节点发送 FD 帧时,会在控制段发一个 EDL 位(显性),告诉其他节点“这是 FD 帧”。如果 CAN 2.0 节点不认识这个位,就会报错。所以混跑时,必须确保所有节点都支持 CAN-FD 的帧格式识别。
实际项目中的仲裁机制问题
仲裁机制本身不复杂,但组合上 CAN-FD 的速率切换后,容易出幺蛾子。我总结了几条经验:
- 速率切换点要留余量:CAN-FD 从仲裁段切换到数据段时,有个 BRS 位。如果切换点设置得太靠近帧头,接收方可能来不及同步。我一般留 2~3 个位的余量。
- 终端电阻别省:高速 CAN-FD 对信号反射更敏感。标准 120Ω 终端电阻是底线,别为了省成本用 100Ω 或 150Ω。
- 仿真工具要跟上:老旧的 CAN 分析仪不支持 CAN-FD 的位填充变化,抓出来的数据全是乱码。我建议团队统一用支持 CAN-FD 的硬件,比如 PCAN-USB FD 或 Kvaser 的 FD 系列。
嗯,CAN 和 CAN-FD 的核心差异就这些。仲裁机制是 CAN 的基石,不管速率怎么变,这个规则不会动。你只要记住:ID 是王道,填充是细节,硬件是底线。下次调试时,按这个顺序排查,能省不少时间。