直流电机 PWM 调速:L298N 实战

直流电机 PWM 调速:L298N 实战

为什么你需要掌握直流电机调速?

玩过小车的同学都知道,电机转得快不难,难的是转得刚刚好。太快容易翻车,太慢又没动力。这时候就需要 PWM 调速技术。

今天咱们用 L298N 这个经典的电机驱动模块,手把手教你如何实现直流电机的精准调速。不管你是要做智能小车、机器人底盘,还是简单的风扇控制,这套方案都能用得上。

硬件清单

配件 型号 价格 备注
L298N 电机驱动模块 双 H 桥 ¥15-25 某宝常见款
直流电机 TT 马达/370 电机 ¥8-15/个 3-6V 或 6-12V
Arduino Uno R3 兼容板 ¥25-35 或其他 5V 单片机
18650 电池 3.7V 2600mAh ¥15-20 电机供电
杜邦线 公对公/母对母 ¥5 若干
面包板 830 孔 ¥8 可选

总成本: 约 ¥70-100(不含电池可更低)

L298N 模块详解

接口说明

L298N 模块看起来复杂,其实就几个关键接口:

+12V  ──→ 电机供电正极(5-35V)
GND   ──→ 共地
+5V   ──→ 逻辑供电(跳线帽连接时输出 5V)

ENA   ──→ A 通道使能(PWM 调速用)
IN1   ──→ A 通道输入 1
IN2   ──→ A 通道输入 2

ENB   ──→ B 通道使能(PWM 调速用)
IN3   ──→ B 通道输入 1
IN4   ──→ B 通道输入 2

OUT1/OUT2 ──→ A 通道电机输出
OUT3/OUT4 ──→ B 通道电机输出

工作原理

L298N 内部是两个 H 桥电路,可以控制两个直流电机的正转、反转、停止。通过 ENA/ENB 引脚输入 PWM 信号,就能调节电机转速。

正反转控制逻辑:

IN1 IN2 电机状态
HIGH LOW 正转
LOW HIGH 反转
LOW LOW 停止
HIGH HIGH 停止(刹车)

接线图

Arduino Uno          L298N 模块
-----------          ----------
5V        ──────→    +5V (跳线帽连接时)
GND       ──────→    GND
D9 (PWM)  ──────→    ENA
D8        ──────→    IN1
D7        ──────→    IN2

电池正极  ──────→    +12V
电池负极  ──────→    GND

电机 A    ──────→    OUT1/OUT2

注意事项:

  • 电机供电和 Arduino 供电要共地
  • 如果电机工作电压≤5V,拔掉 L298N 上的 5V 跳线帽,用 Arduino 的 5V 供电
  • 如果电机工作电压>5V,保留跳线帽,L298N 会给 Arduino 反向供电(谨慎使用)

代码示例

基础调速程序

// L298N 直流电机 PWM 调速
// 引脚定义
const int ENA = 9;    // PWM 调速引脚
const int IN1 = 8;    // 方向控制 1
const int IN2 = 7;    // 方向控制 2

void setup() {
  // 设置引脚模式
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);

  // 串口初始化
  Serial.begin(9600);
  Serial.println("L298N 直流电机 PWM 调速测试");
}

void loop() {
  // 正转加速
  Serial.println("正转加速...");
  for (int speed = 0; speed <= 255; speed += 10) {
    analogWrite(ENA, speed);  // PWM 调速 (0-255)
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    delay(200);
    Serial.print("速度:");
    Serial.println(speed);
  }

  // 全速运行 2 秒
  delay(2000);

  // 正转减速
  Serial.println("正转减速...");
  for (int speed = 255; speed >= 0; speed -= 10) {
    analogWrite(ENA, speed);
    delay(200);
  }

  // 停止 1 秒
  Serial.println("停止");
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  delay(1000);

  // 反转加速
  Serial.println("反转加速...");
  for (int speed = 0; speed <= 255; speed += 10) {
    analogWrite(ENA, speed);
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    delay(200);
  }

  // 全速反转 2 秒
  delay(2000);

  // 反转减速
  Serial.println("反转减速...");
  for (int speed = 255; speed >= 0; speed -= 10) {
    analogWrite(ENA, speed);
    delay(200);
  }

  // 停止 1 秒
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  delay(1000);
}

串口控制调速

这个版本可以通过串口输入 0-255 的值来控制电机速度:

// L298N 串口调速控制
const int ENA = 9;
const int IN1 = 8;
const int IN2 = 7;

int motorSpeed = 0;
char direction = 'f';  // f=正转,r=反转,s=停止

void setup() {
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);

  Serial.begin(9600);
  Serial.println("=== L298N 串口调速控制 ===");
  Serial.println("命令格式:[方向][速度]");
  Serial.println("示例:f200 (正转,速度 200)");
  Serial.println("      r150 (反转,速度 150)");
  Serial.println("      s    (停止)");
}

void loop() {
  if (Serial.available() > 0) {
    String cmd = Serial.readStringUntil('\n');
    cmd.trim();

    char dir = cmd.charAt(0);

    if (dir == 's') {
      // 停止
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, LOW);
      Serial.println("电机停止");
    } else {
      // 解析速度值
      int speed = cmd.substring(1).toInt();
      speed = constrain(speed, 0, 255);

      // 设置方向
      if (dir == 'f') {
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        Serial.print("正转,速度:");
        Serial.println(speed);
      } else if (dir == 'r') {
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        Serial.print("反转,速度:");
        Serial.println(speed);
      }

      // 设置 PWM 速度
      analogWrite(ENA, speed);
    }
  }
}

PWM 调速原理

PWM(脉冲宽度调制)是通过快速开关电源来控制平均电压的技术。

占空比 100%: ████████████████████  平均电压 = 5V
占空比 50%: ████████████████      平均电压 = 2.5V
占空比 25%: ████                  平均电压 = 1.25V

Arduino 的 analogWrite() 函数生成频率约 490Hz 的 PWM 信号,占空比范围 0-255:

  • analogWrite(ENA, 0) → 电机停止
  • analogWrite(ENA, 128) → 50% 速度
  • analogWrite(ENA, 255) → 全速

常见问题排查

问题 1:电机不转

可能原因:

  1. 电机供电不足 → 检查电池电压,确保≥5V
  2. 接线错误 → 确认 IN1/IN2 逻辑正确
  3. ENA 跳线帽未拔 → 如果用电机供电>5V,需要保留跳线帽
  4. 电机损坏 → 直接接电池测试电机是否正常

解决方法:

// 测试代码:直接给 HIGH 看是否转动
void setup() {
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  // 如果接了跳线帽,ENA 默认 HIGH
}

问题 2:电机转速异常

现象: 速度调不高,或者低速时抖动

原因:

  1. PWM 频率不匹配 → L298N 适合 1-20kHz
  2. 供电电压不足 → 电机负载大时压降明显
  3. 电刷电机低速特性差 → 这是物理限制

优化方案:

// 提高 PWM 频率(Arduino Uno)
// 引脚 9/10 是 Timer1,默认 490Hz,可改为 31kHz
void setup() {
  TCCR1B = TCCR1B & 0b11111000 | 0x01;  // 设置分频比=1
  // 现在 analogWrite(9, xxx) 频率约 31kHz
}

问题 3:Arduino 复位或工作不稳定

原因: 电机启动电流大,导致电源电压瞬间下降

解决方法:

  1. 电机供电和 Arduino 供电分开(只共地)
  2. 在 L298N 的 +12V 和 GND 之间加 100μF 电容
  3. 使用更大容量的电池

问题 4:发热严重

正常现象: L298N 在大电流下会发热,这是正常的

注意:

  • 持续电流不要超过 2A(峰值 3A)
  • 如果烫手,加散热片或降低负载
  • 考虑升级到 TB6612FNG(效率更高,发热更小)

进阶技巧

1. 软启动/软停止

避免电机突然启停造成冲击:

void softStart(int targetSpeed, int stepTime = 10) {
  for (int s = 0; s <= targetSpeed; s++) {
    analogWrite(ENA, s);
    delay(stepTime);
  }
}

void softStop(int stepTime = 10) {
  for (int s = 255; s >= 0; s--) {
    analogWrite(ENA, s);
    delay(stepTime);
  }
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
}

2. 速度闭环控制(需要编码器)

如果加了编码器,可以用 PID 实现精准速度控制:

// 伪代码示例
int targetSpeed = 100;
int currentSpeed = readEncoder();
int error = targetSpeed - currentSpeed;
int pwmOutput = kp * error + ki * integral + kd * derivative;
analogWrite(ENA, constrain(pwmOutput, 0, 255));

3. 双电机差速转向

智能小车转向的经典方案:

void turnLeft(int speed) {
  // 左电机反转,右电机正转
  setMotor(1, -speed);  // 左
  setMotor(2, speed);   // 右
}

void setMotor(int motor, int speed) {
  int in1, in2, en;
  if (motor == 1) { in1 = IN1; in2 = IN2; en = ENA; }
  else { in1 = IN3; in2 = IN4; en = ENB; }

  if (speed > 0) {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
  } else {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    speed = -speed;
  }
  analogWrite(en, constrain(speed, 0, 255));
}

升级建议

如果你已经玩转了 L298N,可以考虑这些升级方案:

驱动模块 优点 缺点 价格
L298N 便宜、经典、资料多 发热大、效率低 ¥15-25
TB6612FNG 效率高、发热小、体积小 电流较小(1.2A) ¥20-30
DRV8833 双通道、过流保护 需要 3.3V 逻辑 ¥15-25
VNH2SP30 大电流(30A)、保护完善 贵、体积大 ¥50-80

总结

L298N 虽然是个老模块,但作为学习电机控制的入门选择非常合适。掌握了 PWM 调速和 H 桥控制原理,你就能控制绝大多数直流电机应用。

关键知识点回顾:

  1. PWM 占空比控制平均电压,实现调速
  2. H 桥电路控制电流方向,实现正反转
  3. 电机供电和控制供电要共地
  4. 大电流应用注意散热和电源稳定性

下一步可以试试加个编码器做闭环控制,或者用蓝牙/WiFi 实现无线遥控小车。

希望这篇博客文章对您有所帮助!