
简介这是基于正点原子NANO开发板编写的四电机小车控制程序使用STM32F103RBT6芯片和L298N驱动模块。程序演示前进、停止、后退等基本动作依靠板载发光二极管指示当前状态还说明使能端与输入引脚的接线方式以及共地、外部供电等硬件注意点适合学习单片机通用输出控制的开发者参考。该程序对硬件连接和代码流程均有注释便于对照实物排查问题。压缩包共三百八十三个文件大小接近十四点八三兆字节包含C语言源码与头文件、工程配置文件、编译生成的固件文件以及说明文档可直接编译烧录也可按需修改学习。已有六千三百六十五人学习或下载适合入门者、小车爱好者和竞赛备赛者使用并可在现有程序基础上继续扩展调速、避障等功能。 拿到这个“L298N驱动4个电机小车程序.rar”时我第一反应是这不就是一个四驱小车例程吗等我把里面的接线图、程序结构和驱动逻辑完整过了一遍才发现真正有价值的东西藏在外面看不到的地方——4个电机不是简单地“多接两个电机”那么简单它牵扯到驱动模块的拓扑选择、供电回路的设计、PWM分配以及运动控制的底层逻辑。想用L298N这类经典驱动模块把一台四驱小车跑稳绕不开以下几个问题一片L298N到底能不能拖4个电机4个轮子的转向是靠什么算法实现的为什么小车一启动就重启这些问题我在实际调车过程中都遇到过这篇文章就把整个项目从选型到接线再到程序的完整思路拆开来讲适合正在做四驱小车、智能车竞赛底盘或者准备入坑麦克纳姆轮的朋友参考。1. 四电机驱动方案选型为什么L298N仍然值得用1.1 常见的电机驱动模块对比很多新手一上来就问L298N是不是太老了TB6612、DRV8833这些不是更好吗这问题得看场景。L298N内部是两个完整的H桥一片模块能独立控制两路直流电机额定输出电流每路约2A电机供电范围宽模块上还自带5V稳压和螺丝接线端子对DIY小车来说非常友好。TB6612和DRV8833虽然内阻小、发热低但它们的封装普遍偏小电流输出集中在1.2A到1.5A左右带两个小型TT电机够用带到4个大扭矩电机就有点勉强而且焊盘间距小洞洞板接线容易短路。从我实测的经验来看L298N的压降和发热虽然不占优但它耐造、不容易烧调试阶段往往比精细模块更省心。另一个关键点是L298N模块上通常带一只78M05稳压芯片可以从电机电源取电给单片机供电。这个小设计在教学项目和竞赛底盘中很实用少走一根线也让初学者的接线图更简单。1.2 一片还是两片取决于你要“能跑”还是要“会跑”“L298N驱动4个电机”这句话其实有歧义。一种做法是一片L298N控制两个通道每个通道并联两个电机左侧两个电机接一路右侧两个电机接另一路这是最常见也最省事的接法。另一种做法是用两片L298N每片模块控制两个轮子四个电机全部独立控制这样每个轮子的速度和方向都能单独设置。这两种接法区别非常大。并联接法代码简单但同一侧的两个电机只能同速同向转弯时只能靠左右侧速度差来实现无法做到原地旋转也无法升级成麦克纳姆轮全向移动。两片独立控制的方案看起来复杂一些但它能解锁原地旋转、斜向平移、任意半径转弯这些高阶动作后续加传感器做视觉巡线、避障时优势都很明显。我在实际项目中更推荐两片L298N独立控制四路输出。理由是四驱车的价值不只是“力气大”而是四个轮子可以各自干活如果你一开始就用并联方案后面想改成全向移动整套接线和程序几乎要推翻重来。2. 接线和供电四驱小车能不能稳定跑七成看这一步2.1 看懂L298N的引脚与H桥的关系L298N的驱动核心是两路H桥。所谓H桥就是四个开关管组成的电路通过控制开关管的导通组合改变流过电机的电流方向从而控制电机正反转。具体到模块引脚上OUT1和OUT2是一路输出接一个电机OUT3和OUT4是另一路接另一个电机。IN1、IN2控制第一路的方向IN3、IN4控制第二路的方向ENA和ENB是使能端接PWM可以实现调速。要把L298N用明白需要记住两个关键逻辑第一方向和调速是分开控制的IN脚只管电流方向EN脚管PWM占空比第二逻辑电路和功率电路虽然在同一片模块上但工作时必须有公共参考地这也是后面排错时最容易被忽略却最致命的问题。2.2 4电机接线的推荐拓扑下面是我实测比较稳定的一套接线方案使用两片L298N四个电机全部独立控制主控用Arduino UNO模块功能引脚接主控引脚输出端接电机模块AENA5PWMOUT1/OUT2左前电机模块AIN1/IN22 / 3--模块AENB6PWMOUT3/OUT4右前电机模块AIN3/IN44 / 7--模块BENA10PWMOUT1/OUT2左后电机模块BIN1/IN28 / 9--模块BENB11PWMOUT3/OUT4右后电机模块BIN3/IN412 / 13--这样接的好处是每个轮子的PWM通道都是独立的5、6、10、11刚好是Arduino UNO的硬件PWM引脚用analogWrite输出时不会出现定时器冲突。需要注意IN脚和EN脚的功能不能搞混IN脚接普通数字口就行不需要PWM能力。2.3 供电逻辑为什么需要两个电源以及共地的意义L298N模块上有两个电源入口一个是电机电源VS通常接7.4V或11.1V锂电池另一个是逻辑电源VSS一般接5V。很多模块上带有5V输出当电机电源是7.4V以上时可以用这个输出给Arduino供电但如果电机电源偏低或者电池内阻大这个5V在电机启动瞬间会掉得非常厉害导致单片机复位。正确做法是单独给Arduino供电L298N的VSS也从Arduino的5V取然后把三者的GND全部接到一起。所谓共地就是让单片机的“0V”和驱动模块的“0V”是同一个参考点否则PWM信号相对L298N来说就是浮空的模块会乱动作。我测过最典型的现象就是不共地时小车不动用手触摸一下引脚突然开始转没有任何逻辑可言。电池选择方面四驱小车四个电机同时启动瞬间电流能达到每路1A以上干电池在大电流下电压跌落严重强烈建议使用聚合物锂电池容量至少2000mAh倍率5C以上否则小车一跑起来就掉压重启。3. 程序核心逻辑把“四个电机”变成“一个会走的小车”3.1 最小驱动代码先理解一个电机的控制程序这块建议按“一个电机 → 两个电机 → 四个电机”的路径来写。先看单路控制的最底逻辑#define ENA 5 #define IN1 2 #define IN2 3 void setup() { pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); } void setMotorA(int speed) { // speed: -255 ~ 255 if (speed 0) { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); } else if (speed 0) { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); } else { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); } analogWrite(ENA, abs(speed)); }核心逻辑就三件事判断速度的正负号决定IN脚电平组合用abs取速度绝对值作为PWM占空比speed为0时关闭两路IN实现刹车。这里有一个容易被忽略的细节IN1和IN2电平组合不能同时为HIGH否则H桥上下桥臂直通轻则发热严重重则烧驱动芯片。3.2 差速转向转弯的数学模型两驱车转弯靠的是舵机偏转前轮四驱车转弯则基本靠差速也就是左右两侧轮子速度不一样。假设小车前进速度是100要向右转可以让左侧轮子速度保持100右侧轮子降到50要转得急一点右侧轮子甚至可以反转。原地旋转的逻辑更简单左右两侧速度大小相同、方向相反即可。实际调车时差速转弯有个经验值低速0到100时两侧速度差小一点否则小车会明显甩尾高速时速度差要大一些否则转弯半径太大。这个没有固定公式跟轮胎材质、地面摩擦系数都有关系最好把左右电机速度写成两个参数方便在车上现场调。四轮独立控制时转弯还可以更优雅前轮负责转向趋势后轮负责推力分配这样转弯时车身姿态更稳不会出现两驱方案那种“外侧轮子被拖着走”的情况。3.3 麦克纳姆轮运动学四轮独立控制的价值体现你可能会好奇为什么非要把四个电机拆开独立控制答案就在麦克纳姆轮上。麦轮小车的每个轮子都有45度斜向辊子通过四个轮子不同方向的转动组合可以让车体实现前后、左右、斜向、原地旋转等多个自由度。简化到程序层面只需要给四个电机设定不同速度和方向的组合。以常用安装方式为例运动方向左前右前左后右后前进正转正转正转正转右平移正转反转反转正转原地左转反转正转正转反转斜向右前停止正转停止反转不同厂家麦轮的辊子安装方向可能相反第一次装好以后建议先在平地逐项验证再写进正式程序。如果某个方向实际运动与预期相反交换同侧两个电机的正反转定义即可不用改硬件接线。3.4 程序封装把电机控制收敛成几个函数写成顺序执行的digitalWrite和analogWrite也不是不行就是后续加传感器、做逻辑控制时主循环会变得很乱。我的习惯是把一路电机封装成一个类class Motor { private: byte en, in1, in2; public: Motor(byte e, byte i1, byte i2) { en e; in1 i1; in2 i2; pinMode(en, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); } void setSpeed(int speed) { if (speed 0) { digitalWrite(in1, HIGH); digitalWrite(in2, LOW); } else if (speed 0) { digitalWrite(in1, LOW); digitalWrite(in2, HIGH); } else { digitalWrite(in1, LOW); digitalWrite(in2, LOW); } analogWrite(en, abs(speed)); } }; Motor motorLF(5, 2, 3); // 左前 Motor motorRF(6, 4, 7); // 右前 Motor motorLB(10, 8, 9); // 左后 Motor motorRB(11, 12, 13); // 右后这样主循环里只需要调用四个setSpeed配合上面的麦轮运动学表格就能写出非常干净的移动控制接口。将来接超声波避障、循迹传感器时只需要在函数上叠加判断逻辑不用再碰底层引脚操作。4. 实测踩坑小车一动就重启问题出在哪4.1 最常见的元凶电源电压跌落小车在桌上静态调试一切正常只要放到地上启动电机最多转半秒Arduino就重启这是新手做四驱车最容易遇到的问题。原因很简单四个电机同时启动时的瞬时电流远大于电池平均放电能力电压被瞬间拉到单片机复位阈值以下。解决思路有三个方向。第一是换电池把玩具电池换成高倍率锂电池这是治本第二是在电池正负两端并联一只1000μF/25V以上的电解电容放在靠近L298N电源端的位置给瞬态电流一个缓冲区第三是代码里做软启动不要让PWM直接从0跳到255而是分几十步递增到目标值实测下来对冲击电流的抑制效果非常明显。4.2 共地问题看起来玄实际是基本要求还有一类故障现象是小车用USB线连着电脑时一切正常拔掉USB线单独运行就乱跑。很多人的第一反应是程序问题实际上90%的原因是供电回路没有正确共地。USB连接时电脑的地线通过USB线把单片机和驱动模块的参考点拉齐了所以工作正常拔掉USB之后参考点断开PWM信号失去基准模块就会随机输出。排查方法很简单用万用表测量单片机的GND和L298N的GND之间是不是0欧姆如果有几十欧以上阻值说明共地线没接好或接触不良。这个基础问题不解决后面做任何射频模块、蓝牙控制都会出现类似的诡异现象。4.3 散热与长时间运行L298N是老式线性驱动方案饱和压降大输出电流高时芯片功率损耗很可观。四驱小车连续跑十分钟以上散热片温度能到七八十度虽然不至于立刻烧毁但芯片进入过温保护后会削顶输出表现为小车中途突然跑不动停一会儿又恢复。建议给L298N模块加装主动散热或者在底盘上留好气流通道。另外要特别注意堵转问题小车顶着障碍物不放手电机电流会飙升到远超额定值L298N会先于电机保护但反复堵转大概率会烧芯片所以程序里最好加一个超时保护逻辑检测到PWM输出但电机转速为零时自动断电。4.4 一片并联和两片独立在实测中的差异最后说一个我在调试中对比过的真实差异。一片L298N并联驱动四个电机直线低速跑时左右侧速度差还能接受一旦全速跑电机个体差异会被放大小车慢慢会往一侧偏需要不断手动修正转弯半径也偏大。两片L298N独立控制后每个轮子的速度都能单独校准直线稳定性明显提升原地旋转的轨迹也更接近圆形。代价是接线多了一倍程序也要稍微多写几行但换来的扩展性非常值。从学习角度讲先用并联方案把电机驱动的底层逻辑跑通再用两片方案做一次完整升级这个过程本身就能把L298N理解得很透彻。最后分享一点个人经验做四驱小车程序往往是最后一步前面接线、供电、共地、散热这些硬件问题随便哪一个处理不好代码写得再漂亮也白搭。先用这个L298N方案把电机的脾气摸清楚之后再换更高性能的驱动模块你会发现很多知识点都是通用的。本文还有配套的精品资源点击获取