05:TIM输出比较进阶---PWM波形生成与多通道协同控制 1. PWM波形生成与多通道协同控制基础记得我第一次用STM32的PWM功能驱动LED时看着灯从暗到亮循环变化那种成就感至今难忘。但后来做机器人项目需要同时控制4个电机时才发现单路PWM根本不够用。这时候定时器的多通道协同功能就成了救命稻草。PWM的本质其实就像快速开关水龙头。假设1秒内开关100次每次打开0.3秒关闭0.7秒水流效果就等效于30%的开度。在STM32中CNT计数器就像秒表CCR寄存器就是设置0.3秒的开关点。当CNTCCR输出高电平反之低电平这就是PWM1模式。定时器的每个通道都有独立的CCR寄存器。以TIM2为例它有4个通道CH1-CH4意味着可以生成4路独立PWM。但更厉害的是这些通道可以协同工作。比如要让两路PWM相位差90度只需设置TIM2-CCR2 TIM2-ARR / 4; // CH2相位滞后1/4周期2. 多通道PWM的硬件协同机制去年做无人机电调控制时发现普通GPIO模拟的PWM会抖动而定时器硬件生成的波形稳如老狗。这是因为STM32的定时器有专门的协同逻辑主从定时器模式TIM1可以配置为主模式触发TIM2作为从定时器。我用这个功能实现了6路同步PWMTIM1-CR2 | TIM_CR2_MMS_1; // TIM1触发输出 TIM2-SMCR | TIM_SMCR_SMS_2; // TIM2从模式复位刹车与死区控制驱动三相电机时H桥上下管不能同时导通。高级定时器的BDTR寄存器可以自动插入死区时间TIM1-BDTR | (10 TIM_BDTR_DTG_Pos); // 10个时钟周期的死区DMA联动通过DMA自动更新CCR值我实现了256步的步进电机细分驱动。具体做法是预存正弦表到数组DMA循环传输到CCR寄存器。3. 多通道配置实战从LED到电机控制3.1 呼吸灯阵列控制用TIM3的4个通道控制LED矩阵关键是要平衡分辨率与刷新率。我的经验公式ARR (时钟频率 / PWM频率) - 1比如72MHz时钟要1kHz PWMTIM3-PSC 71; // 分频后1MHz TIM3-ARR 999; // 1MHz/10001kHz通过交替修改4个CCR值可以实现流水灯效果。实测发现当PSC0时记得在改CCR前加TIM3-EGR | TIM_EGR_UG; // 触发更新事件3.2 步进电机细分驱动用TIM1的3个通道实现两相步进电机控制核心是生成相位差120度的PWM。配置步骤计算正弦表以256步为例# Python生成正弦表 import math sin_table [int(500 500 * math.sin(2*math.pi*i/256)) for i in range(256)]配置TIM1通道1-3为PWM模式使用DMA循环模式更新CCRDMA1_Channel5-CNDTR 256; DMA1_Channel5-CMAR (uint32_t)sin_table; DMA1_Channel5-CPAR (uint32_t)TIM1-CCR1; DMA1_Channel5-CCR | DMA_CCR_EN;3.3 舵机群控方案机器人项目需要控制8个舵机但定时器通道不够用。解决方案使用TIM2TIM3共8个通道设置ARR19999PSC7150Hz PWM通过引脚重映射解决IO冲突__HAL_AFIO_REMAP_TIM2_PARTIAL_1(); // TIM2_CH1重映射到PA15特别注意舵机控制需要精确的脉冲宽度0.5ms-2.5ms计算公式CCR (ARR 1) * (0.5 angle/90.0) / 20.04. 高级应用主从定时器与事件同步在做数控电源时需要精确同步ADC采样与PWM更新。STM32的事件互连功能帮了大忙定时器级联TIM4作为主定时器触发TIM5的计数TIM4-CR2 | TIM_CR2_MMS_1; // 更新事件作为触发输出 TIM5-SMCR | TIM_SMCR_SMS_2; // 从模式复位ADC同步用TIM1的TRGO触发ADC采样TIM1-CR2 | TIM_CR2_MMS_2; // 比较脉冲作为TRGO ADC1-CR2 | ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG;互补波形生成高级定时器可以自动生成带死区的互补PWMTIM1-CCMR1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM模式1 TIM1-CCER | TIM_CCER_CC1NE; // 使能互补输出踩过的坑当使用刹车功能时一定要配置BDTR寄存器TIM1-BDTR | TIM_BDTR_MOE; // 主输出使能5. 性能优化与问题排查5.1 资源冲突解决当多个通道需要高分辨率时ARR值可能超出范围。我的解决方案降低PWM频率从20kHz降到1kHzARR可扩大20倍使用32位定时器如TIM2ARR可达2^32-1分时复用用DMA动态切换CCR值5.2 波形抖动问题排查遇到PWM抖动时按以下步骤检查用示波器查看时钟信号是否稳定检查APB总线时钟分频设置确认没有其他中断抢占定时器中断检查预装载寄存器是否使能TIM1-CR1 | TIM_CR1_ARPE; // 使能ARR预装载5.3 效率优化技巧使用寄存器操作替代库函数速度提升明显TIM1-CCR1 1000; // 比HAL_TIM_SetCompare快3倍对于固定占空比启用预装载TIM1-CCMR1 | TIM_CCMR1_OC1PE; // CCR1预装载使能关闭不用的通道降低功耗TIM1-CCER ~TIM_CCER_CC1E; // 关闭通道1输出记得有次调试四轴飞行器PWM突然失控导致炸机。后来发现是中断优先级配置不当现在我都坚持这个原则HAL_NVIC_SetPriority(TIM1_UP_IRQn, 5, 0); // 定时器中断设为中等优先级