L298N 电机驱动:Arduino 正反转与 PWM 调速

Cartoon of a red L298N motor driver board with a black heatsink and blue screw terminals wired to a blue Arduino Uno on a sensor shield and two silver DC motors

在 L298N 上,方向和速度是由不同的引脚管的。IN1 高、IN2 低,电机往一个方向转;IN1 低、IN2 高,就往另一个方向转;而 ENA 上的 analogWrite() 决定它转多快。绊住大多数人第一次开机的,是 ENA 出厂就套着一顶黑色跳线帽——不把它拔掉,你写的调速命令一点作用都没有。

IN1 和 IN2 到底在叫 L298N 做什么?

L298N 模块的核心是 ST 的 L298 双全桥驱动芯片,而所谓全桥,就是围着电机排成 H 形的四个开关。合上左上和右下这一对,电流就从一个方向穿过电机;合上另一条对角线,电流就反过来穿。电源本身的极性从头到尾都没变——变的只是电机横跨在它两端的方向。所以 IN1 和 IN2 其实是两个位,而两个位有四种状态。

ENA IN1 IN2 电机的表现
HIGH HIGH LOW 往一个方向转
HIGH LOW HIGH 往另一个方向转
HIGH LOW LOW 刹车——立刻停住
HIGH HIGH HIGH 刹车——立刻停住
LOW 任意 任意 惯性滑行——自由停车

只要 IN1 和 IN2 电平一样,电机两端就被接到同一条电源轨上,等于把电机自己短路了——而转动中的电机就是一台发电机。发电机接到短路上会推出电流,电流产生扭矩,这个扭矩正好和转向相反。所以 00 和 11 都是刹车,两者都不是「关掉」。

真正的关来自使能脚。把 ENA 拉低,四个晶体管同时断开。绕组里存着的电流再也没有被驱动的通路,只能反过来经板上的续流二极管流回电源,电源顶着它,几乎瞬间就把它耗光——没有电流也就没有制动扭矩,于是转子自己慢慢滑行停下。ST 自家的真值表把这个状态叫作 “Free Running Motor Stop”。刹车是输入脚的状态,惯性滑行是使能脚的状态。ENB、IN3 和 IN4 对第二路电机重复同样的一切。

选配:一支万用表

ItemPriceQty
XL830L Digital Multimeter with backlight Portable Multimeter Electronics ProjectXL830L Digital Multimeter with backlight Portable Multimeter Electronics ProjectMULTIMERM25.95

它让两项五秒钟的检查变得很简单:分辨每顶跳线帽下面哪一个是使能脚、哪一个是 +5V 脚,以及量出电桥真正送到电机上的电压。

卡通图:H 桥的四种状态——电流从一个方向穿过银色电机、从另一个方向穿过、短路成制动回路,以及四个开关全部断开的惯性滑行
同样的四个开关做出全部四种行为:一条对角线、另一条对角线、两端短接在一起刹车,以及全部断开让它滑行。

为什么对 ENA 用 analogWrite() 却没有反应?

L298N 的逻辑排针一共八个位置:两头各有一组两针的排针,各自套着一顶黑色短接帽——靠近三位螺丝端子的那组是 ENA,最远端的那组是 ENB——中间夹着四个 IN 脚。跳线帽把它下面两个针短接起来,而一份这块板的电路拆解写得很明白:ENA 和 ENB 的跳线「把它们接到 +5V 电源平面上拉高」。使能已经被硬件一直按在 HIGH 上,你的 PWM 引脚根本没有东西可以使能了。把两顶帽子都拔下来收好。

接着要分清那两个裸露出来的针,因为它们长得一模一样。板子断电,万用表打到通断档:一支表笔按在 +5V 螺丝端子上,另一支分别去碰这两个针。响的那个,就是跳线帽原本桥接过去的 +5V 那一侧;它旁边那个才是使能输入,你的杜邦线要接的就是它。这十秒钟很值得:万一线接到了 +5V 针上,你的 sketch 第一次把那个 Arduino 引脚拉低时,就等于经由 Arduino 自己的输出管,把板子的 5V 电源轨直接短到地。

人们接下来常试的,是改成对 IN1 做 PWM。那是另一种控制。ENA 上的 PWM 是在驱动惯性滑行之间切换:每一个关断片段都让四个开关全部断开,存着的电流经板上的续流二极管续流,转子靠自己的惯性继续走。而 IN2 保持 LOW、改对 IN1 做 PWM,则是在驱动刹车之间切换,因为 IN1 一低下去,两个输入就相同了——每一个关断片段都在跟你刚推起来的转子较劲。换个方向,IN2 变成 HIGH,于是高电平片段反而成了刹车,占空比的意思整个反过来。速度属于使能脚:只有它的含义不会随方向翻转。

卡通特写:镊子把黑色跳线帽从红色 L298N 板的银色排针上取下,橙色万用表表笔正在量它与蓝色螺丝端子之间的通断
出厂就装着的跳线帽把使能脚永久拉高。先把它拔掉,再让每个裸露的针对 +5V 端子响一下——响的那个是 +5V,另一个才是你的使能输入。

L298N 要怎么接到 Arduino Uno 上?

L298N 的六个控制脚都是公针,直挺挺地立在 PCB 上——而 Arduino Uno 上每一排都是母座,而且这几根立着的针也让模块插不进面包板。Sensor Shield V5.0 扩展板把这件事解决掉:它压在 Uno 的排座上,把每个数字脚以 G/V/S 三针一组的形式重新引出成公的 S 针,于是普通的母对母杜邦线就能把公针接到公针,一处都不用焊。六个信号全部落在相邻的两个区块上,11 10 9 87 6 5 4

动手接线之前,L298N 上有三顶跳线帽要拔掉:上一节里你已经拔掉的 ENA 和 ENB,加上三位螺丝端子旁边那顶 5V 跳线帽——它下面自己有一整节。现在就把第三顶拔掉,因为正是拔掉它,才让 +5V 端子从输出变成输入;帽子还套着就从 Arduino 往那里喂电,正是烧掉这些板子的典型死法。

L298N 接到 用什么线
ENA(跳线帽已拔) 「10」那一列的 S 针 → D10 母对母杜邦线
IN1 「8」那一列的 S 针 → D8 母对母杜邦线
IN2 「7」那一列的 S 针 → D7 母对母杜邦线
ENB(跳线帽已拔) 「9」那一列的 S 针 → D9 母对母杜邦线
IN3 「6」那一列的 S 针 → D6 母对母杜邦线
IN4 「5」那一列的 S 针 → D5 母对母杜邦线
+5V 螺丝端子 扩展板任意一个 V 针 → Uno 5V 母对母再串一根公对公
GND 螺丝端子 扩展板任意一个 G 针 → Uno GND 母对母再串一根公对公
+12V 螺丝端子 DC 母座中心针那一条引线 镀锡裸线
GND 螺丝端子 DC 母座的另一条引线 镀锡裸线
OUT1 / OUT2 第一颗电机的红线和黑线 镀锡裸线
OUT3 / OUT4 第二颗电机的红线和黑线 镀锡裸线

有两行需要换一下公母。螺丝端子夹的是裸露的金属,而母头杜邦线把金属藏在胶壳里,所以拿一根公对公杜邦线插进母对母线空着的那一头,再把它的方针压在螺丝底下拧紧。GND 螺丝要吃两根线:适配器的负极,和这条共地连线,所以拧完之后两根都拉一拉试试。哪根电机线进 OUT1、哪根进 OUT2,随你决定:如果轴转错方向,把这两根线对调,或者在 sketch 里把那个布尔值翻过来。

共地那根线不是可选项。HIGH 只有相对于一个参考点才有意义,所以在 Uno 和 L298N 共地之前,模块根本不知道 IN1 上的 5V 算什么——驱动板完全不理会 Arduino,多半就是这个原因,而不是板子坏了。也要看清楚这根线负责什么:电机电流是经 GND 端子流回适配器的,绝不会穿过 Uno。这种电机在额定 3V 下每颗只吃 12mA,但一旦堵转就是它的许多倍,而 Uno 的 5V 脚不是你想拿来试这件事的地方。

安全,这一段没有一句是小题大做。这里全部是低压直流;5V 适配器是密封件,永远不要拆开。DC 母座尾线接上之前先量一下——从母座的中心针量通断,就能找出正极那一根,而这款适配器是中心正极。电源还带着电的时候,绝对不要拔电机线:切断线圈里的电流会产生电压尖峰,而续流二极管只保护完整的回路。这么小的电流下散热片只是微温,但一旦电机吃到安培级的电流,它会烫到伤手,所以伸手之前先看一眼。

如果你想先看看板子接好、电机真的转起来的样子,再动自己的螺丝,DroneBot Workshop 的 L298N 实作影片用的就是这套硬件:

5V 的方案为什么一定要拔掉 5V 跳线帽?

L298N 上还有第三顶跳线帽,是三位螺丝端子旁边独立的一组两针短接帽。套着的时候,它把电机电源送进板载的 78M05 稳压器,由它做出逻辑用的 5V,再从 +5V 端子送出来——在 12V 电源上这很完美,在 5V 电源上却办不到。78M05 大约需要两伏的压差余量,所以 5V 进去,出来的更接近 3V,而 L298 的逻辑供电脚规定最低 4.5V。低于这个值,ST 对芯片怎么读 IN1 或 ENA 不作任何保证——而且它不会干脆地坏掉,因为电机拉的正是稳压器赖以工作的那条电源轨,所以每一次负载冲击都会把逻辑供电一起拽下去。表现出来,就跟你的 sketch 有 bug 一模一样。

把跳线帽拔掉,同一份拆解文章说 +5V 端子「变成一个接受外部供电的输入口」。从 Uno(这里靠 USB 供电)经扩展板任意一个 V 针给它送去真正的 5V,逻辑供电就稳稳落在数据手册要求的位置上。扩展板上那顶黄色 SEL 跳线帽保持出厂状态、不要动:正是这条连接把它的 V 针接到 Uno 的 5V。

如果 L298N 自己的 5V 跳线帽还套着,同时又往那个端子送电,你就等于把 Uno 的 5V 直接接到了 78M05 的输出脚上:两个稳压器把同一个节点顶在略有差别的电压上,只要还连在一起,强的那个就一直往弱的那个里灌电流,而它们谁也不是设计来吸收这股电流的。这就是这些板子最常见的死法。

L298N 为什么会在电机之前损失大约两伏?

L298 的输出级是达林顿对——两个双极型晶体管叠起来放大电流——而达林顿管没办法把输出一路拉到自己的电源轨。H 桥里的电流要串着穿过两个达林顿级,一个从电源拉出、一个往地里灌入,所以这笔过路费你要付两次。ST 在 1A 下给的数字是:拉电流侧典型 1.35V,灌电流侧典型 1.2V,而「总压降」那一行的最小值是 1.80V,1A 时最大 3.2V,2A 时 4.9V。把最小值那一栏再看一遍——就算发挥到最好,这颗芯片在 1A 下也要给自己留 1.8V。

小电机吃的电流小得多,压降也随电流下降,但永远不会降到零:电流照样要爬过一个个基射结,无论流过的多小,每一个都要收走它那一份电压。在玩家级的电流下,就按电桥内部损失大约 1.5–2V 来算。这正是 L298N 的作品常常让人觉得没力气的原因。

所以:电源要挑得比你希望加在电机上的电压高出大约两伏。我们这颗电机的额定是 1.5V 到 5V、标称 3V,配 5V 适配器差不多落在 3.5V——正好在它的额定范围里。9V 电源会把大约 7.5V 加在一颗上限只有 5V 的电机上;在这里更大不等于更安全,那是把绕组煮熟的做法。手上已经有 12V 电源?用一颗 LM2596 降压模块把它调下来。然后在你自己的板子上量一量:让电机以满占空比转着,用直流电压档量 +12V 端子对 GND,再量 OUT1 和 OUT2 之间。两者的差就是电桥留给自己的那一份(档位和表笔怎么摆,可以看我们的万用表使用教程)。

卡通图:从黑色电源适配器出来的青色电压带,在抵达银色直流电机之前被两个黑色晶体管符号各咬掉一个楔形缺口
串联的两个达林顿级,一个拉电流、一个灌电流,在电机看到任何东西之前先把自己那一份变成热量拿走——这正是电源要按高于电机额定电压来选的原因。

L298N 的 Arduino 代码长什么样?

Uno 的 analogWrite() 不需要任何 library,而 D10 和 D9 是刻意挑的:两个脚都挂在 Timer1 上,频率大约 490 Hz,所以两路的表现完全一致。5 脚和 6 脚跑在接近 980 Hz 的另一个定时器上,而那个定时器同时在驱动 millis(),会让它们的占空比失真——所以这里让它们只负责单纯的方向输出。

// L298N 双 H 桥:方向在 IN 脚上,速度在 EN 脚上。
// 先把 ENA 和 ENB 上的黑色短接帽拔掉。帽子还套着的时候,
// 使能脚被接在板子的 +5V 平面上,对它做 analogWrite()
// 已经没有东西可以切换 - 电机只会一直全速转。

const int ENA = 10;   // PWM 脚,Timer1,约 490 Hz
const int IN1 = 8;
const int IN2 = 7;

const int ENB = 9;    // 同样是 Timer1 上的 PWM 脚,两路才会一致
const int IN3 = 6;
const int IN4 = 5;

// 5V 电源在电桥里大约损失 1.5V,所以满占空比时加在电机上的
// 大约是 3.5V。这颗电机自己的下限是 1.5V,而满量程的 1.5 / 3.5
// 就是 255 * 1.5 / 3.5 = 109 个计数。低于大约 110,平均电压
// 就掉到那个下限以下,电机往往只会停在原地嗡嗡响。
const int MIN_DUTY = 110;
const int MAX_DUTY = 255;
const int KICK     = 200;   // 短促推一下,帮它挣脱静止时的静摩擦

// EN 拉低会同时断开这一路电桥的四个晶体管:电机两端都浮空,
// 没有电流可以循环,转子就靠惯性慢慢停下来。
void coast(int en) {
  digitalWrite(en, LOW);
}

// 两个 IN 脚电平相同、而电桥又是使能的,就把电机两端接到了同一条
// 电源轨上。转动中的电机是一台发电机,而这里它是一台接到自己
// 短路上的发电机 - 那股电流就是制动扭矩。
void brake(int en, int inA, int inB) {
  digitalWrite(inA, LOW);
  digitalWrite(inB, LOW);
  digitalWrite(en, HIGH);
}

// 1,0 是一个方向,0,1 是另一个方向。速度永远不碰这两个脚。
void drive(int en, int inA, int inB, bool forward, int duty) {
  digitalWrite(inA, forward ? HIGH : LOW);
  digitalWrite(inB, forward ? LOW  : HIGH);
  analogWrite(en, constrain(duty, 0, MAX_DUTY));
}

void ramp(int en, int inA, int inB, bool forward, int from, int to) {
  int stepDir = (to >= from) ? 1 : -1;
  for (int duty = from; duty != to; duty += stepDir) {
    drive(en, inA, inB, forward, duty);
    delay(15);
  }
  drive(en, inA, inB, forward, to);
}

void setup() {
  Serial.begin(9600);

  const int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
  for (unsigned int i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) {
    pinMode(pins[i], OUTPUT);
    // L298 数据手册要求电机电源上电之前、断电之前,Enable 都要是
    // LOW。一开始就把所有脚拉低,正好满足这一点。
    digitalWrite(pins[i], LOW);
  }

  Serial.println(F("L298N ready: channel A on D10/D8/D7, channel B on D9/D6/D5"));
}

void loop() {
  Serial.println(F("A forward - kick, then settle to the slowest duty that still turns"));
  drive(ENA, IN1, IN2, true, KICK);
  delay(200);
  ramp(ENA, IN1, IN2, true, KICK, MIN_DUTY);
  delay(1500);

  Serial.println(F("A forward - ramp up to full"));
  ramp(ENA, IN1, IN2, true, MIN_DUTY, MAX_DUTY);
  delay(1500);

  Serial.println(F("A brake - the shaft stops dead"));
  brake(ENA, IN1, IN2);
  delay(1200);

  Serial.println(F("A reverse at full, B forward at half - both bridges at once"));
  drive(ENA, IN1, IN2, false, MAX_DUTY);
  drive(ENB, IN3, IN4, true, 128);
  delay(2000);

  Serial.println(F("A and B coast - both shafts freewheel down"));
  coast(ENA);
  coast(ENB);
  delay(2500);
}

把每一轮结尾的刹车和惯性滑行对照着看:刹车会在不到一圈的角度里把轴钉死,惯性滑行则让它花上一两秒慢慢转停。

我们从真实客户身上看到的常见错误

L298N 最常传到我们这里的情况,是电机卡在同一个速度上——代码没错,D10 那根线也没接错,使能跳线帽还套着。紧跟在后面的,是驱动板完全不理会 Arduino,这几乎总是少了共地,而不是板子坏了。

再来是数值调小时只嗡嗡响却不转的电机:在这套配置里,低于大约 analogWrite(110),平均电压就落到电机自己 1.5V 的下限以下,所以对的做法是先短促地推一下再降回来,而不是换更大的电源。还有最花钱的那一种——因为端子上丝印写着 +12V 就去买了 12V 适配器。那个标注说的是常见情况,既不是上限,也不是指示:这个脚就是电机电源输入,5V 到 35V 都吃得下——真正决定你买哪个适配器的,是你电机的额定电压加上电桥的压降。

常见问题

为什么不管我给 ENA 写什么,L298N 都全速转?

ENA 上那顶黑色短接帽还套着。它把使能脚桥接到板子的 +5V 平面上,让电桥一直开着,于是 analogWrite() 已经没有东西可以切换。把它拔掉;如果你用第二路,ENB 上那顶也一起拔。

我可以改成对 IN1 做 PWM 吗?

电机是会动,但那是另一种控制:IN2 是低电平时 IN1 一低下去,两个输入就相同了,结果是刹车而不是惯性滑行。而且换方向时它还会反过来,因为 IN2 变成 HIGH 之后,高电平片段反倒成了刹车。

L298N 会损失多少电压?

电流要串着穿过两个达林顿级,一个拉电流、一个灌电流。ST 规定 1A 下的总压降最小 1.80V、最大 3.2V。在玩家级的几十毫安下更接近 1.5–2V,所以电源要选得比电机额定电压高出大约两伏。

模块上的 5V 跳线帽该不该拔掉?

只要电机电源低于大约 7V 就拔掉:78M05 没办法用 5V 的输入做出 5V,而 L298 的逻辑供电至少要 4.5V。拔掉之后,+5V 端子就变成一个由 Arduino 供电的输入。9V 或 12V 电源可以让它套着,但也别高太多:78M05 会把电压差全部当成热量烧掉,所以 24V 电源、又从那个端子取用 200mA,等于在一颗自己没有散热片的小贴片稳压器里塞进将近四瓦。

L298N 能把电机稳在一个精确的转速上吗?

不能——analogWrite() 设定的是占空比,不是转速,所以电机一带上负载就会慢下来,而且没有任何东西会告诉 Arduino。要把这个环闭起来,需要一颗会自己报告转动情况的电机,比如我们的带编码器的 TT 减速电机,它那条六线 JST 尾线要配对应的插座,而不是杜邦线。至于驱动的选择:只要单向的话,一颗 MOSFET 就够;单极性步进电机要的是达林顿阵列;而这块板正是我们循线小车指南里的中枢。

最后更新:2026年8月。有问题?WhatsApp 联系我们

Leave a Reply

Your email address will not be published. Required fields are marked *