You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 TIM1与TIM2带相位差PWM重启后TIM2占空比异常问题

问题分析与解决方案

问题背景

基于STM32内部触发系统实现两路带相位差的PWM:

  • TIM1 CH1 输出PWM,TIM1 CH2 作为无输出比较通道(用于触发TIM2)
  • TIM2 CH1 输出PWM
  • 通过UART接收C#端指令0x50开启PWM、0x51关闭PWM

当前启停代码:
启动逻辑:

HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

停止逻辑:

HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);

异常现象:首次启动、首次停止均正常,再次启动时TIM1 PWM输出正常,但TIM2 PWM以100%占空比输出。


核心原因及解决办法

1. TIM2的CCR寄存器值在停止后丢失

HAL_TIM_PWM_Stop()在关闭通道时,可能会重置比较寄存器(CCR)的值,或者TIM2作为从设备,停止后计数器状态异常导致CCR未正确加载预期值。

修复代码:每次启动TIM2前,强制写入目标占空比对应的CCR值:

// 替换原启动代码中的HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, YOUR_TARGET_CCR_VALUE);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

2. TIM2从模式同步未重置

如果TIM2是由TIM1 CH2触发(如触发源为TIM_TRGO_OC2REF),停止TIM1 OC通道后,TIM2计数器可能处于非复位状态,再次启动时无法同步到TIM1的触发信号,导致计数器溢出异常,最终出现100%占空比(CCR ≥ ARR)。

修复代码:启动前复位TIM2计数器并重新配置从模式:

// 复位TIM2计数器
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 重新加载从模式配置(sSlaveConfig为初始化时的从模式结构体)
HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig);
// 设置CCR值并启动PWM
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, YOUR_TARGET_CCR_VALUE);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

3. 绕过HAL库的启停逻辑,直接操作寄存器

部分HAL库版本中,HAL_TIM_PWM_Stop()会额外修改通道配置(如改为GPIO模式),导致再次启动时参数异常。可以直接操作寄存器实现启停,避免HAL的隐式操作。

替代停止代码:

// 关闭TIM1 CH1、CH2输出,停止计数器
TIM1->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC2E);
TIM1->CR1 &= ~TIM_CR1_CEN;
// 关闭TIM2 CH1输出,停止计数器
TIM2->CCER &= ~TIM_CCER_CC1E;
TIM2->CR1 &= ~TIM_CR1_CEN;

替代启动代码:

// 启动TIM1并开启输出
TIM1->CR1 |= TIM_CR1_CEN;
TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E;
// 复位TIM2计数器,设置CCR值,启动计数器并开启输出
TIM2->CNT = 0;
TIM2->CCR1 = YOUR_TARGET_CCR_VALUE;
TIM2->CR1 |= TIM_CR1_CEN;
TIM2->CCER |= TIM_CCER_CC1E;

4. 确认TIM2的ARR寄存器未被修改

停止后TIM2的自动重装载寄存器(ARR)可能被意外改写,导致CCR相对ARR的比例变为100%。启动前可重新设置ARR值:

__HAL_TIM_SET_AUTORELOAD(&htim2, YOUR_TARGET_ARR_VALUE);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, YOUR_TARGET_CCR_VALUE);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

内容的提问来源于stack exchange,提问作者Kaan Kurtça

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:30:33