# 基于STM32G4的HRTIM高分辨率定时器实现多路交错PWM的相位抖动抑制 ## 一、HRTIM与相位抖动问题概述 STM32G4的HRTIM(High-Resolution Timer)由多个子定时器(Timer A~F)组成,每个子定时器可独立生成PWM,且支持主从同步和外部事件触发。其核心优势在于采用延迟锁定环(DLL)技术,将时钟周期细分为多个相位,实现皮秒级分辨率。 在多路交错PWM应用中(如三相逆变器、多相Buck变换器),各通道需按固定相位差(如120°或360°/N)输出。理想情况下,相位差应恒定不变,但实际中常出现抖动(jitter),表现为脉冲边沿位置随机偏移,导致电流纹波增大、电磁干扰恶化。 **相位抖动的主要来源:** - 软件中断响应延迟:更新占空比时,若在中断中修改寄存器,调度延迟会直接反映为相位偏移。 - 定时器同步误差:多个子定时器虽可硬件同步,但若配置不当,启动时刻不一致。 - 死区插入不对称:死区生成逻辑在上升沿和下降沿的延迟可能不同。 - 电源噪声和温度漂移:影响DLL校准精度。 ## 二、硬件架构与同步机制 HRTIM的每个子定时器拥有独立的比较寄存器(CMPx)和周期寄存器(PERx),并支持以下同步方式: - **主从级联**:通过SYNC_OUT和SYNC_IN信号,一个定时器可作为主设备,触发其他从设备复位或启动。 - **外部事件同步**:支持外部信号(如GPIO)触发所有定时器同时复位。 - **DMA请求**:比较事件或更新事件可触发DMA传输,实现寄存器预装载。 对于多路交错PWM,推荐使用**主定时器(如Timer A)产生基准周期,其他定时器(Timer B~F)配置为从模式,通过SYNC信号复位**,从而保证所有通道的周期起点一致。 ## 三、相位抖动抑制策略 ### 1. 硬件同步启动,避免软件干预 所有子定时器在初始化时,通过设置`HRTIM_MCR_SYNC_IN`位,使能同步输入。然后在主定时器启动时,自动触发从定时器复位。这样,各通道的起始相位完全由硬件决定,消除软件启动延迟。 ### 2. 使用DMA预装载比较值 传统做法是在中断中更新CMPx寄存器,但中断延迟不可控。改为使用DMA:当更新事件发生时,DMA自动从内存搬运新的比较值到CMPx寄存器,整个过程无需CPU介入,且DMA传输由硬件时钟驱动,延迟固定。 ### 3. 优化死区配置 HRTIM支持可编程死区,且上升沿和下降沿可独立设置。为减小不对称,应确保上升沿延迟和下降沿延迟相等,并采用硬件死区而非软件插入。 ### 4. 校准DLL HRTIM内置DLL,需在初始化时调用`HAL_HRTIM_DLLCalibrationStart()`进行校准,并在运行中定期检查校准状态,防止温度漂移导致分辨率下降。 ## 四、代码实现:三相交错PWM(相位差120°) 以下示例使用Timer A、B、C生成三路PWM,频率100kHz,占空比50%,相位差120°。 ### 1. 初始化时钟和GPIO ```c // 使能HRTIM时钟和GPIO时钟 __HAL_RCC_HRTIM1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); // 配置PA8、PA9、PA10为HRTIM输出(需查手册复用功能) GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF13_HRTIM1; // 根据具体型号调整 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); ``` ### 2. HRTIM配置 ```c HRTIM_HandleTypeDef hrtim1; HRTIM_TimeBaseCfgTypeDef sTimeBaseCfg; HRTIM_TimerCfgTypeDef sTimerCfg; HRTIM_CompareCfgTypeDef sCompareCfg; // 使能HRTIM hrtim1.Instance = HRTIM1; HAL_HRTIM_Init(&hrtim1); // 配置主定时器A:周期100kHz(假设时钟170MHz,周期值=1700-1) sTimeBaseCfg.Period = 1700 - 1; sTimeBaseCfg.RepetitionCounter = 0; sTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_DIV1; sTimeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS; HAL_HRTIM_TimeBaseConfig(&hrtim1, HRTIM_TIMERINDEX_MASTER, &sTimeBaseCfg); // 配置从定时器B和C,使用同步复位 sTimerCfg.InterruptRequests = HRTIM_TIM_INTERRUPT_NONE; sTimerCfg.DMARequests = HRTIM_TIM_DMA_UPDATE; sTimerCfg.DMASrc = HRTIM_TIM_DMA_SRC_UPDATE; sTimerCfg.HalfMode = HRTIM_HALFMODE_DISABLED; sTimerCfg.StartSync = HRTIM_TIM_SYNC_START; // 由主定时器同步启动 HAL_HRTIM_TimerConfig(&hrtim1, HRTIM_TIMERINDEX_TIMER_B, &sTimerCfg); HAL_HRTIM_TimerConfig(&hrtim1, HRTIM_TIMERINDEX_TIMER_C, &sTimerCfg); // 配置比较值:A在50%处翻转,B在50%+120°处,C在50%+240°处 // 周期1700,50%为850,120°对应566.7,取整567 sCompareCfg.CompareValue = 850; HAL_HRTIM_CompareConfig(&hrtim1, HRTIM_TIMERINDEX_MASTER, HRTIM_COMPAREUNIT_1, &sCompareCfg); sCompareCfg.CompareValue = (850 + 567) % 1700; // 1417 HAL_HRTIM_CompareConfig(&hrtim1, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, &sCompareCfg); sCompareCfg.CompareValue = (850 + 1134) % 1700; // 284 HAL_HRTIM_CompareConfig(&hrtim1, HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_1, &sCompareCfg); // 配置输出:PWM模式1,高电平有效,死区关闭(简化) HRTIM_OutputCfgTypeDef sOutputCfg = {0}; sOutputCfg.Polarity = HRTIM_OUTPUTPOLARITY_HIGH; sOutputCfg.SetSource = HRTIM_OUTPUTSET_TIMCMP1; sOutputCfg.ResetSource = HRTIM_OUTPUTRESET_TIMPER; HAL_HRTIM_OutputConfig(&hrtim1, HRTIM_TIMERINDEX_MASTER, HRTIM_OUTPUT_1, &sOutputCfg); // 类似配置B和C的输出,略 ``` ### 3. 启动HRTIM和DMA ```c // 启动DMA传输(需预先定义数组存储比较值) // 假设dmaBuf[3] = {850, 1417, 284},每次更新事件自动加载 HAL_HRTIM_DMAStart(&hrtim1, HRTIM_TIMERINDEX_MASTER, HRTIM_DMA_UPDATE, (uint32_t*)dmaBuf, 3); // 启动主定时器,从定时器自动同步启动 HAL_HRTIM_WaveformCounterStart(&hrtim1, HRTIM_TIMERINDEX_MASTER); HAL_HRTIM_WaveformCounterStart(&hrtim1, HRTIM_TIMERINDEX_TIMER_B); HAL_HRTIM_WaveformCounterStart(&hrtim1, HRTIM_TIMERINDEX_TIMER_C); ``` ## 五、注意事项 - **同步启动顺序**:务必先配置从定时器的`StartSync`为`HRTIM_TIM_SYNC_START`,再启动主定时器,否则从定时器不会自动同步。 - **DMA缓冲区**:DMA传输的数据宽度需与寄存器匹配(32位),且缓冲区需在内存中保持有效。 - **死区设置**:若需死区,使用`HAL_HRTIM_DeadTimeConfig`,并确保上升沿和下降沿延迟一致。 - **DLL校准**:在初始化后调用`HAL_HRTIM_DLLCalibrationStart`,并等待校准完成标志,否则分辨率可能不达标。 - **中断优先级**:若仍需中断(如故障保护),应将其优先级设为最高,并避免在中断中执行耗时操作。 ## 六、总结 通过硬件同步和DMA预装载,可有效抑制多路交错PWM的相位抖动,充分发挥STM32G4 HRTIM的高分辨率优势。本文提供的代码框架可直接应用于数字电源或电机控制项目,开发者可根据实际需求调整通道数和相位差。