4、PWM原理与配置:PWM频率与占空比、定时器配置(以STM32为例)、死区时间设置

说到电机控制,PWM绝对是绕不开的核心技术。说白了,电机调速的本质就是靠PWM来完成的。我刚开始做电机驱动那会儿,总觉得PWM不就是个方波嘛,有啥好研究的?结果第一次调BLDC电机,电机嗡嗡响就是不转,查了半天才发现是PWM频率没选对。嗯,这玩意儿还真不能马虎。

4.1 PWM频率与占空比:两个最关键的参数

PWM信号,你可以想象成一个开关。开的时间长,关的时间短,平均电压就高。反之就低。这里面有两个核心参数:频率占空比

频率,就是开关一秒钟来回切换多少次。单位是Hz。频率越高,电机运行越平滑,噪音也越小。但频率太高,MOS管的开关损耗会急剧增加,发热严重。我见过有人把频率设到100kHz,结果MOS管烫得能煎鸡蛋。

占空比,就是高电平时间占整个周期的百分比。0%就是一直关,100%就是一直开。电机转速跟占空比基本成正比。比如50%占空比,电机大概跑一半的速度。

重要经验:对于直流有刷电机,PWM频率通常选1kHz~20kHz。低于1kHz,电机会有明显的顿挫感。高于20kHz,人耳听不到啸叫声,但MOS管损耗会明显上升。我个人习惯,无刷电机用10kHz~20kHz,有刷电机用8kHz~16kHz。

4.2 定时器配置:以STM32为例

STM32的定时器功能非常强大。生成PWM,我们一般用高级定时器(TIM1、TIM8)或者通用定时器(TIM2~TIM5)。高级定时器多了死区插入、刹车输入等功能,做电机控制首选。

配置步骤其实不复杂,我拆开来讲:

  1. 时钟源选择:定时器挂在哪条总线上,APB1还是APB2?注意,APB2的频率通常更高,适合高速PWM。
  2. 预分频器设置:决定定时器计数一次的时间。公式:计数时钟 = 总线时钟 / (预分频值 + 1)。
  3. 自动重装载值:决定PWM周期。周期 = (重装载值 + 1) / 计数时钟。
  4. 比较值设置:决定占空比。占空比 = 比较值 / (重装载值 + 1)。
  5. 输出通道配置:选择PWM模式1还是模式2,极性是正还是反。

举个例子,我想输出一个10kHz的PWM,系统时钟72MHz,挂APB1(36MHz)。

// 定时器配置示例(STM32F1,TIM2)
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

// 1. 使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

// 2. 配置时基
TIM_TimeBaseStructure.TIM_Prescaler = 36 - 1;      // 预分频,36MHz/36 = 1MHz
TIM_TimeBaseStructure.TIM_Period = 100 - 1;         // 重装载值,1MHz/100 = 10kHz
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

// 3. 配置PWM输出
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;   // PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 50;                 // 比较值,占空比50%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);

// 4. 使能定时器
TIM_Cmd(TIM2, ENABLE);

小技巧:我习惯把预分频值设成总线频率的整数分之一,这样计算周期和占空比时不容易出错。比如36MHz,预分频36,得到1MHz的计数时钟,周期和占空比都是整数,调试起来特别方便。

4.3 死区时间设置:电机驱动的保命符

死区时间,这是新手最容易忽略的地方。什么叫死区?就是上下桥臂同时关断的那一小段时间。

为什么会这样?你想想看,MOS管从导通到关断需要时间。如果上管还没完全关断,下管就导通了,那上下管直接短路,电流瞬间飙升,MOS管秒烧。我在项目中遇到过这种情况,第一次调H桥,没设死区,一上电就冒烟了。嗯,从那以后我再也不敢不设死区了。

死区时间怎么算?主要看MOS管的关断延迟时间。一般数据手册会给出td(off)和tf。死区时间至少要大于这两个值之和,再留点余量。

MOS管型号 关断延迟(典型) 建议死区时间
IRF540 约50ns 200ns~500ns
IRF3205 约60ns 300ns~600ns
N沟道小功率管 约20ns 100ns~300ns

STM32高级定时器配置死区很简单,用TIM_BreakDeadTimeConfig函数。死区时间单位是定时器的计数时钟周期。比如计数时钟1MHz,一个周期就是1us,设死区值为100,就是100us。

// 死区时间配置示例
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 100;   // 死区时间,单位:计数时钟周期
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

警告:死区时间不是越大越好。死区太大,电机在换相时会有明显的电流断续,导致转矩脉动,电机运行不平稳。我一般从500ns开始试,用示波器看上下管波形,确保没有直通,然后逐步减小,找到平衡点。

4.4 实战中的几个坑

最后分享几个我踩过的坑:

  • PWM频率和电机电感要匹配:频率太低,电流纹波大,电机发热。频率太高,MOS管开关损耗大。我一般先算一下电机的时间常数,然后选频率在时间常数的10倍左右。
  • 占空比不要到0%或100%:极端占空比会导致MOS管长时间导通或关断,容易出问题。我习惯限制在5%~95%之间。
  • 死区时间要实测验证:别光看数据手册。不同批次、不同温度的MOS管参数会有差异。上电后用示波器抓一下上下管的栅极波形,确认没有重叠。
  • 注意定时器的时钟源:STM32的定时器时钟可能跟总线时钟不同步。我遇到过APB1预分频后,定时器时钟翻倍的情况,导致PWM频率算错。建议用CubeMX自动配置,省心。

PWM配置说难不难,说简单也不简单。关键是要理解背后的原理,然后多动手调试。你只要把频率、占空比、死区这三个参数搞明白了,电机控制就入门了一大半。