智能车电机驱动 H 桥 PWM 配置详解:STM32 定时器 4 通道输出 20kHz 波形
STM32高级定时器实现H桥PWM电机驱动全解析1. H桥驱动与PWM基础原理在智能车电机控制系统中H桥电路是实现直流电机正反转和调速的核心功率拓扑结构。这种由四个开关管组成的H形电路通过不同的导通组合可以改变电机两端的电压极性从而实现电机的双向控制。H桥工作模式解析正向导通模式当Q1和Q4导通时电流从左至右流过电机实现正转反向导通模式当Q2和Q3导通时电流方向反转电机反转制动模式通过特定开关组合使电机两端短接产生制动效果// H桥控制真值表示例 typedef enum { MOTOR_STOP 0x00, // 所有MOSFET关断 MOTOR_FWD 0x05, // Q1和Q4导通 (二进制0101) MOTOR_REV 0x0A, // Q2和Q3导通 (二进制1010) MOTOR_BRAKE 0x0F // Q1Q3或Q2Q4导通 (二进制1111) } MotorState;PWM调制技术通过快速切换开关状态来调节平均电压其关键参数包括参数典型值说明频率20kHz超出人耳听觉范围减少噪音分辨率16bitSTM32高级定时器最大分辨率死区时间100-500ns防止上下管直通重要提示死区时间设置不足会导致桥臂直通烧毁MOSFET过长则会引入非线性失真。需要根据具体MOSFET的开关特性调整。2. STM32高级定时器配置STM32的TIM1/TIM8等高级定时器专为电机控制设计具备互补输出、死区插入和紧急关断等高级功能。以下是基于HAL库的配置步骤2.1 定时器基础配置TIM_HandleTypeDef htim1; TIM_OC_InitTypeDef sConfigOC; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; htim1.Instance TIM1; htim1.Init.Prescaler 0; htim1.Init.CounterMode TIM_COUNTERMODE_UP; htim1.Init.Period SystemCoreClock / 20000 - 1; // 20kHz PWM htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter 0; htim1.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_ENABLE; HAL_TIM_PWM_Init(htim1);2.2 互补通道配置sConfigOC.OCMode TIM_OCMODE_PWM1; sConfigOC.Pulse 0; // 初始占空比0% sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode TIM_OCFAST_DISABLE; sConfigOC.OCIdleState TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState TIM_OCNIDLESTATE_RESET; HAL_TIM_PWM_ConfigChannel(htim1, sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_ConfigChannel(htim1, sConfigOC, TIM_CHANNEL_2);2.3 死区时间计算与设置死区时间与系统时钟频率相关计算公式为T_dt (DTG[7:0] 1) * T_dts其中T_dts由时钟分频决定CKD[1:0]T_dts00t_CK_INT012 * t_CK_INT104 * t_CK_INTsBreakDeadTimeConfig.OffStateRunMode TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime 54; // 约300ns 72MHz sBreakDeadTimeConfig.BreakState TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput TIM_AUTOMATICOUTPUT_DISABLE; HAL_TIMEx_ConfigBreakDeadTime(htim1, sBreakDeadTimeConfig);3. 完整驱动实现方案3.1 初始化流程GPIO配置设置PWM输出引脚为复用推挽输出定时器配置按上述步骤初始化TIM1启动PWMHAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1)启动互补通道HAL_TIMEx_PWMN_Start(htim1, TIM_CHANNEL_1)3.2 动态控制接口void Motor_SetDuty(int16_t duty) { uint16_t pulse (uint32_t)abs(duty) * htim1.Init.Period / 10000; if(duty 0) { __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, pulse); __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_2, 0); } else { __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, 0); __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_2, pulse); } }3.3 保护机制实现过流保护电路设计要点在电机回路串联采样电阻通常5-50mΩ使用比较器实时监测电压降触发保护时立即关闭PWM输出// 紧急停止函数 void Motor_EmergencyStop(void) { HAL_TIM_PWM_Stop(htim1, TIM_CHANNEL_1); HAL_TIMEx_PWMN_Stop(htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Stop(htim1, TIM_CHANNEL_2); HAL_TIMEx_PWMN_Stop(htim1, TIM_CHANNEL_2); // 配置刹车输入引脚 GPIO_InitTypeDef GPIO_InitStruct {0}; GPIO_InitStruct.Pin BRAKE_PIN; GPIO_InitStruct.Mode GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull GPIO_NOPULL; HAL_GPIO_Init(BRAKE_PORT, GPIO_InitStruct); }4. 实测波形分析与优化使用示波器观察H桥输出时应重点关注以下信号质量指标关键测量参数上升/下降时间应100ns过冲电压应电源电压的20%死区时间实际值开关节点振铃幅度常见问题解决方案问题现象可能原因解决方法波形振荡栅极驱动电阻过大减小栅极电阻4.7Ω→2.2ΩMOSFET过热开关损耗大提高死区时间或降低频率电机抖动PWM分辨率不足改用32位定时器或提高时钟布局布线建议功率回路与信号回路严格分离栅极驱动走线尽量短3cm在MOSFET的DS极间并联RC缓冲电路使用低ESR的陶瓷电容进行电源去耦5. 与编码器及PID的协同工作完整的电机控制系统需要速度反馈闭环典型架构如下[PID控制器] → [PWM生成] → [H桥] → [电机] ↑ | └──[编码器反馈]←──┘速度计算实现// 编码器接口配置 TIM_Encoder_InitTypeDef sEncoderConfig; sEncoderConfig.EncoderMode TIM_ENCODERMODE_TI12; sEncoderConfig.IC1Polarity TIM_ICPOLARITY_RISING; sEncoderConfig.IC1Selection TIM_ICSELECTION_DIRECTTI; sEncoderConfig.IC1Prescaler TIM_ICPSC_DIV1; sEncoderConfig.IC1Filter 6; sEncoderConfig.IC2Polarity TIM_ICPOLARITY_RISING; sEncoderConfig.IC2Selection TIM_ICSELECTION_DIRECTTI; sEncoderConfig.IC2Prescaler TIM_ICPSC_DIV1; sEncoderConfig.IC2Filter 6; HAL_TIM_Encoder_Init(htim3, sEncoderConfig); // 速度计算 int32_t GetMotorSpeed(void) { static int32_t last_count 0; int32_t current_count __HAL_TIM_GET_COUNTER(htim3); int32_t speed (current_count - last_count) * 1000 / CONTROL_PERIOD_MS; last_count current_count; return speed; }PID参数整定经验值电机类型KpKiKd控制周期直流有刷0.5-2.00.1-0.50.01-0.11-10ms直流无刷1.0-3.00.2-1.00.05-0.20.1-1ms实际调试时建议先设置KiKd0逐渐增大Kp直到出现轻微振荡然后取该值的50%作为最终Kp。接着以类似方法调整Ki和Kd。