CAN FD 基础:与传统 CAN 的区别与兼容性解析
👁 8 阅读 · 2026-08-20 · 嵌入式 CAN
CAN FD(CAN with Flexible Data-rate)是传统 CAN 2.0 协议的扩展,旨在突破带宽瓶颈,满足现代汽车和工业应用对高速、大数据量传输的需求。本文面向嵌入式开发者,深入剖析 CAN FD 与传统 CAN 在帧格式、仲裁机制、数据场长度及位速率上的核心差异,并重点讨论两者在同一总线上的兼容策略、配置要点及实际代码示例,帮助你在现有系统中平滑迁移或混合部署。
## 引言
随着自动驾驶、实时控制和高带宽传感器网络的普及,传统 CAN(2.0A/B)最高 1 Mbps 的速率和 8 字节数据场已捉襟见肘。CAN FD 应运而生,它在保留 CAN 物理层和仲裁机制的基础上,将数据段速率提升至 8 Mbps 以上,数据场长度扩展到 64 字节。然而,CAN FD 并非完全颠覆,它与传统 CAN 共存于同一总线时需谨慎设计。本文将从帧结构、位时序、兼容性策略和代码实现四个维度展开。
## 一、CAN FD 与传统 CAN 的核心区别
### 1. 帧格式差异
- **控制场**:传统 CAN 中,DLC(数据长度码)仅用 4 位表示 0-8 字节;CAN FD 扩展了 DLC 编码,支持 0-64 字节(但 9-15 映射为 12、16、20、24、32、48、64)。
- **FDF 位**:CAN FD 帧在控制场中新增 FDF(FD Format)位(隐性),用于区分传统 CAN 帧(显性)和 FD 帧。
- **BRS 位**:CAN FD 帧中新增 BRS(Bit Rate Switch)位,若为隐性,则数据段切换到更高位速率;若为显性,则全程保持仲裁段速率。
- **ESI 位**:错误状态指示位,用于标识发送节点是否处于错误被动状态。
- **CRC 场**:CAN FD 使用 17 位或 21 位 CRC(取决于数据长度),并引入位填充保护,提高错误检测能力。
### 2. 位速率与数据长度
| 特性 | 传统 CAN | CAN FD |
|------|----------|--------|
| 最大数据速率 | 1 Mbps | 8 Mbps(数据段) |
| 最大数据长度 | 8 字节 | 64 字节 |
| 仲裁段速率 | 固定 | 与仲裁段相同(通常 ≤1 Mbps) |
| 数据段速率 | 固定 | 可切换(如 2-8 Mbps) |
### 3. 位时序与同步
CAN FD 在数据段使用更短的位时间,因此对振荡器精度和采样点要求更高。传统 CAN 的位时序配置(如 SJW、采样点)通常可复用,但数据段需独立配置,且推荐采样点设置在 70%-80% 之间,以容忍边沿相位误差。
## 二、CAN FD 与传统 CAN 的兼容性
### 1. 物理层兼容
CAN FD 完全沿用传统 CAN 的物理层(ISO 11898-2),因此收发器(如 TJA1044)可直接使用。但注意:高速数据段要求收发器支持更高的转换速率(如 TJA1057 等 CAN FD 专用收发器)。
### 2. 协议层兼容
- **混合总线**:CAN FD 节点与传统 CAN 节点可共存于同一总线,但传统 CAN 节点无法理解 FD 帧,会将其视为错误帧并触发错误处理。因此,混合网络中必须确保 FD 帧只发送给支持 FD 的节点,或使用网关隔离。
- **帧类型识别**:CAN FD 节点必须能识别传统 CAN 帧(FDF=0),并正常接收;传统 CAN 节点收到 FD 帧(FDF=1)时,会因格式错误而报错,但不会影响总线(错误帧会破坏 FD 帧,导致重传)。
- **仲裁机制**:CAN FD 在仲裁段仍使用传统 CAN 的 CSMA/CA 机制,因此与传统 CAN 帧的优先级仲裁完全一致。
### 3. 配置注意事项
- **采样点**:仲裁段采样点建议与传统 CAN 一致(如 75%),数据段采样点可稍后(如 80%),但需根据总线长度和波特率调整。
- **位速率切换**:BRS 位必须在数据段开始前设置,且数据段速率必须高于仲裁段,否则无意义。
- **错误处理**:CAN FD 的错误计数器规则与传统 CAN 相同,但错误帧的位模式略有差异,需确保控制器固件正确实现。
## 三、配置步骤与代码示例
以 STM32H7 系列(内置 FDCAN 外设)为例,演示如何配置 CAN FD 并发送一帧数据。
### 1. 初始化时钟与引脚
```c
// 使能 FDCAN1 时钟和 GPIO 时钟
__HAL_RCC_FDCAN1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; // RX, TX
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
```
### 2. 配置 FDCAN 参数
```c
FDCAN_HandleTypeDef hfdcan1;
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS; // 允许 BRS
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = DISABLE;
// 仲裁段位时序:500 kbps,采样点 75%
hfdcan1.Init.NominalPrescaler = 4;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 13;
hfdcan1.Init.NominalTimeSeg2 = 2;
// 数据段位时序:2 Mbps,采样点 75%
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 13;
hfdcan1.Init.DataTimeSeg2 = 2;
HAL_FDCAN_Init(&hfdcan1);
```
### 3. 发送 CAN FD 帧
```c
FDCAN_TxHeaderTypeDef txHeader;
uint8_t txData[64] = {0};
// 填充数据
for (int i = 0; i < 64; i++) txData[i] = i;
txHeader.Identifier = 0x123;
txHeader.IdType = FDCAN_STANDARD_ID;
txHeader.TxFrameType = FDCAN_DATA_FRAME;
txHeader.DataLength = FDCAN_DLC_BYTES_64; // 64 字节
txHeader.FDFormat = FDCAN_FD_CAN; // FD 帧
txHeader.BitRateSwitch = FDCAN_BRS_ON; // 启用 BRS
txHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
txHeader.BitRateSwitch = FDCAN_BRS_ON;
HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txHeader, txData);
```
### 4. 接收配置(混合模式)
```c
// 启用过滤器,接受所有帧(包括传统 CAN 和 FD)
FDCAN_FilterTypeDef filter;
filter.IdType = FDCAN_STANDARD_ID;
filter.FilterIndex = 0;
filter.FilterType = FDCAN_FILTER_MASK;
filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
filter.FilterID1 = 0;
filter.FilterID2 = 0;
HAL_FDCAN_ConfigFilter(&hfdcan1, &filter);
// 启动接收中断
HAL_FDCAN_Start(&hfdcan1);
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
```
## 四、注意事项与常见陷阱
- **位速率切换的时序**:BRS 位在仲裁段结束后立即切换,因此数据段的位时序必须精确配置,否则会因采样点偏移导致错误。建议使用逻辑分析仪验证实际波形。
- **与传统 CAN 节点共存**:若总线上存在传统 CAN 节点,则所有 FD 帧必须发送到支持 FD 的节点,否则传统节点会触发错误帧,导致 FD 帧重传,降低效率。
- **CRC 计算差异**:CAN FD 的 CRC 算法与传统不同,且对于超过 16 字节的数据使用 21 位 CRC,因此软件实现时需注意。
- **收发器选型**:高速数据段要求收发器支持快速转换(如 TJA1057),普通 CAN 收发器可能无法满足,导致信号完整性下降。
- **兼容性测试**:在混合网络中,建议先以传统 CAN 模式运行,再逐步启用 FD 功能,并监控错误计数器。
## 结语
CAN FD 在保留传统 CAN 可靠性的同时,显著提升了带宽和效率,是下一代车载网络的重要基础。理解其帧结构差异和兼容策略,是嵌入式开发者顺利迁移的关键。通过合理配置位时序和收发器,你可以在现有系统中无缝引入 CAN FD,或构建混合网络,实现平滑过渡。