1. 项目概述:当电机控制遇上无线互联
去年帮朋友改造一台小型CNC雕刻机时,发现传统的有刷电机在长时间工作后碳刷磨损严重,于是尝试用无刷电机替代。在这个过程中,我设计了一套基于STM32的无刷直流电机控制系统,通过蓝牙实现手机APP无线控制和实时监测。这套方案不仅解决了设备维护问题,还意外获得了更好的调速性能和能耗表现。
无刷直流电机(BLDC)凭借高效率、长寿命和低噪音的特点,正在逐步取代传统有刷电机。而STM32作为性价比极高的ARM Cortex-M系列MCU,其丰富的外设和实时性能使其成为电机控制的理想选择。加上蓝牙无线通信,这套系统可以应用在无人机、智能家居、机器人等需要远程控制的场景中。
2. 系统架构设计
2.1 硬件组成框架
整个系统采用模块化设计,主要包含三个部分:
-
功率驱动模块:
- 选用IR2104半桥驱动器配合IRL3803 MOSFET组成三相全桥
- 母线电压设计为24V,峰值电流15A
- 集成电流采样电阻(0.01Ω/3W)和运放调理电路
-
控制核心模块:
- STM32F103C8T6最小系统板(72MHz主频)
- 6路PWM输出(TIM1高级定时器)
- 3路霍尔传感器接口(TIM4编码器模式)
- 1路12位ADC用于电流检测
-
无线通信模块:
- HC-05蓝牙模块(Class2,10米传输距离)
- 串口通信波特率设置为115200bps
- 自定义简单通信协议(后文详述)
实际调试中发现,电机启动时会对电源造成较大干扰,建议在电源输入端增加470μF电解电容并联0.1μF陶瓷电容的组合。
2.2 软件功能规划
系统软件采用前后台架构:
-
实时任务(中断驱动):
- PWM生成(16kHz开关频率)
- 霍尔信号捕获(换相判断)
- 过流保护(硬件比较器+软件双重保护)
-
后台任务(主循环):
- 蓝牙协议解析
- PID速度调节
- 状态监测与上报
- 故障处理与恢复
3. 无刷电机控制实现
3.1 六步换相控制原理
无刷电机采用电子换相替代机械换相,其关键是根据转子位置(霍尔信号)切换不同MOSFET的组合导通。以三相星型连接电机为例:
code复制霍尔状态 | 导通相
--------|-------
001 | A+B-
010 | A+C-
011 | B+C-
100 | A-B+
110 | A-C+
101 | B-C+
在STM32中,我们使用TIM1的PWM互补输出模式,配置为中央对齐PWM1模式。关键寄存器设置:
c复制TIM1->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM模式1
TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE; // 使能主输出和互补输出
TIM1->BDTR |= TIM_BDTR_MOE; // 主输出使能
3.2 速度闭环控制实现
采用增量式PID算法进行速度调节:
c复制typedef struct {
float Kp, Ki, Kd;
float err, last_err, integral;
} PID_Controller;
float PID_Update(PID_Controller* pid, float target, float feedback) {
pid->err = target - feedback;
pid->integral += pid->err;
float derivative = pid->err - pid->last_err;
pid->last_err = pid->err;
return pid->Kp * pid->err +
pid->Ki * pid->integral +
pid->Kd * derivative;
}
速度检测通过霍尔信号频率计算实现。在TIM4的捕获中断中:
c复制void TIM4_IRQHandler() {
static uint32_t last_cnt = 0;
uint32_t curr_cnt = TIM4->CNT;
uint32_t period = curr_cnt - last_cnt;
if(period < 0xFFFF) { // 防止溢出误判
speed_rpm = 60 * (SystemCoreClock/72) / (period * 7); // 7极对电机
}
last_cnt = curr_cnt;
TIM4->SR = ~TIM_SR_CC1IF; // 清除中断标志
}
4. 蓝牙通信协议设计
4.1 自定义通信帧格式
为简化开发,设计了基于ASCII码的文本协议:
code复制[起始符][命令][分隔符][数据][校验和][结束符]
示例命令:
- 设置速度:
$SPD:1500*23\n - 读取状态:
$STS?*1A\n - 故障代码:
$ERR:02*45\n
校验和采用简单的异或校验:
c复制uint8_t calc_checksum(const char* buf) {
uint8_t sum = 0;
for(int i=1; buf[i]!='*'; i++) {
sum ^= buf[i];
}
return sum;
}
4.2 Android APP开发要点
使用Android Studio开发控制APP,核心功能包括:
- 蓝牙连接管理:
java复制BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = adapter.getBondedDevices().get(0);
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
- 速度控制滑块实现:
xml复制<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="3000"
android:progress="1500"/>
- 实时曲线显示:
使用MPAndroidChart库绘制转速-时间曲线,每200ms更新一次数据。
5. 系统调试与优化
5.1 常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 电机抖动不转 | 霍尔相位错误 | 调整霍尔传感器接线顺序 |
| 高速时失步 | PWM死区时间不足 | 增大TIM1->BDTR中DTG值 |
| 蓝牙连接不稳定 | 电源干扰 | 给蓝牙模块单独供电并加磁珠 |
| 电流读数不准 | 采样电阻温漂 | 改用合金采样电阻或进行软件补偿 |
5.2 性能优化记录
-
PWM频率选择:
- 初始测试使用8kHz,MOSFET温升明显
- 提高到16kHz后开关损耗降低约40%
- 但超过20kHz会导致栅极驱动不足
-
PID参数整定:
- 先用Ziegler-Nichols方法初步确定参数
- 实际测试发现需要减小积分项防止超调
- 最终参数:Kp=0.8, Ki=0.05, Kd=0.12
-
低功耗优化:
- 空闲时关闭TIM1时钟
- 蓝牙模块设置AT+ROLE=0进入从机模式
- 整体待机电流从120mA降至15mA
6. 应用场景扩展
这套系统经过适当修改可应用于:
-
智能家居:
- 窗帘电机控制
- 新风系统风机调速
- 水泵流量调节
-
模型制作:
- 无人机电调
- 遥控车动力系统
- 船模推进控制
-
工业设备:
- 小型传送带调速
- 自动化设备执行机构
- 实验室仪器精密运动控制
在实际部署中发现,对于需要更高可靠性的场合,可以考虑以下改进:
- 改用ESP32实现WiFi和蓝牙双模控制
- 增加CAN总线接口实现多电机同步
- 引入FOC(磁场定向控制)算法提升低速性能
调试过程中最深的体会是:电机参数对控制效果影响极大。建议在实际使用前先用示波器捕获反电动势波形,准确测定电机电气参数。另外,PCB布局时功率地和信号地要单点连接,否则电流采样会引入严重噪声。