1. 直流电机双向可逆控制系统概述
双向可逆控制是工业自动化领域的基础需求,在机床进给、传送带、卷帘门等场景中随处可见。传统继电器控制方案存在机械磨损、响应慢等痛点,而基于PWM(脉宽调制)的电子控制方案正逐步成为主流选择。
我最近完成的一个物料分拣项目就采用了这种设计。系统要求传送带能根据传感器信号随时切换方向,且速度需精确调节。经过对比测试,采用H桥电路配合STM32单片机方案,最终实现了0-3000rpm无级调速和10ms内快速换向的指标。下面就把这套经过实战验证的方案拆解给大家。
2. 系统核心架构设计
2.1 电力电子拓扑选择
H桥电路是双向控制的核心,其本质是四个功率开关管组成的桥式结构。当Q1/Q4导通时电流从左至右,Q2/Q3导通时电流反向流动。实际工程中需要注意:
- 开关管选型:对于12V/5A的直流电机,我选用IRF540N MOSFET(Vds=100V,Rds(on)=44mΩ),其导通损耗P=5²×0.044=1.1W,无需额外散热片
- 死区时间:必须设置至少1μs的死区防止上下管直通,STM32的TIM1高级定时器可自动生成死区
- 续流二极管:每个MOSFET需并联快恢复二极管(如FR107),处理电机电感产生的反向电动势
2.2 控制核心选型对比
| 控制器类型 | 成本 | 开发难度 | 性能指标 | 适用场景 |
|---|---|---|---|---|
| 纯硬件逻辑 | 低 | 高 | 固定功能 | 简单启停控制 |
| 51单片机 | 中 | 低 | 10位PWM | 低速场合 |
| STM32F103 | 中 | 中 | 16位PWM | 本文方案 |
| DSP28335 | 高 | 高 | 150MHz主频 | 伺服系统 |
最终选择STM32F103C8T6最小系统板,其优势在于:
- 72MHz主频满足实时控制需求
- 4个16位PWM定时器(TIM1高级定时器支持互补输出)
- 12位ADC可做电流反馈
- 成本仅15元左右
3. 关键电路实现细节
3.1 H桥驱动电路设计
直接使用MCU的GPIO驱动MOSFET会导致开关损耗大,必须增加驱动芯片。我采用IR2104半桥驱动器,其典型接线如图:
c复制// STM32 PWM输出配置
TIM_OCInitTypeDef oc;
oc.TIM_OCMode = TIM_OCMode_PWM1;
oc.TIM_OutputState = TIM_OutputState_Enable;
oc.TIM_Pulse = 720; // 50%占空比(1440/2)
oc.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &oc);
关键提示:VCC与VB之间需接自举电容(通常0.1uF+10uF并联),否则高端MOSFET无法持续导通
3.2 电流检测方案
过流保护是必须功能,这里采用ACS712-5A霍尔传感器:
- 灵敏度:185mV/A
- 零点偏移:VCC/2(2.5V)
ADC采样值换算公式:
matlab复制Current = (ADC_Value/4095*3.3 - 2.5)/0.185
实际测试时发现电机启动瞬间电流可达额定值3倍,因此软件中设置2.5A的硬阈值触发保护。
4. 控制算法实现
4.1 双极性PWM生成
通过调节PWM占空比实现正反转控制:
- 正转:PWM1>0,PWM2=0
- 反转:PWM1=0,PWM2>0
- 刹车:PWM1=PWM2=100%
在STM32CubeMX中配置TIM1通道1/2为互补输出模式,关键代码:
c复制// 设置方向和速度
void SetMotor(int16_t speed) {
if(speed > 0) {
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, speed);
__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, -speed);
}
}
4.2 速度闭环控制
采用增量式PID算法,参数整定过程:
- 先设Ki=Kd=0,增大Kp至出现等幅振荡(本例中Kp=2.1)
- 取Kp为临界值的0.6倍(1.26),设置Ti=0.5*振荡周期
- 最终参数:Kp=1.2, Ki=0.8, Kd=0.2
PID实现代码片段:
c复制typedef struct {
float Kp,Ki,Kd;
float integral;
float prev_error;
} PID;
float PID_Update(PID* pid, float error, float dt) {
float deriv = (error - pid->prev_error)/dt;
pid->integral += error*dt;
pid->prev_error = error;
return pid->Kp*error + pid->Ki*pid->integral + pid->Kd*deriv;
}
5. 工程调试经验
5.1 典型问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 电机单方向不转 | MOSFET损坏/驱动异常 | 用万用表测量GS电压应>8V |
| 上电后电机抖动 | 死区时间不足 | 调整TIM1->BDTR寄存器DTG位 |
| 高速时MOSFET发烫 | 开关频率过低 | 将PWM频率提升至20kHz以上 |
| 电流读数波动大 | 电源地线干扰 | 在ACS712输出端加104电容滤波 |
5.2 实测波形分析
使用DSO5102P示波器捕获的典型波形:
- 黄色:PWM信号(10kHz)
- 蓝色:电机两端电压
- 红色:相电流(通过1Ω采样电阻)

注意观察电流纹波是否超过额定值的20%,过大时需要增加LC滤波
6. 系统优化方向
在完成基础功能后,可以考虑:
- 加入位置闭环:加装编码器实现精确角度控制
- 能量回馈:在刹车时通过BOOST电路将能量回充到电源
- 网络控制:通过CAN总线接收运动指令
- 参数自整定:加入Ziegler-Nichols算法的自动整定功能
这个项目最让我意外的是电机电磁噪声问题。通过FFT分析发现主要谐波集中在16kHz,最终在电机端子并联0.1μF+100Ω的RC吸收电路后,噪声降低了约15dB。
