STM32实战:基于H桥与PWM的直流有刷电机驱动与调速

STM32实战:基于H桥与PWM的直流有刷电机驱动与调速 1. 直流有刷电机基础原理直流有刷电机是嵌入式项目中最常见的执行机构之一它的结构简单但控制逻辑却非常典型。想象一下小时候玩的四驱车里面嗡嗡转动的马达就是最典型的直流有刷电机。这种电机有两个显著特点当通电时会持续旋转调换电源极性就能立即反转。在实际项目中我们常用它来驱动智能小车的车轮、机械臂的关节或者传送带的滚轮。电机内部的核心是绕有线圈的转子和永磁体构成的定子。当电流通过电刷流入转子线圈时会产生电磁场与永磁体相互作用推动转子旋转。这里的电刷通常采用石墨材料就像铅笔芯一样柔软既能导电又不会在频繁摩擦中损坏换向器铜片。我拆解过不少报废的电机发现电刷磨损是常见故障点这也解释了为什么高质量电机都会用弹簧持续压紧电刷。在实际接线时有个有趣现象如果直接把电机接上电池它会以最大转速狂转。但若想精确控制就需要PWM脉冲宽度调制技术。这就像用开关快速通断电路通过改变通电时间的比例来调节平均电压。举个例子假设PWM频率是1kHz每秒开关1000次当50%占空比时相当于电机只获得了一半的电压转速自然就会下降。2. H桥驱动电路详解要让电机既能正转又能反转H桥电路是必不可少的。这个名称来源于电路形状像字母H——四个开关管分布在上下左右电机横跨中间。我最早用面包板搭建H桥时就因同时导通同侧开关管烧毁了好几个MOSFET后来才明白防直通保护有多重要。现代驱动芯片如EG2104S已经帮我们解决了这个难题。它内部集成了死区时间控制确保上下管切换时有几百纳秒的间隔。就好比十字路口的红绿灯必须保证一个方向完全变红后另一个方向才能变绿。实测用EG2104S驱动24V/5A的电机芯片温升只有30℃左右比早期用分立元件搭建的电路稳定得多。自举电路是另一个精妙设计。它仅用一颗二极管和电容就实现了高压侧驱动原理类似水车当下管导通时电容被充电切换至上管导通时电容放电提供驱动电压。我在PCB布局时会把自举电容尽量靠近芯片放置过长的走线会导致驱动能力下降。以下是典型接线参数元件规格备注自举二极管1N4148快恢复型自举电容100nF/50V陶瓷电容X7R材质栅极电阻10Ω抑制振铃现象3. STM32的PWM配置实战STM32的定时器功能强大但配置复杂我推荐使用CubeMX工具生成初始化代码。以TIM1为例要产生20kHz的PWM信号适合大多数直流电机时钟配置如下// 时钟树设置 HCLK 168MHz APB2 prescaler 2 → TIM1时钟84MHz PWM频率 84MHz/(8400*100) 20kHz // 关键寄存器配置 TIM1-ARR 8400-1; // 自动重装载值 TIM1-PSC 100-1; // 预分频值 TIM1-CCR1 4200; // 初始占空比50%在代码中动态调整占空比有个技巧直接修改CCRx寄存器会比调用HAL库函数快得多。我在做平衡车项目时就发现用TIM1-CCR1 value比__HAL_TIM_SET_COMPARE()节省了0.5μs的执行时间这对需要快速响应的控制很重要。高级定时器如TIM1还支持互补输出和刹车功能。互补输出可以驱动H桥的两侧而刹车引脚能在紧急情况下快速关断输出。有次调试时电机突然卡死正是刹车功能防止了驱动芯片过热烧毁。建议在初始化时开启这个功能TIM1-BDTR | TIM_BDTR_MOE | TIM_BDTR_BKE; TIM1-BDTR | (0x0F TIM_BDTR_BKP_SHIFT); // 设置刹车有效电平4. 完整电机控制系统实现把各个模块组合起来时软件架构设计很关键。我的经验是采用分层结构底层硬件驱动、中间控制算法、上层用户接口。下面这个状态机模型在多个项目中验证过可靠性[按键扫描] → [指令解析] → [速度规划] → [PWM输出] ↑ ↓ [编码器反馈] ← [PID计算] ← [电流检测]具体到代码实现可以用结构体封装电机参数typedef struct { uint16_t target_speed; // 目标转速RPM uint16_t current_speed; // 当前转速 int32_t position; // 编码器累计位置 uint8_t direction; // 0-正转 1-反转 PID_Params pid; // PID参数结构体 } Motor_TypeDef;按键处理建议采用状态机方式而非简单延时消抖。下面这种实现能识别长按和短按void Key_Handler(void) { static uint8_t key_state[5] {0}; // 每个按键独立处理 for(int i0; i5; i) { if(按键按下) { if(key_state[i] 255) key_state[i]; } else { if(key_state[i] 20) { // 长按触发 // 执行长按功能 } else if(key_state[i] 2) { // 短按触发 // 执行短按功能 } key_state[i] 0; } } }最后提醒几个容易踩坑的细节电机电源与MCU要共地PWM信号线最好用双绞线大电流走线宽度至少2mm。曾经有个项目因为地线环路导致PWM信号异常电机时不时抽风似的乱转后来用磁珠隔离数字地和功率地才解决问题。