STM32无刷直流电机驱动实战:H_PWM_L_ON模式详解

张开发
2026/4/17 5:22:20 15 分钟阅读

分享文章

STM32无刷直流电机驱动实战:H_PWM_L_ON模式详解
1. H_PWM_L_ON模式基础原理无刷直流电机BLDC的驱动方式多种多样其中H_PWM_L_ON模式因其简单高效的特点在中小功率应用中非常受欢迎。这种模式的核心思想是上桥臂采用PWM信号控制下桥臂则保持常开或常闭。听起来有点抽象我们可以用自来水管道来类比上桥臂就像可调节的水龙头PWM控制流量下桥臂则是固定开度的阀门全开或全关。在实际电路中上桥臂的MOS管会接收来自STM32的PWM信号通过调节占空比来控制电机绕组的通电时间。而下桥臂的MOS管则直接由GPIO控制要么完全导通低电平有效要么完全关闭。这种组合方式既能实现调速功能又比全PWM模式更节省计算资源。注意使用H_PWM_L_ON模式时一定要配置死区时间Dead Time防止上下桥臂瞬间直通导致短路。一般建议设置在1-2微秒范围内。2. 硬件电路设计要点2.1 驱动芯片选型与连接IRS2101S这类半桥驱动芯片是BLDC驱动系统的中间人它负责将STM32输出的3.3V信号升压到MOS管需要的10-15V驱动电压。我在多个项目中实测发现使用IRF540NS这类N沟道MOS管时驱动电压最好保持在12V左右既能保证充分导通又不会超过栅极耐压值。硬件连接时要注意三个关键点每个半桥的上桥臂自举电容要足够大通常0.1-1μF确保高侧MOS管能持续导通PWM信号线要尽量短必要时加22Ω电阻抑制振铃电机电源与逻辑电源之间要用0.1μF电容去耦2.2 保护电路设计有次我在测试时忘了接电流检测电阻结果电机堵转瞬间烧毁了MOS管。吃一堑长一智现在我的电路板上必定包含三相电流检测电阻通常0.01-0.1Ω栅极泄放电阻10kΩTVS二极管防止电压尖峰过温保护热敏电阻3. STM32定时器配置详解3.1 TIM1高级定时器设置TIM1是STM32中功能最强大的定时器特别适合电机控制。下面这段初始化代码我优化过多个版本现在分享最稳定的配置方案void DcMotorTim1Init(uint32_t pwm_period, uint32_t frequency) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period pwm_period - 1; // 例如255对应8位分辨率 TIM_TimeBaseStructure.TIM_Prescaler SystemCoreClock/frequency/pwm_period - 1; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, TIM_TimeBaseStructure); TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_BDTRInitStructure.TIM_DeadTime 0x6A; // 约1.8μs死区 TIM_BDTRConfig(TIM1, TIM_BDTRInitStructure); }关键参数说明pwm_period决定PWM分辨率256对应8位1024对应10位frequency建议设置在10-20kHz之间超过20kHz可能引起MOS管开关损耗DeadTime根据MOS管规格书中的开启/关闭时间计算3.2 PWM输出模式配置H_PWM_L_ON模式需要配置TIM1的通道输出特性TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse 0; // 初始占空比0% TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_Low; // 上桥臂极性 TIM_OC1Init(TIM1, TIM_OCInitStructure); // 重复配置CH1/CH2/CH3特别注意互补通道下桥臂的配置要匹配GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; // 下桥臂用普通GPIO GPIO_Init(GPIOB, GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15, GPIO_InitStructure);4. 软件控制策略实现4.1 六步换相控制BLDC电机需要按照霍尔传感器信号进行换相。下面这个状态表是我通过实测优化的换相顺序霍尔值导通相PWM相下桥臂导通0x05A-BAB0x01A-CAC0x03B-CBC0x02B-ABA0x06C-ACA0x04C-BCB对应的代码实现片段void UpdateCommutation(uint8_t hall) { switch(hall) { case 0x05: // AB相 TIM1-CCR1 current_duty; // A相PWM GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_13); // B相常开 break; // 其他状态类似... } }4.2 速度闭环控制单纯的换相只能让电机转起来要实现稳定运行还需要PID算法。我常用的增量式PID实现如下typedef struct { float Kp, Ki, Kd; float last_error, prev_error; int32_t output; } PID_Controller; void PID_Update(PID_Controller* pid, float error) { float delta pid-Kp*(error - pid-last_error) pid-Ki*error pid-Kd*(error - 2*pid-last_error pid-prev_error); pid-output delta; pid-prev_error pid-last_error; pid-last_error error; }使用时需要注意先调Kp直到出现小幅振荡然后加Kd抑制振荡最后加Ki消除静差输出限幅在0-PWM_PERIOD之间5. 调试技巧与常见问题5.1 上电无反应排查步骤遇到电机不转时可以按照这个顺序排查用万用表测量驱动芯片供电是否正常VCC和VB电压检查STM32的PWM输出是否正常可用示波器看PA8/9/10确认霍尔传感器信号是否变化测量PC6/7/8电压断开电机测量各相MOS管栅极驱动波形5.2 典型故障处理问题现象电机抖动但不旋转可能原因霍尔传感器相位接反解决方法尝试交换任意两相线序或调整霍尔信号映射问题现象MOS管发热严重可能原因死区时间不足或PWM频率过高解决方法增加TIM_BDTRInitStructure.TIM_DeadTime值或降低PWM频率问题现象高速运行时失步可能原因反电动势采样延迟解决方法在换相点增加5-10°的提前量或改用传感器less算法6. 性能优化实践6.1 电流采样优化在H_PWM_L_ON模式下下桥臂的导通状态可以用来采样相电流。我通常在下桥臂导通后延迟1-2μs再进行ADC采样这样可以避开开关噪声。具体实现void ADC_Config(void) { ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_28Cycles); ADC_ExternalTrigConvCmd(ADC1, ENABLE); ADC_ExternalTrigConvConfig(ADC1, ADC_ExternalTrigConv_T1_CC1); }6.2 动态刹车功能紧急停止时可以启用动态刹车快速制动void EmergencyBrake(void) { // 关闭所有上桥臂PWM TIM1-CCR1 TIM1-CCR2 TIM1-CCR3 0; // 下桥臂全部导通形成短路 GPIO_SetBits(GPIOB, GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); }这个功能在机器人应用中特别有用但要注意连续制动时间不要超过3秒否则可能过热。

更多文章