## 引言 随着自动驾驶、实时控制和高带宽传感器网络的普及,传统 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,或构建混合网络,实现平滑过渡。