# STM32H7 400MHz 下 FDCAN 与 TSN 时间同步的硬件触发对齐实践 ## 1. 为什么需要硬件触发对齐? 在 TSN 网络中,时间同步由 gPTP(IEEE 802.1AS)协议维护,同步精度通常要求在亚微秒级。而 FDCAN(CAN FD)本身不具备硬件时间戳,仅依赖软件中断记录时间,会导致数百纳秒到微秒级的抖动。STM32H7 的 FDCAN 支持硬件时间戳(Timestamp)功能,但默认与系统时钟独立。若能将 FDCAN 的时基与 TSN 的全局时间(如通过外部 PHY 或交换机提供的 1PPS 信号)对齐,即可实现确定性通信。 硬件触发对齐的核心思想:利用 STM32H7 的 HRTIM(高分辨率定时器,分辨率 2.5ns @400MHz)或通用定时器,捕获外部 TSN 同步脉冲(如 1PPS),并产生触发事件,重置或校准 FDCAN 的时基计数器,使 FDCAN 时间戳与 TSN 全局时间同步。 ## 2. 硬件架构与原理 ### 2.1 信号链路 - **外部 TSN 同步源**:通常来自 TSN 交换机的 1PPS 输出(TTL 电平),或以太网 PHY 的 1PPS 信号。 - **STM32H7 输入捕获**:将 1PPS 接入定时器输入捕获通道(如 TIM1_CH1),或 HRTIM 的外部事件输入。 - **FDCAN 时基**:FDCAN 内核有一个 16 位自由运行计数器(FDCAN_TTTC),可配置为外部时钟源,并支持硬件复位/置位。 ### 2.2 同步机制 1. **捕获 1PPS 上升沿**:定时器捕获当前计数值,并产生中断或 DMA 请求。 2. **计算偏差**:将捕获值与预期值(基于上一次同步周期)比较,得到时钟偏移。 3. **硬件校准**:通过定时器的比较输出(OC)或 HRTIM 的触发输出,连接到 FDCAN 的 TTTS(Time Triggered Transmit Schedule)输入,强制 FDCAN 时基重置为预设值。 这样,每个 1PPS 周期,FDCAN 时基被精确对齐到 TSN 全局时间,误差仅取决于硬件传播延迟(<10ns)。 ## 3. 配置步骤(以 STM32H743 为例) ### 3.1 时钟配置 - 系统时钟:400MHz(PLL1)。 - 定时器时钟:TIM1 挂载在 APB2 上,频率为 400MHz(若 APB2 分频为 1)。 - FDCAN 时钟:FDCAN 内核时钟可选 PCLK1(通常 100MHz)或 PLL2 输出,建议使用独立 PLL 以隔离抖动。 ### 3.2 定时器配置(TIM1 输入捕获 + 输出比较) ```c // 初始化 TIM1 为输入捕获模式,捕获 1PPS 上升沿 TIM_HandleTypeDef htim1; htim1.Instance = TIM1; htim1.Init.Prescaler = 0; // 400MHz 计数 htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 0xFFFFFFFF; // 32位 HAL_TIM_IC_Init(&htim1); // 配置通道1为输入捕获,上升沿触发 TIM_IC_InitTypeDef sConfigIC; sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_IC_SELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; // 可增加滤波,但会增加延迟 HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); ``` ### 3.3 FDCAN 时基配置 FDCAN 支持外部触发复位时基。在 STM32H7 中,FDCAN 的 TTTS 输入可连接到定时器比较输出。 ```c // 使能 FDCAN 时间触发模式,并配置时基源 FDCAN_InitTypeDef hfdcan; hfdcan.Instance = FDCAN1; hfdcan.ClockDivider = FDCAN_CLOCK_DIV1; hfdcan.NominalPrescaler = 2; // 例如 100MHz -> 50MHz 时基 hfdcan.NominalTimeSeg1 = 13; hfdcan.NominalTimeSeg2 = 2; hfdcan.TTCM = FDCAN_TTCM_ENABLE; // 使能时间触发模式 hfdcan.TTOCF = FDCAN_TTOCF_TTSE; // 使能外部时间同步 HAL_FDCAN_Init(&hfdcan); ``` ### 3.4 硬件触发连接 在 STM32H7 中,TIM1 的 OC1 输出可以映射到 FDCAN 的 TTTS 输入(通过 SYSCFG 或直接连接)。具体需查阅参考手册,通常使用 TIM1_CH1 的 OC 输出,配置为 PWM 模式,在捕获到 1PPS 后,延迟固定周期输出一个脉冲。 ```c // 配置 TIM1 通道1为 PWM 模式,用于产生触发脉冲 TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 100; // 脉冲宽度,决定触发时刻 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1); HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1); ``` ### 3.5 中断处理与校准 在捕获中断中,计算偏差并调整 PWM 的脉冲宽度,以补偿时钟漂移。 ```c void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { static uint32_t last_capture = 0; uint32_t current_capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); uint32_t diff = current_capture - last_capture; last_capture = current_capture; // 期望周期为 1 秒(400MHz 计数),计算偏差 int32_t error = (int32_t)diff - 400000000; // 调整 PWM 脉冲宽度,例如减小脉冲宽度提前触发 __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, 100 - error/1000); } ``` ## 4. 完整代码示例(简化) ```c // main.c 核心部分 int main(void) { HAL_Init(); SystemClock_Config(); // 400MHz MX_GPIO_Init(); MX_TIM1_Init(); MX_FDCAN1_Init(); // 启动捕获和 PWM HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1); // 使能 FDCAN 并启动通信 HAL_FDCAN_Start(&hfdcan1); HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); while (1) { // 主循环处理其他任务 } } ``` ## 5. 注意事项与优化 - **硬件连接**:确保 1PPS 信号电平兼容(3.3V),必要时加电平转换。 - **滤波与延迟**:输入捕获滤波器会增加延迟,建议在噪声可控时关闭或设置最小滤波。 - **FDCAN 时基分辨率**:FDCAN 时基计数器频率不宜过高,否则 16 位计数器会快速溢出。建议配置为 1MHz~10MHz,并通过软件扩展。 - **同步周期**:1PPS 同步周期较长,中间漂移可能累积。可增加辅助同步(如每 10ms 同步一次)或使用更高频率的同步脉冲。 - **抖动分析**:使用逻辑分析仪测量实际触发时刻,确保误差在 ±50ns 内。若超出,检查中断响应时间,可改用 DMA 或硬件直接连接。 - **多 FDCAN 同步**:若使用多个 FDCAN,可共享同一触发信号,但需注意时基独立,需分别校准。 ## 6. 总结 通过硬件触发对齐,STM32H7 的 FDCAN 能够与 TSN 网络实现亚微秒级同步,满足工业控制等高精度场景。本文的方法利用了定时器的捕获与比较功能,避免了软件中断的抖动,为异构网络融合提供了可靠方案。开发者可根据实际系统需求调整同步周期和校准算法,进一步优化性能。