CAN FD 基础回顾:从 CAN 2.0 到 CAN FD 的进化
各位同学,咱们开始第一讲。说实话,CAN FD 这个概念在汽车电子圈里已经火了好几年了。我最早接触它是在 2016 年做的一个车载网关项目,当时被客户要求支持 CAN FD,我还觉得「这玩意儿跟普通 CAN 有啥区别?」结果一上手才发现,坑还真不少。
这一章咱们先把地基打牢。我会从 CAN 2.0 和 CAN FD 的区别讲起,再到帧结构、速率提升原理,最后看看 STM32 的 CAN FD 外设长什么样。嗯,都是干货,没有废话。
1.1 CAN 2.0 与 CAN FD:到底差在哪?
先问大家一个问题:为什么要有 CAN FD?
传统 CAN 2.0 的带宽只有 1 Mbps,数据场最多 8 个字节。这在十年前够用,但现在一辆车上有几十个 ECU,OTA 升级、ADAS 数据、高精度地图……8 个字节?根本不够塞牙缝的。
CAN FD(Flexible Data-Rate)就是在这样的背景下诞生的。它保留了 CAN 2.0 的物理层和总线仲裁机制,但在数据段做了两件事:提速和扩容。
| 对比项 | CAN 2.0 | CAN FD |
|---|---|---|
| 最大数据场长度 | 8 字节 | 64 字节 |
| 最大速率(数据段) | 1 Mbps | 8 Mbps(实际常用 2~5 Mbps) |
| 帧格式 | 标准帧 / 扩展帧 | 兼容 CAN 2.0,新增 FDF 标志位 |
| CRC 校验 | 15 位 CRC | 17 位 / 21 位 CRC(根据数据长度) |
| 总线仲裁 | 逐位仲裁 | 相同(仲裁段速率不变) |
| 向后兼容 | — | CAN FD 节点可与 CAN 2.0 节点共存 |
核心要点:CAN FD 不是推翻重来,而是在 CAN 2.0 的基础上做了「局部加速」和「数据扩容」。仲裁段仍然用原来的速率,只有数据段才切换到高速模式。这样做的好处是——总线仲裁逻辑不变,现有 CAN 控制器可以低成本升级。
1.2 CAN FD 帧结构:多出来的那些位
咱们来看看 CAN FD 的帧长什么样。我习惯把 CAN FD 帧分成三段:仲裁段、控制段、数据段。
跟 CAN 2.0 相比,CAN FD 在控制段里多了几个关键位:
- FDF 位(Flexible Data Format):这是 CAN FD 的「身份证」。FDF = 1 表示这是一个 CAN FD 帧,CAN 2.0 控制器看到这个位会直接报错。
- BRS 位(Bit Rate Switch):速率切换开关。BRS = 1 时,从 BRS 位之后的数据段切换到高速模式;BRS = 0 则全程用仲裁段速率。
- ESI 位(Error State Indicator):发送节点的错误状态指示。主动错误节点发 0,被动错误节点发 1。
- DLC 编码变化:CAN FD 的 DLC 从 0~8 映射到数据长度 0~64 字节,具体映射表后面会讲。
我给大家画了一张帧结构对比图,一看就明白:
我的经验:刚开始用 CAN FD 时,我总搞混 BRS 位的作用。记住一句话——BRS 位是「油门」,踩下去(=1)数据段就加速,松掉(=0)就按原速跑。但要注意,BRS 位本身是用仲裁段速率传输的,所以接收端必须在 BRS 位之后立即切换采样点。
1.3 数据段速率提升原理:为什么能跑那么快?
好,接下来是重点。CAN FD 的数据段速率为什么能提升到 5 Mbps 甚至更高?
说白了,就两个原因:缩短位时间和优化采样点。
在仲裁段,所有节点必须同步采样,因为要逐位仲裁。这时候位时间不能太短,否则传播延迟会导致仲裁失败。CAN 2.0 的位时间通常设在 1 µs(1 Mbps),再快就危险了。
但进入数据段后,仲裁已经结束,总线上只有一个节点在发送。这时候就没有「多节点同步」的压力了。我们可以把位时间缩短到 200 ns(5 Mbps)甚至 125 ns(8 Mbps)。
不过,这里有个陷阱——采样点位置。高速模式下,位时间变短,采样点的精度要求更高。我见过一个项目,CAN FD 在 4 Mbps 下跑得好好的,换了一批发动机 ECU 就疯狂报错。查了半天,发现是采样点偏移了 5%。
⚠️ 避坑指南:我曾经在一个车载项目中,把 CAN FD 数据段速率设到 8 Mbps,结果发现线束稍微长一点(超过 1 米)就丢帧。后来老老实实降到 4 Mbps,配合 70% 采样点,稳如老狗。记住:速率越高,对线束、终端电阻、PCB 走线的要求越苛刻。
下面这张图展示了 CAN FD 的速率切换过程:
1.4 STM32 CAN FD 外设概述
好了,理论讲完了,咱们来看看 STM32 是怎么实现 CAN FD 的。
STM32 的 CAN FD 外设,在 FDCAN 系列(比如 STM32H7、G4、L5 等)中集成。它基于 Bosch M_CAN 内核,支持 CAN FD 规范 ISO 11898-1:2015。
我个人觉得 STM32 的 FDCAN 外设有几个亮点:
- 双时钟域:一个时钟给仲裁段(通常 40~80 MHz),另一个给数据段(最高 80 MHz),方便独立配置速率。
- 64 字节专用 RAM:用于消息 RAM,支持最多 32 个 Rx FIFO 和 32 个 Tx 缓冲。
- 硬件时间戳:每个接收帧自动打上时间戳,精度可达 10 ns。我在做 CAN FD 数据记录时特别喜欢这个功能。
- 低功耗模式:支持 Sleep、Standby 和 Wake-up,这也是咱们后面课程的重点。
下面是一个典型的 STM32 FDCAN 初始化代码片段,我习惯用 HAL 库:
/* FDCAN 初始化配置 */
FDCAN_HandleTypeDef hfdcan1;
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS; // CAN FD 帧,带 BRS
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
/* 仲裁段:1 Mbps */
hfdcan1.Init.NominalPrescaler = 2;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 13;
hfdcan1.Init.NominalTimeSeg2 = 2;
/* 数据段:4 Mbps */
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 9;
hfdcan1.Init.DataTimeSeg2 = 2;
HAL_FDCAN_Init(&hfdcan1);
小提示:配置数据段速率时,别忘了检查 STM32 的 FDCAN 时钟源。我遇到过有人把 FDCAN 时钟配成 40 MHz,却想跑 8 Mbps 数据段——位时间只有 5 个时钟周期,根本不够用。一般建议数据段位时间至少 8~10 个时钟周期。
1.5 本章小结
咱们这一章把 CAN FD 的基础过了一遍。总结几个关键点:
- CAN FD 是 CAN 2.0 的升级版,核心改进是数据段提速和数据场扩容。
- 帧结构多了 FDF、BRS、ESI 三个控制位,理解它们的作用是配置 CAN FD 的前提。
- 速率提升的原理是「仲裁后加速」,但采样点配置和线束质量是瓶颈。
- STM32 的 FDCAN 外设功能强大,双时钟域和硬件时间戳是亮点。