第1章:电机控制基础

1.1 直流电机原理

直流电机,说白了就是最基础的电机类型。你给它通上电,它就转。方向反了,它就反转。电压高了,它就转得快。就这么简单。

但简单归简单,咱们得搞清楚它为什么能转。我刚开始做电机控制时,总觉得这东西就是个黑盒子,通电就转呗。直到有一次调试一个精密定位系统,电机怎么都停不准位置,我才老老实实回去翻电机原理。

直流电机的核心结构其实就三部分:

  • 定子 —— 外壳上的永磁体或励磁绕组,产生固定磁场
  • 转子 —— 中间转动的部分,上面绕有线圈
  • 换向器 —— 这个很关键,它负责切换电流方向

为什么会转?电流通过转子线圈,在定子磁场中受到安培力,产生力矩。换向器保证线圈转到不同位置时,电流方向自动切换,力矩方向始终一致。嗯,这里要注意,换向器是有刷电机的标志,无刷电机用的是电子换向。

我在项目中遇到过一个问题:有刷电机用久了,换向器和碳刷磨损,接触电阻变大,电机就开始抖。后来我养成了一个习惯——但凡用到有刷电机,一定预留碳刷更换周期。

核心公式:

转速 n = (U - I×R) / (Ke×Φ)

其中 U 是电压,I 是电流,R 是电枢电阻,Ke 是电机常数,Φ 是磁通量。

说白了,电压越高转速越快,负载越大转速越慢。

1.2 H桥驱动电路

电机要正反转,怎么办?H桥就是干这个的。

你想想看,一个电机两端,如果左边接正极、右边接负极,它正转。反过来接,它就反转。H桥就是用四个开关管(通常是MOSFET)搭成一个"H"形状的电路,通过控制哪两个管子导通,来决定电流方向。

我画了一张图,帮你理解H桥的工作逻辑:

H桥驱动电路原理图 Q1 Q2 Q3 Q4 M 电机 VCC (+) GND (-) 正转:Q1+Q4导通 反转:Q2+Q3导通

H桥的四种工作状态:

Q1Q2Q3Q4电机状态
ONOFFOFFON正转
OFFONONOFF反转
OFFOFFOFFOFF停止(惰行)
ONONOFFOFF刹车(短路制动)

⚠️ 致命陷阱: 绝对不能让 Q1 和 Q2 同时导通,或者 Q3 和 Q4 同时导通!这叫"直通",相当于把电源正负极直接短路。我曾经见过一个新手,代码里延时没写对,两个管子同时开了0.5毫秒,MOSFET直接冒烟。嗯,从那以后我写H桥驱动代码,第一件事就是加死区时间。

1.3 PWM调速控制

电机速度怎么调?调电压。但实际电路中,我们很少用可调电源。更常用的办法是——PWM。

PWM,脉冲宽度调制。说白了就是:把电源以很高的频率开关。开的时间长,平均电压就高,电机转得快。开的时间短,平均电压就低,电机转得慢。

关键参数就两个:

  • 频率 —— 开关的快慢。我一般用1kHz到20kHz。低于1kHz电机会"嗡嗡"响,高于20kHz人耳听不到,但MOSFET开关损耗会变大。
  • 占空比 —— 开的时间占总周期的比例。0%就是全关,100%就是全开,50%就是一半电压。

我个人习惯,PWM频率选10kHz左右。为什么?因为人耳听不到这个频率的噪声,而且大多数MOSFET在这个频率下效率还不错。

💡 经验之谈: 占空比不要从0%直接跳到100%。电机启动电流很大,容易烧驱动。我一般做软启动——占空比从0%慢慢升到目标值,每10ms增加5%。这样电流平缓,电机寿命也长。

用C语言控制PWM,其实就是操作定时器的比较寄存器。以STM32为例:

// 初始化PWM,频率10kHz,定时器时钟72MHz
// 预分频器 72-1,自动重装值 100-1
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;      // 72MHz / 72 = 1MHz
TIM_TimeBaseStructure.TIM_Period = 100 - 1;         // 1MHz / 100 = 10kHz
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

// 配置PWM通道1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 50;                 // 初始占空比50%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);

TIM_Cmd(TIM3, ENABLE);

// 运行时修改占空比
void set_motor_speed(uint8_t duty) {
    // duty范围 0~100
    TIM_SetCompare1(TIM3, duty);
}

这段代码看着简单,但实际项目中坑不少。我记得有一次,我写了个电机控制程序,占空比设到100%时电机反而不转了。查了半天,发现是定时器自动重装值设成了99,而占空比设了100,比较器永远匹配不到。嗯,边界条件一定要测。

1.4 电机方向控制

方向控制,其实就是控制H桥里哪两个管子导通。在代码层面,我习惯用两个GPIO引脚来控制:一个叫DIR(方向),一个叫EN(使能)。

逻辑是这样的:

  • EN = 1, DIR = 0 → 正转
  • EN = 1, DIR = 1 → 反转
  • EN = 0 → 电机停止

但实际硬件连接上,我建议用四个独立的GPIO分别控制四个MOSFET。这样灵活性最高,还能实现刹车和惰行。

下面是我常用的电机控制函数:

// 电机控制结构体
typedef struct {
    uint8_t pwm_duty;      // 0~100
    uint8_t direction;     // 0:正转, 1:反转
    uint8_t brake;         // 0:惰行, 1:刹车
} MotorControl_t;

void motor_control(MotorControl_t *mc) {
    // 先关所有管子,防止直通
    GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);
    
    if (mc->brake) {
        // 刹车模式:上下管同时导通
        GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_2);  // Q1和Q3导通
        return;
    }
    
    if (mc->pwm_duty == 0) {
        // 占空比为0,电机惰行停止
        return;
    }
    
    // 设置PWM占空比
    set_motor_speed(mc->pwm_duty);
    
    // 设置方向
    if (mc->direction == 0) {
        // 正转:Q1常开,Q4用PWM
        GPIO_SetBits(GPIOA, GPIO_Pin_0);   // Q1导通
        // Q4由PWM控制(已在定时器配置中设定)
    } else {
        // 反转:Q2常开,Q3用PWM
        GPIO_SetBits(GPIOA, GPIO_Pin_1);   // Q2导通
        // Q3由PWM控制
    }
}

🔑 关键点总结:

  1. 改变方向前,一定要先停止PWM输出,等电机停稳再切换。否则容易烧MOSFET。
  2. 刹车不是立刻停住,电机有惯性。如果需要精确定位,得加编码器做闭环控制。
  3. PWM频率和电机电感要匹配。电感小的电机用高频PWM,电流纹波小。

说到方向切换,我踩过一个坑。有一次做AGV小车,电机正反转切换太频繁,结果MOSFET驱动芯片过热保护了。后来加了切换延时,每次方向切换至少间隔50ms,问题就解决了。你想想看,电机从正转切换到反转,电流方向瞬间改变,产生的反电动势会很大。不加延时,驱动芯片扛不住。

好了,这一章的内容就这些。直流电机原理、H桥驱动、PWM调速、方向控制,这四个知识点是电机控制的基础。搞懂了这些,后面学步进电机、伺服电机、闭环控制,都会轻松很多。


公众号:蓝海资料掘金营,微信deep3321