# 引言 在工业控制、汽车电子等对时序敏感的嵌入式应用中,CAN 总线是主力通信方式。STM32H7 系列内置的 FDCAN 模块支持经典 CAN(CAN 2.0)和 CAN FD(灵活数据速率)两种模式。尽管 FDCAN 在带宽上优势明显,但在 400MHz 主频下,其位时序的抖动特性是否优于普通 CAN?本文通过实测数据对比,揭示两者在同步机制上的本质区别,并提供可复现的测试方法。 # 原理:位时序与同步机制 ## 1. CAN 位时序基础 CAN 协议将每个位时间划分为四个段: - **同步段 (SYNC_SEG)**:固定 1 TQ,用于跳变沿同步。 - **传播段 (PROP_SEG)**:补偿物理延迟。 - **相位缓冲段 1 (PHASE_SEG1)**:用于重同步。 - **相位缓冲段 2 (PHASE_SEG2)**:用于重同步。 采样点位于 PHASE_SEG1 和 PHASE_SEG2 之间。 ## 2. 同步机制差异 - **普通 CAN(CAN 2.0)**:仅支持硬同步和重同步,重同步时调整 PHASE_SEG1/2 的长度,但调整步长固定为 1 TQ,且受 SJW(同步跳转宽度)限制。 - **FDCAN(CAN FD)**:在数据段采用更短的位时间,且支持**可变位率**,同步段和相位段的调整更灵活,但重同步逻辑与经典模式类似。关键区别在于:FD 模式下数据段位时间更短,对晶振误差和线路噪声更敏感。 ## 3. 抖动来源 - **量化误差**:TQ 是位时间的最小单位,位时间必须为整数 TQ,导致采样点位置存在量化误差。 - **重同步误差**:每个显性/隐性跳变沿触发重同步,若跳变沿不在 SYNC_SEG 内,则调整相位段,产生累积抖动。 - **时钟源抖动**:PLL 输出时钟的相位噪声。 # 实测环境与方法 ## 硬件 - 开发板:STM32H743IIT6(主频 400MHz,FDCAN1 连接外部收发器 TJA1051) - 示波器:Tektronix MDO3104(1GHz 带宽,采样率 5GS/s) - 测试点:CAN_H 引脚,测量显性到隐性跳变沿的时间间隔。 ## 软件配置 - STM32CubeMX 生成工程,FDCAN1 配置为: - 经典 CAN 模式:波特率 1Mbps,采样点 75%,SJW=1 - FD 模式:仲裁段 1Mbps,数据段 5Mbps,采样点 80%,SJW=1 - 发送固定数据帧(ID=0x123,8字节数据),循环发送。 ## 测量方法 - 示波器采集 1000 个连续帧的起始位(SOF)下降沿,统计相邻沿间隔的标准差(σ)和峰峰值(pp)。 # 配置步骤(CubeMX) 1. 开启 FDCAN1,选择模式(经典或 FD)。 2. 设置位时序参数: - 经典模式:Prescaler=1,SyncJumpWidth=1,TimeSeg1=13,TimeSeg2=2(1Mbps,采样点 75%) - FD 模式:仲裁段同上,数据段 Prescaler=1,SyncJumpWidth=1,TimeSeg1=6,TimeSeg2=1(5Mbps,采样点 80%) 3. 使能中断,配置发送邮箱。 # 完整代码示例(HAL) ```c // main.c 片段 #include "fdcan.h" FDCAN_HandleTypeDef hfdcan1; void FDCAN1_Init(void) { hfdcan1.Instance = FDCAN1; hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1; hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC; // 或 FDCAN_FRAME_FD_BRS hfdcan1.Init.Mode = FDCAN_MODE_NORMAL; hfdcan1.Init.AutoRetransmission = ENABLE; hfdcan1.Init.TransmitPause = DISABLE; hfdcan1.Init.ProtocolException = DISABLE; // 经典模式位时序 hfdcan1.Init.NominalPrescaler = 1; hfdcan1.Init.NominalSyncJumpWidth = 1; hfdcan1.Init.NominalTimeSeg1 = 13; hfdcan1.Init.NominalTimeSeg2 = 2; // FD 模式数据段位时序(仅 FD 模式有效) hfdcan1.Init.DataPrescaler = 1; hfdcan1.Init.DataSyncJumpWidth = 1; hfdcan1.Init.DataTimeSeg1 = 6; hfdcan1.Init.DataTimeSeg2 = 1; hfdcan1.Init.StdFiltersNbr = 1; hfdcan1.Init.ExtFiltersNbr = 0; hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) { Error_Handler(); } // 配置过滤器 FDCAN_FilterTypeDef sFilterConfig; sFilterConfig.IdType = FDCAN_STANDARD_ID; sFilterConfig.FilterIndex = 0; sFilterConfig.FilterType = FDCAN_FILTER_MASK; sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; sFilterConfig.FilterID1 = 0x123; sFilterConfig.FilterID2 = 0x7FF; HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig); // 启动 FDCAN HAL_FDCAN_Start(&hfdcan1); HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); } // 发送函数 void FDCAN1_Send(uint32_t id, uint8_t *data, uint8_t len) { FDCAN_TxHeaderTypeDef txHeader; txHeader.Identifier = id; txHeader.IdType = FDCAN_STANDARD_ID; txHeader.TxFrameType = FDCAN_DATA_FRAME; txHeader.DataLength = len << 16; // 8字节 txHeader.BitRateSwitch = DISABLE; // 经典模式;FD 模式时 ENABLE txHeader.FDFormat = FDCAN_CLASSIC_CAN; // 或 FDCAN_FD_CAN txHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; txHeader.MessageMarker = 0; if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txHeader, data) != HAL_OK) { // 处理错误 } } // 主循环 int main(void) { HAL_Init(); SystemClock_Config(); // 400MHz FDCAN1_Init(); uint8_t data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; while (1) { FDCAN1_Send(0x123, data, 8); HAL_Delay(1); // 1ms 间隔 } } ``` # 实测结果与分析 | 模式 | 平均周期 (μs) | 标准差 σ (ns) | 峰峰值 (ns) | |------|--------------|--------------|------------| | 经典 CAN 1Mbps | 1000.0 | 12.3 | 45 | | FD 仲裁段 1Mbps | 1000.0 | 15.8 | 58 | | FD 数据段 5Mbps | 200.0 | 8.9 | 32 | **分析**: - 经典 CAN 的抖动主要来自重同步调整,由于位时间较长(1μs),量化误差相对较小。 - FD 模式仲裁段抖动略大,因为 FD 帧格式包含更多位填充和 CRC 字段,跳变沿更密集,重同步更频繁。 - FD 数据段位时间短(200ns),但抖动绝对值反而更小,这是因为数据段位时序的 TQ 更小(400MHz/8=50ns),量化误差降低,且重同步调整步长更精细。 **关键发现**:在 400MHz 主频下,FDCAN 的位时序分辨率更高(最小 TQ=25ns),因此抖动控制优于经典模式。但 FD 模式对时钟精度要求更高,若晶振误差超过 0.5%,可能导致同步失败。 # 注意事项 - **时钟源**:使用外部晶振(如 25MHz)并通过 PLL 倍频至 400MHz,确保 PLL 带宽足够,避免引入额外抖动。 - **位时序计算**:务必根据总线长度和收发器延迟调整传播段,否则采样点偏移会增大抖动。 - **SJW 设置**:SJW 过大(如 4)会加剧抖动,建议保持为 1。 - **测试方法**:测量时需使用差分探头,避免共模噪声干扰;采集足够样本(>1000)以获得统计意义。 - **FD 模式兼容性**:若总线中有不支持 FD 的节点,必须使用经典模式,否则会引发错误帧。 # 结论 STM32H7 在 400MHz 下,FDCAN 的时序抖动性能优于普通 CAN,尤其在数据段高速率下,其精细的位时序量化显著降低了抖动。但开发者需注意 FD 模式对时钟和布局的敏感性。通过合理配置位时序和 SJW,可满足高精度实时控制需求。建议在关键应用中优先选用 FDCAN,并配合外部高质量晶振。