拓冰建站拓冰建站
首页 / 资讯中心 / 正文

AT89S52+L298N电机驱动板原理图与PWM调速实战拆解

简介这是一份基于AT89S52单片机与L298N电机控制器的完整软硬件设计资源适合电子工程专业学生、嵌入式初学者及电机控制爱好者用于项目实践与二次开发。压缩包共374个文件约2.45MB包含原理图、PCB工程文件、C语言源码、Keil工程文件及编译中间产物另有芯片数据手册、元件清单和实物图片可支撑从电路设计到程序调试的全流程学习。已有262人浏览学习。资源价值在于提供了一整套可复用的直流电机控制方案AT89S52负责逻辑控制L298N双H桥驱动电机实现正反转与调速配套的DXP/Altium Designer工程文件可帮助理解双层板布局思路例程源码则演示了PWM调速、方向切换等关键编程方法适合对照手册逐模块拆解快速上手单片机电机控制系统的开发与调试。1. 这套AT89S52L298N板子为什么值得拆一遍做智能小车或者毕业设计时电机驱动板是最先要趟平的一关。市面上现成L298N模块几十块钱就能买到但模块只给了H桥和接线端子真正把单片机、电机驱动、电源、保护电路画到一块80×65mm两层PCB上才是从“会接线”到“会设计”的分水岭。这份资料恰好把原理图、PCB工程、元件清单、Demo源码都打包在一起而且原理图是AT89S52直接驱动L298N没有加专用电机驱动芯片线路足够简单适合拿来做单片机最小系统到电机控制链路的学习载体。我按“原理图为什么这么画—PCB怎么布—源码怎么跑—上电先查哪些点”的顺序拆中间会给出能直接抄的定时器PWM代码和调试方法。2. 从硬件链路理解L298N H桥驱动与AT89S52 IO的配合2.1 L298N的H桥逻辑表与使能引脚L298N内部是两个独立的H桥每个桥由四个功率晶体管组成负载电机接在OUT1和OUT2之间。H桥的核心逻辑是通过改变四个开关的通断组合让电流以不同方向流过电机从而实现正转、反转和刹车。只看IN1、IN2两个输入引脚和一个使能引脚ENA就能覆盖直流电机所有控制状态。下面这张逻辑表是看原理图时最常用的对照表建议直接打印出来贴在工作台旁边输入IN1输入IN2使能ENA电机行为001停止两个下管关断101正转011反转111刹车输出两端同电位XX0禁止输出电机自由滑行表中X表示任意电平。重点在于“使能引脚”的作用ENA为高电平时H桥输出跟随IN1/IN2的动作ENA为低电平时无论IN1/IN2是什么状态输出都被切断。正是这个特性让ENA成为PWM调速的天然入口——用单片机输出一个频率固定、高电平时间可变的方波给ENA就能控制电机平均电压进而控制转速。原理图里如果不直接给固定高电平而是引出到单片机某个IO脚就表示这块板子预留了调速能力。2.2 AT89S52准双向IO驱动L298N时为什么要加上拉电阻AT89S52属于MCS-51内核经典单片机P1、P2、P3口都是准双向IO内部有弱上拉但输出高电平时的拉电流能力很小一般不到1mA。L298N的输入端内部是一个TTL电平接口逻辑高电平门槛约2.3V虽然听起来很容易满足但实际布线后引脚上的寄生电容、噪声耦合都会拉低电平。更麻烦的是P0口是开漏输出内部完全没有上拉直接接IN1会连高电平都出不来。所以原理图里对驱动L298N的每条IO线几乎都会加一个10kΩ排阻到VCC这既不是多余设计也不是为了省IO电流而是保证电平处于稳定高电位。常见做法是在原理图里画一个RESPACK-8把P0.0到P0.3接上拉排阻P1、P3则看设计者习惯有的也加。L298N输入引脚自身的输入电流很小10kΩ上拉完全不会造成额外功耗。反过来看AT89S52的IO灌电流能力比拉电流强得多所以如果电路反着接把电机驱动模块换成低电平有效的逻辑高电平问题就会变成低电平问题原理图上的上拉电阻位置也要跟着改。读这套原理图时先找每个IO对VCC的上拉网络再看L298N的IN和ENA线有没有串电阻这比直接看芯片引脚名称更有用。2.3 原理图里几处保护器件和电源拓扑原理图上最容易忽略的是续流二极管。电机是感性负载电流被切断瞬间会产生反向电动势电压尖峰可能达到电源电压的几倍直接打在L298N的输出晶体管上。L298N数据手册明确要求外部增加八个快恢复二极管两两反向并联在OUT1、OUT2和VS、GND之间典型型号是1N5819或1N4007。原理图中二极管画在电机接线端子旁边PCB上就要保证二极管靠近端子而不是靠近芯片否则引线电感会削弱保护效果。电源拓扑方面这套板子如果是单电源输入常见的接法是12V电机电源先到L298N的VS再通过7805稳压到5V给AT89S52和L298N的VSS供电。7805输入端必须接100μF电解电容输出端再接104瓷片电容原理图里这两个电容的位置和封装决定了电源纹波大小。特别注意逻辑地GND和电机电源地最终要连在一起但连前先把采样点分开这是后续PCB布局的地线规划基础。如果原理图里出现了光耦隔离那是为了把单片机逻辑部分和电机功率部分彻底电气隔离这块80×65mm的小板很少加光耦因为尺寸和成本都太紧张。3. 2层板PCB布局80×65mm尺寸下的电源、走线和散热设计3.1 板框尺寸约束下先摆接口再走线的顺序拿到原理图后第一步不是自动布线而是先明确板框里各个接口的位置。80×65mm的2层板面积很紧张四个必需接口按优先级排序电源输入端子、电机输出端子、单片机的ISP下载口、外接按键或传感器排针。我一般先把端子放在板子外围电源端子和电机端子分布在相对两侧避免大电流走线横穿单片机区域。电机输出走线属于强电回路如果和晶振走线平行产生耦合电机换向瞬间的尖峰很容易让单片机复位。布局顺序可以固定为“大体积器件优先、接口优先、发热器件优先”。L298N是板上最大功率器件放在靠近电机端子的边缘位置7805和3.3V稳压器放在电源端子附近输入输出电容紧贴引脚AT89S52放在信号输出到L298N之间的中间地带保证引脚到H桥输入端的走线不超过10cm。晶振Y1放在单片机X1、X2引脚旁边两条晶振线尽量等长且包地远离电机电源走线。下面这张表是我做这种两层板时常用的默认约束可以直接套用网络类别最小线宽最小间距说明电机电源VS1.5mm0.3mm承载电机电流短而粗地线GND1.0mm0.3mm大面积铺铜减少回路电感逻辑信号0.3mm0.3mmL298N输入和单片机IO晶振线0.3mm0.3mm包地间距距离越短越好电源5V0.8mm0.3mm给7805输出和单片机供电3.2 L298N大电流回路的线宽、覆铜和散热过孔L298N的数据手册标称每通道峰值电流2A但持续2A时芯片结温会非常高PCB设计的第一要务不是把线画通而是把热量带走。如果板子结构允许我会在L298N下方铺一块独立的铜皮芯片金属底板通过散热孔焊接到这块铜皮上再在铜皮上打一排0.8mm的过孔把热量导到反面。过孔不能打在芯片封装正下面导致焊接时漏锡要打在焊盘外围1mm以外。电机电流路径上的走线需要用覆铜而不是细线顶层和底层各铺一层地铜地铜再用过孔阵连接起来。要注意地铜分割功率地和逻辑地单点连接连接点放在电源端子附近。很多初次画双层板的人直接整板铺一块地结果电机启动瞬间逻辑地电位被抬高200300mV单片机工作就不稳。判断地线设计好不好可以用示波器测AT89S52的VCC引脚对地的噪声峰峰值超过100mV基本就是地回路设计有问题。3.3 在Altium Designer里打开DXP工程后的网络检查压缩包里那个“DXP资本”通常指Protel DXP或Altium Designer的工程文件用AD17以上版本可以直接打开但老工程可能有封装兼容问题。打开工程后第一件事不是看界面而是编译工程Project - Compile PCB Project然后看Messages面板里的错误和警告。最常见的错误是元件封装缺失例如L298N的封装在旧库中叫MULTIWATT15新版AD可能变成DIP-15需要手动替换。网络标号不匹配也会在编译时被标红例如原理图里连到L298N VSS引脚的网络名如果叫5V而单片机电源网络叫VCC即使电气上都是5V网络名不同会导致PCB上无法连通。检查时把ERC电气规则检查里所有Warning级别的问题都过一遍尤其是单端网络和未连接引脚这两个坑在电机控制板里出现频率最高。验证PCB和原理图是否同步用先对比网络表再对比反向标注的方式。AD里执行Design - Board Information查看PCB上的网络数量再和原理图编译报告里的网络数量比对数量不一致说明有器件没放完。演示板如果还带元件清单可以用清单上的元器件封装和PCB库里实际封装比对省得后期买料发现电容封装尺寸对不上。3.4 元件清单与采购要点元件清单文件里通常列了全部器件型号、封装和数量是可以直接下单的购物车。需要重点检查的是电阻功率和电容耐压。L298N的VS输入端如果要放电解电容建议耐压至少25V因为它要承受电机反电动势叠加后的电压尖峰。续流二极管选择1N58191A/40V或更高规格不能用普通1N4007整流管替代因为快恢复特性对高频PWM尖峰的抑制效果完全不同。晶振频率决定了后面PWM和串口波特率计算的基准如果清单里写的是11.0592MHz那是为了串口波特率无误差如果是12MHz则机器周期恰好是1μs适合做定时器延时和PWM。两种频率的定时器初值差一点下载例程源码后如果电机转速感觉不对先查清单里的晶振型号是不是和代码对应。4. Demo例程源码拆解用定时器0实现PWM调速和正反转控制4.1 引脚分配和Keil工程组织例程包里的代码是AT89S52基础风格Keil工程里通常只有一个main.c文件所有功能写在同一个地方。为了让这段代码能直接跑先约定引脚映射我们把P1口前四个脚接到L298N的IN1到IN4P1.4和P1.5接到ENA和ENB。引脚分配表如下单片机引脚连接网络功能P1.0IN1A路方向输入P1.1IN2A路方向输入P1.2IN3B路方向输入P1.3IN4B路方向输入P1.4ENAA路使能/PWMP1.5ENBB路使能/PWMKeil里新建工程时选择Atmel的AT89S52注意不要选成AT89C52两者Flash容量不同但引脚兼容。如果用的Keil5需要先安装51单片机支持包否则器件列表里看不到AT89S52。下载程序用通用ISP下载器接线时下载器的RXD、TXD要和单片机交叉连接GND必须共地。4.2 定时器0产生软件PWM的初值计算和中断代码AT89S52内部没有硬件PWM模块只能靠定时器中断翻转IO。这里用12MHz晶振机器周期是12/12MHz1μs。设定时器0工作在模式1也就是16位定时器每50μs进入一次中断重装初值计算如下50μs除以1μs得50个机器周期所以初值是65536-5065486换算成十六进制是0xFFCE。每次中断将计数器pwm_cnt加1计数到100时清零这样一个PWM周期就是50μs×1005ms频率200Hz。占空比用一个0到100的变量控制当计数小于该变量时输出高电平否则输出低电平。/* pwm.c - AT89S52定时器0产生软件PWM周期5ms占空比0-100 */ #include REG52.H unsigned char pwm_cnt 0; /* 0-99循环计数 */ unsigned char duty_a 50; /* A路占空比初始50% */ bit ena P1^4; /* 将P1.4定义为位变量 */ void timer0_init(void) { TMOD 0xF0; /* 只清T0模式位不影响T1 */ TMOD | 0x01; /* T0设为16位定时器模式1 */ TH0 0xFF; /* 50us初值高8位 */ TL0 0xCE; /* 50us初值低8位 */ ET0 1; /* 开T0中断 */ TR0 1; /* 启动T0 */ } void timer0_isr(void) interrupt 1 { TH0 0xFF; /* 重装初值保证每次周期一致 */ TL0 0xCE; pwm_cnt; if (pwm_cnt 100) /* 100次为1个周期5ms */ pwm_cnt 0; if (pwm_cnt duty_a) ena 1; /* 输出高电机供电 */ else ena 0; /* 输出低电机续流 */ }这段代码的逻辑是每50微秒进入一次中断然后通过比较pwm_cnt和duty_a来决定P1.4的输出状态。duty_a等于100时整个周期内计数永远小于100电机全速运行duty_a等于0时永不小电机停止。要注意bit ena P1^4;这一行在某些Keil版本中不能这样定义位变量更常见的写法是在main函数外的文件头部定义一组宏或位变量比如sbit ena P1^4;这样中断服务程序里才能直接引用。参数选择上200Hz的PWM频率对直流减速电机足够但如果你用的是高转速空心杯电机200Hz低于电机电气时间常数转速会有可感知的脉动。遇到这种情况可以修改定时器初值把中断周期缩短到20μsPWM周期仍然是100次计数频率升到500Hz初值改成65536-20655160xFFEC。改动初值后要重新计算TH0和TL0的值。4.3 正转、反转、刹车、停止的状态机实现电机控制不能只用PWM占空比一个维度方向控制需要通过IN1/IN2组合实现。程序里定义四个状态每一种状态对应一组IO电平。下面给出一个典型的电机状态机实现/* motor.c - 电机状态切换 */ #define MOTOR_STOP 0 #define MOTOR_FORWARD 1 #define MOTOR_BACKWARD 2 #define MOTOR_BRAKE 3 sbit IN1 P1^0; sbit IN2 P1^1; sbit ena P1^4; void motor_set(unsigned char state) { switch (state) { case MOTOR_FORWARD: IN1 1; IN2 0; /* 电流正方向流过电机 */ ena 1; /* 使能输出 */ break; case MOTOR_BACKWARD: IN1 0; IN2 1; /* 电流反向 */ ena 1; break; case MOTOR_BRAKE: IN1 1; IN2 1; /* 两边同为高电机端电压为零 */ ena 1; break; case MOTOR_STOP: default: ena 0; /* 关断输出 */ IN1 0; IN2 0; break; } }刹车和停止的区别需要注意刹车是把电机的两个接线端接到同一个电位电机转子被磁场力矩迅速止住停止是直接切断使能让电机依靠惯性滑行。如果应用是循迹小车赛道急弯应该用刹车状态而不是停止状态。状态机代码放在定时器中断之外的main循环里避免在中断里做过多的Switch分支因为中断服务函数要尽可能短。4.4 速度渐变和按键控制示例直接从占空比0跳变到100电流冲击很大机械上会把小车抬头电气上会让L298N的电流尖峰到好几安培。例程里如果只给了启停和正反转我建议自己加一个加减速函数让速度按线性爬坡/* ramp.c - 从当前占空比加速到目标值 */ void ramp_to(unsigned char target, unsigned int step_ms) { unsigned char speed duty_a; while (speed ! target) { if (speed target) speed; else speed--; duty_a speed; delay_ms(step_ms); /* 每个步长延时step_ms5到20毫秒 */ } }参数说明step_ms是速度改变一级的间隔10毫秒对应从0到100共1秒完成加速适合小车起步如果想做平滑曲线可以把step_ms改成变长比如启动初期每档20ms高速区间每档5ms。这个代码直接操作duty_a全局变量在main循环里调用不会干扰定时器中断里的比较逻辑。如果板子上有独立按键按键扫描可以去抖后调用ramp_to实现点动和连续调速两种模式。5. 上电调试的三个高频坑使能悬空、地不共、PWM频率乱选5.1 电机不转先查ENA/ENB有没有被拉低上电后最让人火大的现象是程序烧进去了、按键也有反应但电机纹丝不动。第一件事不是怀疑代码而是用万用表电压档测L298N的ENA引脚对地电压。如果电压在0.5V以下说明使能引脚没有被拉高。L298N模块上如果有跳帽这个跳帽控制ENA是接高电平还是接单片机IO跳帽没插好或者插在了错误位置ENA就会悬空或为低。自己的板子如果ENA引脚是通过单片机上拉但单片机上电瞬间IO默认是高电平此时L298N应该已经处于禁止状态而程序里如果初始化P1.4时把它置0电机自然不转。调试时把ENA临时用手线接到VCC如果电机能转问题就出在单片机到ENA这段控制线上。5.2 单片机与电机驱动共地的验证方法第二个高频坑是AT89S52的GND和L298N的GND没有连到同一个网络。很多第一次接触电机驱动的人把单片机电源和电机电源分开认为两个电源各自独立所以地也要独立。实际上单片机输出的是相对自身GND的电平信号L298N识别输入电平时用的也是相对自身GND的电位两个地必须等电位。用万用表蜂鸣档测单片机电源地端的GND和L298N逻辑供电VSS的GND如果是同一个网络蜂鸣器响如果不响看原理图上它们是否通过一个0Ω电阻或磁珠连接这个位号在原理图里很容易被忽略。改板时我会在原理图里单独画一个跳线焊盘调试时直接短接量产时再决定是否断开。5.3 用示波器确认PWM波形和门极驱动时序软件PWM初值算错了PWM频率可能变成几十赫兹电机一边哆嗦一边发热。示波器探头夹在P1.4上地用鳄鱼夹接单片机GND观察波形如果占空比50%时高电平宽度为2.5ms周期是5ms说明初值正确如果周期变成50ms检查是晶振频率不是12MHz还是定时器重装初值放错位置。再看L298N的OUT1和OUT2之间的波形无论IN1/IN2如何切换两个输出都不能同时出现长时间高电平否则会导致桥臂直通烧毁L298N。直通在时序上的表现是OUT1和OUT2的波形在同一时刻都为高且持续超过10μs出现这种情况要检查代码里置位IN1和IN2之间是否插了延时。5.4 把Demo改成双电机差速的验证技巧最后分享一个验证整个系统是否正常的技巧用两个电机做差速前进。给A路占空比60%B路占空比40%让小车在桌面上走直线偏转如果偏转方向符合预期说明两路PWM都能独立调节。这样测的同时也验证了L298N一路、二路的续流二极管和散热设计是否到位——摸一下芯片表面温度低于60℃算正常如果烫得不能碰检查PWM频率是否选得太低或散热焊盘有没有问题。这套板子如果配合STM32或者STC单片机原理图里AT89S52换成对应封装代码里改一下寄存器名就能移植但PWM初值要按新单片机的时钟重新算。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门