1. 先搞清楚L298N是什么,再谈接线和代码
很多朋友第一次接触电机驱动,不管是做小车、机械臂还是智能家居项目,都会遇到L298N这块板子。名字听起来高大上,其实拆开看就是一颗双路H桥驱动芯片,加上外围电路和散热片,做成了一块方便接线的模块。它的作用是把主控板的弱电信号放大成电机需要的强电电流,同时通过信号控制电机的正转、反转和调速。
我最早用L298N是在做一辆两驱循迹小车的时候。当时手头没有专用的电机驱动 shield,看了几篇教程就选了这块板子。上手之后发现,接线并不复杂,真正让人懵的是供电那部分:为什么需要两组电源?为什么共地出了问题,电机就是不转?这些坑踩过一遍之后,我基本上把这块板子的脾气摸透了。这篇帖子就按照“原理 — 接线 — 代码 — 排错”的顺序,把L298N的完整玩法写清楚,适合刚接触嵌入式开发、准备做小车或者自动控制类项目的朋友参考。
1.1 L298N内部到底是个什么东西
L298N模块的关键是ST公司生产的L298N芯片,它内部集成了两个H桥电路。H桥这个名字你可能听过,它本质上是四个开关管组成的桥式结构,电机接在桥的中间。通过控制四个开关管的导通组合,可以改变电机两端的电压方向,从而让电机正转或者反转。四个开关管不能同时导通同一侧,否则电源直接短路,这个在硬件设计上已经处理好了,我们正常使用不用过度担心。
模块上有几个关键接口:
- VCC:逻辑电源正极,一般是5V,给芯片内部逻辑电路供电。
- GND:公共地。
- VMS / 12V:电机电源正极,一般接电机的主供电,比如7-12V电池组。
- OUT1 / OUT2:A路电机输出。
- OUT3 / OUT4:B路电机输出。
- ENA / ENB:A路和B路的使能端,用来输入PWM信号调速。
- IN1 / IN2 / IN3 / IN4:控制信号输入端,决定电机的转动方向。
模块上还有一个5V输出端子,如果电机电源是12V,可以从这里取5V给主控板供电。这个功能很方便,但是实际使用时要注意电流限制,我后面会细说。
1.2 什么时候选L298N比较合理
L298N作为一款经典的电机驱动方案,最大的优势是便宜、皮实、资料多。单路持续电流2A,峰值电流3A,对于普通的直流减速电机、TT马达、小型步进电机来说完全够用。两路输出意味着可以同时驱动两个直流电机,正好对应两轮小车的左轮和右轮。
如果你的项目满足下面几个条件,L298N是很稳的选择:
- 电机工作电压在7V到12V之间。
- 单路电机持续工作电流不超过2A。
- 项目处于学习验证阶段,优先考虑成本和可获取性。
- 需要双电机独立控制,完成差速转向或者双轴驱动。
反过来,如果你的电机电流需求很大,或者要求模块体积特别小、效率特别高,那L298N就不太合适了。比如无人机、机器人关节这类对重量和效率敏感的场景,更适合使用集成MOSFET的驱动芯片,比如DRV8833、TB6612这类。TB6612我也用过,它比L298N效率高很多,体积小,但电流能力也小一些,适合1.2A以下的电机。两者怎么选,关键看电机参数和安装空间。
1.3 把电机控制拆成三个问题
学L298N不需要死记硬背引脚,只要记住三件事:
- 给电机供电,也就是给模块的电机电源端接上合适的电池或电源。
- 让逻辑电路工作,也就是接好5V逻辑供电和地线。
- 控制转向和转速,也就是主控板的GPIO口输出高低电平控制方向,输出PWM控制转速。
把这三个问题拆开,后面的接线和代码自然就通了。很多教程喜欢直接甩一张接线图让你照抄,但如果原理没搞懂,一旦遇到不转的情况就很难排查。所以这篇帖子我会把每一步为什么这么接、为什么要共地、为什么PWM要接ENA而不是IN端,全都讲清楚。
2. 接线实操详解:从供电到信号线一次接对
接线是L298N最容易被绕晕的地方。正面看模块,左右两边是电机输出和信号输入,中间是电源端子。不同厂家生产的模块引脚排列可能略有差异,但大的功能划分是一致的。我下面以最常见的板子布局为例讲解。
2.1 供电接线:先分清逻辑电源和电机电源
L298N模块上有两个电源概念,很多人第一次接触时最容易搞混。一个是电机电源,就是真正驱动电机旋转的大电流电源,接在标着VMS或者12V的端子上;另一个是逻辑电源,给芯片内部逻辑电路供电,接在标着VCC或者5V的端子上。
我见过不少新手直接把5V电源接到12V端子,然后说板子没反应。实际上,电机电源决定了电机能跑多快,逻辑电源决定芯片能不能正常工作。两者都要接,而且逻辑电源的电压范围一般是5V到7V,电机电源的范围一般是7V到12V。
这里有一个很常用的省事接法:如果电机电源用的是12V,可以直接把模块上的5V输出引脚引出来给主控板供电。因为L298N模块上自带一个78M05稳压芯片,可以把12V转为5V输出。但要注意,这个5V输出最大只能提供大概几百毫安的电流,带动Arduino或者其他低功耗主控没问题,如果直接给舵机或者大功率传感器供电,稳压芯片会过热保护。
接线的时候还要注意电源的极性。电源端子旁边一般标有正负极符号,接反了轻则不工作,重则烧板。我习惯在电池输出端串一个自恢复保险丝或者船型开关,方便调试时快速断电。
2.2 电机接线与使能跳线帽的处理
L298N有A、B两个通道,每个通道接一路电机。以A路为例,OUT1和OUT2两个端子就是电机的正负极。直流电机两根线没有严格的正反,接反了只是旋转方向反过来,不影响使用。如果你发现电机转向和预期相反,最简单的办法是把这两根线对调。
模块上还有两个跳线帽,分别对应ENA和ENB。跳线帽插上的时候,使能端被直接接到高电平,意味着这路电机始终处于使能状态,此时IN1和IN2的电平组合直接控制电机转动。这种接法适合不需要调速的场景,电机全速运转,方向由IN1、IN2控制。
如果要调速,就需要拔掉跳线帽,把ENA接到主控板的PWM输出引脚上。通过改变PWM的占空比,可以调节电机两端的平均电压,从而控制转速。注意PWM频率对电机运行的声音和扭矩有影响,后面我会专门讲。
还有一个小细节,模块上有输出指示灯,电机运转时灯会亮。如果灯亮但电机不转,大概率是电机电源没接好或者电流不够,这个在排查部分会详细说。
2.3 控制信号接线:主控板怎么连L298N
控制信号线一共六根:IN1、IN2控制A路,IN3、IN4控制B路,ENA、ENB控制使能和PWM调速。实际接线时,只需要把主控板的GPIO引脚和这些端口一一连接即可。
以Arduino Uno为例,典型接法是这样:
- D5接ENA(PWM调速)
- D6接IN1
- D7接IN2
- D8接IN3
- D9接IN4
- D10接ENB(PWM调速)
这样连接之后,代码里可以通过digitalWrite控制IN1、IN2的高低电平组合,实现正转、反转和刹车;通过analogWrite给ENA输出0到255的PWM值,实现调速。
需要注意的是,不同主控板的PWM引脚位置不同。Arduino Uno上标注了“~”符号的引脚才是PWM引脚,比如3、5、6、9、10、11。如果你的开发板PWM引脚不够用,也可以选择用同一路PWM同时控制ENA和ENB,只影响左右轮独立调速,不影响正反转控制。
还有一个容易忽略的问题,就是信号线的电平标准。L298N的逻辑输入兼容TTL电平,也就是3.3V到5V都能识别。如果你用的是树莓派这种3.3V GPIO,直接接L298N通常是没问题的,因为3.3V已经高于高电平阈值。但如果追求稳定,可以通过电平转换模块把3.3V转换成5V信号再接进去。
2.4 共地问题:为什么控制信号不生效
共地(Common Ground)是L298N接线里最让我头疼、也最让新手困惑的问题。所谓共地,就是主控板的GND和L298N模块的GND要连在一起。为什么要这样?因为主控板输出的控制信号是以自己的GND为参考点的,而L298N的逻辑电路以模块的GND为参考点。如果两个地不连在一起,控制信号的电平在L298N看来就是悬浮的,高电平可能不够高,低电平也不够低,逻辑状态就会随机甚至完全失效。
判断是否共地很简单:用一个杜邦线,把Arduino的GND和L298N的GND连起来。哪怕你给L298N供了12V,给Arduino供了5V,只要两个地不在同一个电位上,控制信号就会失灵。这个坑我当年踩过一次:板子供电正常、信号线也都连对了,但电机纹丝不动,检查了一个晚上才发现地线没接。
如果电机电源和主控板共用一个电源,比如都用同一个5V电源适配器供电,那地线理论上已经通过电源共享了。但实际项目中我建议还是单独拉一条地线,避免大电流通过走线时产生压降,干扰逻辑电平。
3. 核心原理与代码实现:从PWM到实际驱动
接线完成之后,进入代码阶段。L298N的驱动逻辑本身不复杂,核心就两个动作:控制方向和控制速度。方向靠IN引脚的逻辑电平组合,速度靠ENA/ENB的PWM占空比。下面我分原理和代码两部分讲。
3.1 电机控制背后的原理:H桥与PWM调速
L298N芯片内部的两个H桥,一个负责一路电机。H桥四个开关管,以A路为例,IN1控制左上和右下两个开关管,IN2控制右上和左下两个开关管。当IN1为高、IN2为低时,电流从OUT1流向OUT2,电机正转;反过来,IN2为高、IN1为低时,电机反转。
如果IN1和IN2同时为高或者同时为低,此时电机两端电压相等,电机会因为惯性继续转一会儿,但很快停下来,这个状态叫“刹车”。如果你想要电机自由滑行,也就是不给它任何外力,可以把ENA使能端设为低电平,让H桥的输出变成高阻态,电机不受驱动控制,自然减速。
PWM调速的本质是快速切换电源的通断。假设电源电压是12V,PWM占空比是50%,那么电机两端平均电压大概是6V,电机的转速也大约是全速的一半。L298N的EN引脚接收PWM信号,实际上就是在控制H桥的输出是否导通,导通的占空比越高,平均电流越大,电机转速越快。
这里有一个经验参数:PWM频率一般建议设置在1kHz到10kHz之间。频率太低,电机会发出明显的嗡嗡声,而且扭矩波动大;频率太高,L298N内部的开关损耗会增加,发热变严重。Arduino的analogWrite默认频率在490Hz左右,虽然听起来有点尖,但对大多数直流电机来说足够用了。如果你要做更精细的调速控制,可以在STM32或者树莓派上通过定时器/软件PWM调整频率。
3.2 Arduino平台代码实现
Arduino是我玩L298N用的最多的平台,因为语法简单、库生态好,特别适合快速验证。直接用GPIO输出高低电平控制方向,用analogWrite输出PWM控制速度,几行代码就能让小车动起来。
下面这段代码实现的功能是:驱动两个电机,先全速前进两秒,然后左转两秒,再后退两秒,最后停止。逻辑非常简单,但包含了方向控制和速度控制两个核心点。
// L298N 电机驱动示例 —— 双电机前进/左转/后退 #define ENA 5 #define IN1 6 #define IN2 7 #define IN3 8 #define IN4 9 #define ENB 10 void setup() { pinMode(ENA, OUTPUT); pinMode(ENB, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); } void loop() { // 前进:A路正转,B路正转,全速 digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(ENA, 255); analogWrite(ENB, 255); delay(2000); // 左转:A路停转,B路正转 digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(ENA, 0); analogWrite(ENB, 200); delay(2000); // 后退:A路反转,B路反转 digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); analogWrite(ENA, 255); analogWrite(ENB, 255); delay(2000); // 停止:所有引脚置低,刹车 digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); analogWrite(ENA, 0); analogWrite(ENB, 0); delay(2000); }代码本身不复杂,但有几点值得注意:
第一,方向组合要统一。你在写代码之前,最好先在纸上明确哪两个引脚控制的一路电机、哪个方向算正转。如果左右轮正转方向不一致,小车会原地打转而不是直线前进。
第二,analogWrite的第二个参数范围是0到255,对应占空比0%到100%。不要写成100,那是占空比约39%,电机会看起来没力。
第三,循环里每次改变方向之前,最好先给一个短暂的刹车或者延时。尤其是高速运转突然反转,电机的反电动势可能对驱动芯片造成冲击。
3.3 STM32 HAL库代码实现
如果要把L298N接到STM32上,思路是一样的,但代码风格完全不同。STM32的GPIO需要初始化模式,PWM需要通过定时器输出。下面以STM32F103系列为例,展示最简配置。
在CubeMX里做如下配置:
- 将PA0、PA1、PA2、PA3设置为GPIO输出,分别接IN1、IN2、IN3、IN4。
- 将PA6和PA7设置为TIM3的通道1和通道2,分别接ENA和ENB,PWM频率设为1kHz。
然后在代码里这样控制:
// 控制A路电机方向:正向 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 控制A路电机速度:占空比60% __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 600); // 控制B路电机方向:反向 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); // 控制B路电机速度:占空比60% __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 600);ARR设置为1000的话,600就代表60%占空比。使用__HAL_TIM_SET_COMPARE修改比较寄存器值,可以实时调整速度,非常方便。如果要做PID闭环控制,这种配置方式是最基础的。
STM32的好处是可以把PWM频率精确控制在几kHz甚至几十kHz,电机运行的噪声明显小于Arduino的490Hz。缺点是需要手动配置定时器,学习曲线比Arduino陡一些。
3.4 树莓派Python代码实现
树莓派用Python控制L298N也很常见,尤其是做视觉小车这类需要跑Python算法的项目。树莓派的GPIO引脚本身是3.3V电平,直接接L298N的逻辑输入一般没问题。但要注意,树莓派的GPIO不能直接驱动L298N的逻辑电源,需要单独供电。
使用RPi.GPIO库或者gpiozero库都可以。下面以RPi.GPIO为例:
import RPi.GPIO as GPIO import time ENA = 12 IN1 = 16 IN2 = 20 IN3 = 21 IN4 = 26 ENB = 13 GPIO.setmode(GPIO.BCM) GPIO.setup(ENA, GPIO.OUT) GPIO.setup(ENB, GPIO.OUT) GPIO.setup(IN1, GPIO.OUT) GPIO.setup(IN2, GPIO.OUT) GPIO.setup(IN3, GPIO.OUT) GPIO.setup(IN4, GPIO.OUT) pwm_a = GPIO.PWM(ENA, 1000) # 1kHz PWM pwm_b = GPIO.PWM(ENB, 1000) pwm_a.start(0) pwm_b.start(0) # 前进,50%速度 GPIO.output(IN1, GPIO.HIGH) GPIO.output(IN2, GPIO.LOW) GPIO.output(IN3, GPIO.HIGH) GPIO.output(IN4, GPIO.LOW) pwm_a.ChangeDutyCycle(50) pwm_b.ChangeDutyCycle(50) time.sleep(2) # 停止 pwm_a.ChangeDutyCycle(0) pwm_b.ChangeDutyCycle(0) GPIO.cleanup()树莓派的PWM由内核的DMA实现,频率可以设置得比较高,1kHz是L298N比较舒服的区间。注意GPIO.setmode要和你实际接线图对应,BCM模式和BOARD模式容易搞混,一旦搞错,控制信号就会输出到错误的引脚上,电机自然不转。
4. 常见问题与排查技巧实录
L298N用了这么久,我总结了一些高频问题的排查方法。这些问题单独看都不算大,但组合在一起,很容易让人怀疑人生。下面我从实际经验出发,一个个说清楚。
4.1 电机不转、转向反了、转起来无力
电机完全不转,首先检查有没有共地。前面说过,这是L298N最经典的坑。其次检查ENA和ENB的跳线帽是不是插好了,没有插好的话,即使IN引脚电平正确,电机也不会动。还有一个容易忽略的地方是电机电源有没有接对,有些电源适配器的输出端有保护,瞬间电流不够,电机就动不起来。
转向反了最简单,交换该路电机的两根输出线即可,或者在代码里交换IN1和IN2的逻辑。如果你不想动线,直接改代码里的高低电平组合也行。
转起来无力,优先检查电源电流是否足够。L298N驱动一个大功率电机时,瞬时电流可能超过电源适配器的供电能力,电压被拉低,电机就会表现出“能转但没劲”的状态。解决方法是换一个电流余量更大的电源,或者在电池两端并一个大电容,比如470uF到1000uF,来缓冲电流尖峰。这个电容我强烈建议加上,它能显著改善电机的启动表现。
4.2 板子发烫:正常还是异常
L298N工作时发热是正常的,芯片上的散热片摸起来有点烫手也不用太紧张。但如果烫到不能碰,那就要检查了。最常见的原因是电机堵转或者电流过大。堵转时,电机电流会飙升到额定值的几倍,L298N内部的H桥开关管会承受很大的功耗,温度快速上升。
因为L298N用双极性晶体管,饱和压降比较大,大概是1.5V到2V,这就意味着它天然比MOSFET方案的驱动效率低。比如2A电流流过时,芯片内部功耗就有3W到4W,这对于芯片来说已经不小了。如果是连续大功率运行,我建议加一个小风扇主动散热,或者降低PWM占空比,让电机不要长时间全速运转。
如果排除了以上因素,板子依然发烫,可以检查VMS供电电压是否过高。L298N的最高电机电源电压是46V,但实际使用超过24V就比较危险了,芯片内部的稳压电路会承受过大的压降。
4.3 干扰复位、误动作问题
电机是典型的干扰源。电刷换向时会产生火花和反电动势,这些噪声会通过电源线和地线传导到主控板,造成主控板复位、传感器数据跳动等问题。我遇到过小车稍微一转,Arduino就自动重启的情况,最后发现是供电线和地线太细,电机电流引起的压降导致主控板电压跌落。
解决干扰问题有几招很有效:
- 在电机电源两端并联一个反向续流二极管,吸收电机换向时产生的反向电动势。
- 在电机两端并联一个0.1uF陶瓷电容,抑制高频噪声。
- 主控板单独供电,或者至少用粗一点的导线给主控板供电。
- 控制信号线尽量远离电机电源线,不要平行走线。
- 必要的话,在共地点用磁珠或者电感隔离数字地和电机地。
最后补充一句,L298N模块本身已经内置了续流二极管,一般不需要额外加。但如果用的是裸芯片自己搭电路,那续流二极管是必须的,不然后端MOS管很容易被电机反电动势击穿。
4.4 快速故障排查表
整理了一张表格,方便现场排查故障时对照。
| 故障现象 | 可能原因 | 排查方法 |
|---|---|---|
| 电机完全不转 | 未共地 | 检查主控GND与模块GND是否相连 |
| 电机完全不转 | 使能跳线帽未插 | 检查ENA/ENB跳线帽是否安装 |
| 电机完全不转 | 电机电源未接或极性接反 | 测量VMS两端电压是否正常 |
| 电机只朝一个方向转 | IN引脚信号无法翻转 | 用万用表量IN1/IN2电平变化 |
| 电机无力 | 电源电流不足 | 更换大电流电源,并联电容 |
| 电机抖动有异响 | PWM频率太低 | 提高PWM频率到1kHz以上 |
| 板子过热 | 电机堵转或占空比过高 | 检查负载,降低占空比,加散热 |
| 主控板自动复位 | 电源压降或干扰 | 独立供电,加续流二极管,优化布线 |
| 控制信号无效 | 主控板电平与L298N不匹配 | 检查是否共地,必要时加电平转换 |
这张表基本覆盖了我实际调试中遇到的大部分问题。如果你碰到的问题不在表里,先别急着怀疑板子坏了,用万用表从电源开始一级一级往下测:逻辑电源电压是否正常、IN引脚能否拉到高电平、OUT端子是否有电压输出、电机端能否测到电压。按照这个顺序排查,大部分故障都能定位。
5. 最后说几点实操心得和扩展方向
L298N这块板子,网上教程非常多,但真正上手之后你才会发现,资料里没写清楚的小细节才决定项目能不能顺利跑起来。根据我个人的经验,再分享几个关键心得。
第一,磨合阶段不要直接上大功率电机。先用小电流的TT马达或者塑胶减速电机调通代码,确认方向控制和PWM调速都没问题,再换大电机。大电机起步电流很猛,对电源和接线都是考验,一开始就跑大功率电机,很容易把接线问题放大,排查起来更痛苦。
第二,接线能短就短,能用粗线就不用细线。电机的大电流路径,也就是电源到模块、模块到电机的这段线,建议使用0.5平方毫米以上的导线。信号线可以用杜邦线,但电源线尽量用来焊锡的排针或者接线端子连接,接触不良是很多诡异故障的根源。
第三,如果要跑闭环控制,L298N最好搭配带编码器的电机使用。这一块我后续也在做。L298N的两路输出正好能驱动两个带编码器的直流减速电机,通过读取编码器脉冲数可以算出实际转速,再用PID调节PWM占空比,小车的直线行驶精度会好非常多。具体来说,可以在Arduino上启用外部中断读取编码器信号,然后周期性计算转速,把目标转速和实际转速的差值丢给PID控制器,输出值再映射到PWM占空比。这样的两轮小车,直线行驶不再需要手动修正方向。
第四,如果你只是做一个短期的学习项目,L298N确实够用。但如果项目要长期运行或者对能效有要求,我更推荐换用TB6612或者DRV8833这类MOSFET方案的驱动模块。它们在轻负载下的发热量小很多,相同占空比下电机的输出扭矩也更大。做产品原型的时候可以用L298N验证逻辑,量产时再换器件也能减少不少麻烦。
最后分享一个小技巧:调试时养成先写一个“点动测试函数”的习惯。也就是单独写一个函数,每次调用时让某个电机以固定方向转200ms,然后停止。这个函数可以帮你快速验证每一路电机和每一路信号线是否正常,之后再写复杂的逻辑就会省很多时间。我的所有L298N项目,第一段代码几乎都是这个点动测试,从不直接上完整流程。