STM32 定时器(主从模式实现 3路PWM相位差)
⚙️ 一、实现原理
- 核心机制
- 主定时器生成基准PWM信号,将其OCxRef(通道原始PWM信号)作为触发输出(TRGO)。
- 从定时器以TRGO为触发源,通过设置不同的计数器初值实现相位偏移。
- 相位差公式:
相位差角度 = (延迟时间 / PWM周期) × 360° 延迟时间 = 从定时器计数器初值 / 时钟频率
类比:主定时器是乐队指挥(统一节奏),从定时器是乐手(按指挥信号分时段演奏)。
🔧 二、硬件配置(以TIM1为主,TIM2/TIM3/TIM4为从)
1. 主定时器(TIM1)配置
// 1. 时基单元:72MHz时钟 → 1kHz PWM(周期1ms)
TIM_TimeBaseInitTypeDef tb;
tb.TIM_Period = 1000 - 1; // ARR=999
tb.TIM_Prescaler = 72 - 1; // 72MHz→1MHz
tb.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &tb);// 2. 通道1输出PWM(占空比50%)
TIM_OCInitTypeDef oc;
oc.TIM_OCMode = TIM_OCMode_PWM1;
oc.TIM_Pulse = 500; // CCR1=500 → 50%占空比
oc.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1Init(TIM1, &oc);// 3. 关键!将OC1Ref设为TRGO源
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC1Ref);
TIM_CtrlPWMOutputs(TIM1, ENABLE); // 高级定时器需使能MOE
TIM_Cmd(TIM1, ENABLE); // 启动定时器
2. 从定时器配置(TIM2/TIM3/TIM4)
void SlaveTimer_Init(TIM_TypeDef* TIMx, uint16_t phase_delay) {// 1. 时基单元:与主定时器参数一致(同频同周期)TIM_TimeBaseInitTypeDef tb;tb.TIM_Period = 1000 - 1; // ARR=999tb.TIM_Prescaler = 72 - 1; // 1MHz时钟tb.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIMx, &tb);// 2. 配置为门控模式(Gated Mode)TIM_SelectSlaveMode(TIMx, TIM_SlaveMode_Gated); // TRGO有效时计数TIM_SelectInputTrigger(TIMx, TIM_TS_ITR0); // TIM1的TRGO映射到ITR0// 3. 设置相位延迟(核心!)TIM_SetCounter(TIMx, phase_delay); // 计数器初值=延迟时间对应的计数值// 4. 通道1输出PWM(占空比可独立设置)TIM_OCInitTypeDef oc;oc.TIM_OCMode = TIM_OCMode_PWM1;oc.TIM_Pulse = 300; // 占空比30%(可独立调整)oc.TIM_OutputState = TIM_OutputState_Enable;TIM_OC1Init(TIMx, &oc);TIM_Cmd(TIMx, ENABLE);
}// 初始化三个从定时器(相位差120°)
SlaveTimer_Init(TIM2, 0); // 0°延迟 → 相位0°
SlaveTimer_Init(TIM3, 333); // 333计数值 → 120°延迟(1000/3≈333)
SlaveTimer_Init(TIM4, 666); // 666计数值 → 240°延迟
关键点:
TIM_TS_ITR0
是TIM1→TIM2的固定内部触发线路(其他定时器需查手册映射)。- 相位差计算:120°延迟 = (120/360)×1000 ≈ 333计数值(1MHz时钟下每计数值=1μs)。
⚡ 三、工作流程
- 主定时器通道1输出PWM,其上升沿触发
OC1Ref
信号 → 作为TRGO输出。 - 从定时器在TRGO有效时开始计数:
TIM2
从0开始计数 → 相位0°。TIM3
从333开始计数 → 延迟333μs(120°相位差)。TIM4
从666开始计数 → 延迟666μs(240°相位差)。
- 各从定时器独立生成PWM,频率/占空比可独立调整。
📊 四、相位差验证(示波器观测)
信号 | 引脚 | 相位差 | 波形特征 |
---|---|---|---|
主PWM (TIM1) | PA8 | 基准0° | 占空比50%,周期1ms |
从PWM1 (TIM2) | PA0 | 0° | 与主PWM完全同步 |
从PWM2 (TIM3) | PA6 | 120° | 波形滞后主PWM 333μs |
从PWM3 (TIM4) | PB6 | 240° | 波形滞后主PWM 666μs |
注:引脚需配置为复用推挽输出(
GPIO_Mode_AF_PP
)。
⚠️ 五、常见问题与优化
无输出问题
- 检查
TIM_CtrlPWMOutputs()
(高级定时器必需)。 - 确认GPIO模式为
GPIO_Mode_AF_PP
(非普通推挽输出)。
- 检查
相位误差
- 所有定时器预分频器(PSC)需相同,否则频率不一致。
- 减少中断干扰:关闭无用中断,或使用DMA传输数据。
动态调整相位
// 运行时修改TIM3相位为90° uint16_t new_delay = (1000 * 90) / 360; // 250计数值 TIM_SetCounter(TIM3, new_delay); // 需在TRGO间隙修改
💡 六、应用场景
- 三相电机驱动:120°相位差控制无刷电机换向。
- RGB调光:三路LED独立相位,避免同时开关导致的电流突变。
- 多路同步信号:通信系统中错开发送时序,减少干扰。
通过此方案,STM32仅用硬件触发实现纳秒级精度的相位控制,无需CPU实时干预,极大减轻系统负载。
总结:
- 核心:主定时器
OCxRef
触发从定时器 → 计数器初值决定相位差。 - 口诀:同频(PSC一致)、同源(TRGO触发)、初值调相位。
- 扩展:若需更多相位通道,可级联更多从定时器(如TIM5从TIM4触发)。