1. 项目背景与原理概述
直流电机闭环控制系统是工业自动化和机器人领域的基础应用之一。相比开环控制,闭环系统能够实时监测电机运行状态并自动调整输出,有效应对负载变化、电压波动等干扰因素。本系统基于STM32F103C8T6单片机,通过PWM波控制电机转速,利用ADC采集工作电流,结合PID算法实现精准调速。
1.1 核心原理拆解
PWM调速原理
脉宽调制(PWM)通过快速开关MOS管来控制电机两端的平均电压。占空比(Duty Cycle)决定了有效电压大小:50%占空比的12V PWM波等效于6V直流电压。STM32的定时器可以生成高精度PWM信号,我们使用TIM1的CH1通道输出1kHz PWM波。
电流采样原理
在电机回路中串联0.1Ω采样电阻,根据欧姆定律U=IR,电流转化为电压信号。STM32的12位ADC将模拟电压量化为0-4095的数字值,3.3V参考电压下分辨率达到0.8mV,对应电流测量精度约8mA。
PID控制算法
比例-积分-微分控制器通过三种作用调节系统:
- 比例项(P):即时响应当前误差,但会导致稳态误差
- 积分项(I):累积历史误差消除静差,但可能引起超调
- 微分项(D):预测误差变化趋势,抑制振荡
1.2 硬件选型指南
| 模块 | 推荐型号 | 关键参数 | 选型依据 |
|---|---|---|---|
| 主控 | STM32F103C8T6 | 72MHz主频,3个ADC | 性价比高,资源丰富 |
| 电机驱动 | L298N | 2A持续电流 | 双H桥,支持正反转 |
| 采样电阻 | 0.1Ω/2W | 1%精度 | 功率余量充足 |
| 编码器 | 霍尔AB相 | 11PPR | 分辨率适中 |
| 电源 | 12V/2A开关电源 | 纹波<100mV | 确保电流供应 |
实际选型时需注意:电机额定电流应小于驱动芯片限流值,采样电阻功率P=I²R需留50%余量,编码器分辨率要与转速范围匹配。
2. 硬件电路设计与实现
2.1 系统架构设计
完整的硬件系统包含五个主要部分:
- 电源模块:12V转5V给MCU供电
- 驱动模块:L298N桥接电路
- 采样模块:电流-电压转换电路
- 反馈模块:编码器信号处理
- 主控模块:STM32最小系统
2.2 关键电路详解
电流采样电路优化
基础方案存在两个问题:
- 采样电阻两端电压可能为负值(电机反转时)
- 共模电压超出STM32 ADC输入范围(0-3.3V)
改进方案采用差分放大电路:
code复制电机负极 —— 采样电阻 —— 地
|
+-- 10kΩ --+
|—— OPAMP输出到ADC
+-- 10kΩ --+
|
虚地(1.65V)
运放配置增益G=10,虚地抬升1.65V,使-0.15V~+0.15V的差分信号转换为0.15V~3.15V的单端信号。
PCB布局要点
- 电机驱动部分与信号处理分区布局
- 采样电阻采用开尔文接法(Kelvin Connection)
- ADC输入走线远离PWM等高频信号
- 地平面分割:数字地与模拟地单点连接
3. 软件环境配置
3.1 开发工具链搭建
推荐使用VSCode+PlatformIO生态:
- 安装Visual Studio Code
- 添加PlatformIO IDE插件
- 创建STM32项目,选择框架为
stm32cube - 配置platformio.ini:
ini复制[env:bluepill_f103c8]
platform = ststm32
board = bluepill_f103c8
framework = stm32cube
upload_protocol = stlink
3.2 STM32CubeMX关键配置
定时器PWM模式配置
- TIM1通道1选择"PWM Generation CH1"
- 时钟源选择内部时钟
- 预分频(PSC)=71,计数周期(ARR)=999
- PWM模式选择"PWM mode 1",极性高有效
ADC采样优化技巧
- 开启连续转换模式
- 采样时间设为239.5周期(最大精度)
- 添加DMA传输减轻CPU负担
- 配置硬件过采样(Hardware Oversampling)提升分辨率
4. 核心算法实现
4.1 PID控制器改进
抗积分饱和处理
常规PID在长时间误差累积时会出现"windup"现象。改进方案:
c复制// 在PID计算函数中加入
if(fabsf(pid->Output) >= pid->MaxOutput) {
pid->SumError -= pid->Error; // 反向修正积分项
}
变参数PID实现
根据误差大小动态调整参数:
c复制float dynamic_kp = pid->Kp * (1 + 0.5f * fabsf(pid->Error)/pid->Target);
4.2 转速测量算法优化
M法测速公式改进
传统公式在低速时误差大,改进为:
c复制// 当脉冲数N < 5时切换为周期测量法
if(Encoder_Count < 5) {
Motor_Speed = 60 / (N * T * Reduction_Ratio);
} else {
Motor_Speed = (Encoder_Count * 60) / (PPR * Reduction_Ratio * Δt);
}
5. 系统调试实战
5.1 调试工具准备
必备仪器:
- 数字示波器:观测PWM波形
- 逻辑分析仪:捕获编码器信号
- 电流探头:实时监测电机电流
- 串口调试助手:查看数据输出
5.2 PID参数整定流程
Ziegler-Nichols整定法
- 将Ki和Kd设为0,逐渐增大Kp直到出现等幅振荡
- 记录临界增益Ku和振荡周期Tu
- 根据规则设置参数:
- P控制:Kp = 0.5Ku
- PI控制:Kp = 0.45Ku, Ki = 0.54Ku/Tu
- PID控制:Kp = 0.6Ku, Ki = 1.2Ku/Tu, Kd = 0.075KuTu
现场调试技巧
- 先用手转动电机感受阻力,估算初始P值
- 调试时逐步增加目标转速,避免突变
- 负载变化测试:突然施加阻力观察恢复时间
- 温度监测:连续运行30分钟检查器件温升
6. 性能优化进阶
6.1 电流环-速度环双闭环控制
控制结构
code复制速度PID输出 → 作为电流环的目标值
↓
电流PID输出 → PWM驱动器 → 电机
↑
电流反馈(ADC)
实现要点
- 电流环响应速度应比速度环快5-10倍
- 两个PID控制器需独立调参
- 增加电流限幅保护电路
6.2 状态观测器设计
对于无编码器系统,可采用龙伯格观测器:
c复制// 电机状态方程离散化
current_est = A * last_current + B * PWM_duty;
speed_est = C * current_est;
// 校正环节
current_est += L * (real_current - current_est);
7. 故障排查手册
7.1 常见问题分析
电机抖动问题
可能原因及解决方案:
- 电源功率不足:更换更大电流电源
- PWM频率过低:提高到10kHz以上
- 机械共振:添加橡胶减震垫
ADC采样异常
排查步骤:
- 检查参考电压是否稳定
- 测量输入信号是否在0-3.3V范围
- 确认采样时钟不超过14MHz
- 检查是否有电磁干扰
7.2 安全防护措施
- 软件看门狗定时器配置:
c复制IWDG_InitTypeDef IWDG_InitStruct = {0};
IWDG_InitStruct.Prescaler = IWDG_PRESCALER_32;
IWDG_InitStruct.Reload = 0xFFF;
HAL_IWDG_Init(&IWDG_InitStruct);
- 硬件保护电路:
- 自恢复保险丝
- TVS二极管防反接
- 光耦隔离控制信号
8. 项目扩展方向
8.1 无线控制实现
蓝牙模块集成
- 选用HC-05模块
- 配置AT命令模式:
bash复制AT+NAME=MotorCtrl
AT+PSWD=1234
AT+UART=115200,0,0
通信协议设计
c复制#pragma pack(1)
typedef struct {
uint8_t head; // 0xAA
uint16_t speed; // 目标转速
uint8_t dir; // 方向
uint16_t crc; // CRC校验
} MotorCmd_t;
8.2 能量回馈设计
制动能量回收电路
- 采用MOSFET同步整流
- 升压电路将回馈能量充入电容
- 电压检测控制充电过程
软件实现
c复制void Brake_Energy_Recovery(void) {
if(bus_voltage < 12.5f) {
PWM_Disable();
Enable_Charge_Circuit();
}
}
在实际项目中,我发现电机参数辨识对PID调参至关重要。通过施加阶跃信号并记录响应曲线,可以建立准确的电机数学模型。另外,使用MATLAB的PID Tuner工具可以大幅提高调参效率,将仿真参数作为现场调试的初始值,通常能减少50%以上的调试时间。
