资讯动态

PLC基本指令实战精讲:从梯形图逻辑到工程避坑指南

发布时间:2026/10/23 3:52:45 来源:尧图企业网站定制
1. 为什么还要死磕PLC基本指令干了十几年工控我见过太多人栽在“基本功”上。有人拿着西门子1200的编程手册翻来覆去地看梯形图里一个自锁回路却写得漏洞百出有人能把伺服参数调得飞起结果设备一上电一个简单的起保停都跑不起来。问题出在哪不是他们不懂高级功能是基本指令没吃透。PLC基本指令说白了就是编程语言里的“九九乘法表”。你乘法竖式再溜口诀背不熟算个账照样卡壳。接触器、继电器、定时器、计数器、比较指令、传送指令——这些东西看着简单但真正到了现场设备动作不对、信号丢失、时序错乱十有八九都是这些“简单东西”没处理好。这篇文章我打算把PLC基本指令从头到尾捋一遍。不是照搬手册那种念经式的讲法而是结合我这些年在产线上踩过的坑、调过的设备、半夜被叫起来处理的故障把每个指令背后的逻辑、使用场景、容易翻车的地方都讲清楚。不管你是刚入行的新手还是干了几年但总觉得基础不牢的老手看完应该都能有点收获。文章会以梯形图为主因为这是现场最通用的表达方式三菱、西门子、欧姆龙、台达底层逻辑都相通。2. 基本指令的底层逻辑从继电器控制到梯形图2.1 常开常闭不是“开关”是条件判断很多人初学PLC把常开触点理解成“开关按下就通”常闭触点理解成“开关按下就断”。这个理解不能说错但太浅了。在PLC的扫描周期里常开和常闭本质上是对位变量当前值的判断。常开触点如果这个位是1条件成立能流通过如果是0条件不成立能流断开。 常闭触点如果这个位是0条件成立能流通过如果是1条件不成立能流断开。你看它跟物理开关没有必然关系。一个输入点X0接的是常开按钮还是常闭按钮跟你在程序里用常开还是常闭触点是两码事。我见过一个经典错误现场急停按钮接的是常闭触点安全规范通常要求急停用常闭断线也能触发停机结果有人在程序里又用了一个常闭触点X0。按钮没按的时候物理回路是通的X0为1程序里的常闭触点断开设备直接没法启动。他查了半天硬件最后发现是程序里触点用反了。注意输入硬件是常闭还是常开决定了PLC输入映像寄存器的初始状态。程序里用常开还是常闭取决于你的控制逻辑需要。两者不要混为一谈。2.2 能流的概念梯形图的“电流”梯形图看起来像电路图但它没有真正的电流只有“能流”——一种逻辑上的导通状态。能流从左母线出发经过一系列触点条件最终到达线圈或功能指令。能流能走通线圈就动作走不通线圈就不动作。这个“能流”是单向的从左到右不能倒流。所以梯形图里不允许出现回路也不允许线圈直接接左母线某些品牌允许但不推荐。理解能流的方向性对后面理解自锁、互锁、置位复位非常关键。2.3 扫描周期为什么你的程序“慢半拍”PLC是循环扫描执行的。一个扫描周期分三个阶段输入采样、程序执行、输出刷新。输入采样阶段把物理输入点的状态读进输入映像寄存器程序执行阶段从头到尾扫一遍程序根据映像寄存器的值计算结果写到输出映像寄存器输出刷新阶段把输出映像寄存器的值送到物理输出点。这意味着什么意味着你的程序里输入信号的状态在整个扫描周期内是“冻结”的。如果在一个扫描周期内某个输入变了程序里看不到要等下一个周期才更新。同样输出线圈的状态也是在扫描周期末尾才真正输出。这个机制导致两个常见问题一是输入信号窄于一个扫描周期可能被漏掉二是程序里前后使用的同一个输入点状态是一致的不会因为物理信号变化而中途改变。理解这一点才能理解为什么有些逻辑要放在中断里为什么有些信号要用上升沿捕捉。3. 触点与线圈指令最基础也最容易翻车3.1 常开常闭触点的实战用法常开触点LD/LDI、AND/ANI、OR/ORI和常闭触点在程序里无处不在。但什么时候用常开什么时候用常闭很多人是凭感觉。我的经验是从“条件成立”的角度去想而不是从“开关状态”去想。比如一个启动按钮按下时信号为1我要它触发启动那就用常开触点。一个停止按钮现场接的是常闭按钮不按时信号为1按下时信号为0我要它在按下时切断运行那就用常闭触点。再比如一个限位开关平时不碰是0碰到是1我要“碰到就停”那就用常开触点我要“没碰到才允许运行”那就用常闭触点。这里有个口诀你要什么条件成立就用什么触点去判断。条件成立时该位为1用常开条件成立时该位为0用常闭。别去管物理开关长什么样。3.2 输出线圈与置位复位输出线圈OUT是最常用的指令。能流通过时线圈对应的位被置1能流断开时被置0。注意是每个扫描周期都重新写一次。也就是说如果某个扫描周期能流断了线圈立刻变0不管之前是什么状态。置位SET和复位RST则不同。置位是能流通过时把位置1之后即使能流断了位保持1直到遇到复位指令。复位同理。什么时候用OUT什么时候用SET/RST我的原则是如果这个输出在每个扫描周期都能明确计算出该通还是该断用OUT如果这个输出是事件触发的需要保持状态用SET/RST。举个例子一台电机的运行控制。如果逻辑是“启动按钮按下且没有停止信号且没有故障电机运行”那用OUT最合适因为每个周期都能算出结果。但如果逻辑是“按下启动按钮电机运行并保持按下停止按钮电机停止”用SET/RST更直观启动按钮用SET停止按钮用RST。但SET/RST有个坑如果同一个位被多处SET和RST最后执行的那条指令决定最终状态。我见过一个程序同一个输出线圈在三个地方被SET两个地方被RST结果调试的时候动作完全乱套。后来全部改成OUT逻辑一下子清晰了。实操心得新手阶段尽量用OUT少用SET/RST。OUT强迫你每个周期都考虑完整条件不容易出逻辑漏洞。等熟练了再在合适的地方用SET/RST。3.3 上升沿与下降沿捕捉瞬间信号上升沿LDP、ANDP、ORP和下降沿LDF、ANDF、ORF是基本指令里最容易被忽视、也最容易出问题的部分。上升沿的作用是当条件从0变1的那个扫描周期能流通过一个周期之后即使条件保持为1也不再通过。下降沿同理从1变0时通过一个周期。为什么需要沿指令因为PLC扫描周期很快一个按钮按下去可能持续几十毫秒到几百毫秒这期间程序已经扫描了几百上千次。如果你用普通触点去触发一个计数或者一个动作它会触发很多次。用上升沿只触发一次。我踩过的一个坑用普通触点去触发一个数据传送指令结果按钮按一下数据被传送了几百次。虽然结果一样但扫描周期被拖慢了而且如果传送的目标地址在变化就会出问题。后来改成上升沿触发干净利落。沿指令还有一个常见用法配合SET/RST做单按钮启停。一个按钮第一次按启动第二次按停止。逻辑是按钮的上升沿触发一个辅助继电器M0M0的常开和电机的常闭做自锁M0的常开和电机的常开做互锁……这个逻辑用沿指令实现起来很简洁但初学者容易绕晕。我的建议是先把普通自锁回路写熟再玩单按钮启停。4. 定时器与计数器时间与数量的控制核心4.1 定时器不只是“延时”定时器T是PLC里使用频率最高的功能指令之一。不同品牌的定时器类型和精度不同但基本原理一致有一个设定值SV一个当前值PV一个计时条件。计时条件成立时当前值开始累加或递减到达设定值后定时器输出触点动作。三菱的定时器T0-T199是100ms精度T200-T245是10ms精度西门子的TON、TOF、TP类型各有用途。这里不展开品牌差异重点讲使用逻辑。定时器最常见的用法是延时启动、延时停止、闪烁、超时报警。但有几个细节容易被忽略第一定时器的计时条件是能流。能流通过时计时能流断了就复位普通定时器。所以如果你希望定时器在某个条件成立后开始计时条件消失后保持当前值那要用保持型定时器或者用SET指令把计时条件锁住。第二定时器的设定值可以是常数也可以是寄存器。用寄存器做设定值可以在触摸屏上修改灵活性高很多。但要注意寄存器的数据类型和范围别设了一个超出定时器量程的值。第三多个定时器级联可以实现长时间延时。比如一个定时器最大只能设3276.7秒你要延时两小时可以用第一个定时器计时60秒它的输出触发第二个定时器再计时60秒两个定时器的输出串联作为最终条件。级联的时候注意第一个定时器的输出要用上升沿触发第二个定时器的计时条件否则第二个定时器会一直计时。注意定时器的当前值在计时条件断开后是否复位取决于定时器类型。普通定时器会复位保持型定时器不会。用之前一定要确认清楚否则会出现“时间到了但没动作”或者“时间没到就动作了”的诡异现象。4.2 计数器上升沿是灵魂计数器C用来对事件计数。基本要素计数输入、复位输入、设定值、当前值。计数输入每来一个上升沿当前值加一或减一到达设定值后输出触点动作。计数器的核心是上升沿。如果你用普通触点去触发计数一个信号持续期间计数器会每个扫描周期加一次瞬间就溢出了。所以计数器的计数输入必须用上升沿或者用脉冲信号。我见过一个包装机项目用光电开关计数产品数量。光电开关的信号持续几十毫秒程序里用普通触点计数结果一个产品被计了几十次。后来改成上升沿问题解决。但还有第二个问题光电开关抖动。机械振动导致光电开关在短时间内多次通断上升沿也捕捉到了多次。最后在程序里加了一个小延时滤波或者用计数器配合定时器做防抖才彻底稳定。计数器的复位也很关键。有些计数器是复位端有信号时当前值归零有些是复位端从0变1时归零。用之前查手册别想当然。4.3 定时器和计数器的组合应用定时器和计数器组合可以实现很多有意思的功能。比如一个定时器计时1秒它的输出触发计数器计数计数器计到60就是1分钟再计到3600就是1小时。这种组合在需要长时间计时但单个定时器量程不够时非常有用。另一个经典应用是闪烁电路。两个定时器互相触发一个控制亮的时间一个控制灭的时间就能做出任意频率和占空比的闪烁效果。比用系统自带的闪烁继电器灵活得多。还有一个我常用的技巧用计数器做设备运行时间统计。设备运行时一个定时器每秒产生一个脉冲计数器对这个脉冲计数。计数器的当前值就是运行秒数换算一下就是小时数。这个数据可以显示在触摸屏上提醒维护人员按时保养。5. 数据传送与比较指令让程序“会算账”5.1 传送指令MOV不是简单的赋值传送指令MOV把源操作数的值复制到目标操作数。看起来简单但有几个点要注意。第一数据类型要匹配。源是16位整数目标是32位浮点数直接传送会出错。有些品牌会自动转换有些不会。用之前确认清楚。第二传送是每个扫描周期都执行的。如果源数据在变化目标数据也跟着变。如果你希望只在某个条件成立时传送一次要用上升沿触发。第三传送指令可以传送常数、寄存器、位组合。比如把常数100传送到一个数据寄存器D0或者把输入端子X0-X7的状态传送到一个字节寄存器。后者在读取拨码开关或者多位输入时很有用。我踩过的一个坑用MOV指令把一个寄存器的值传送到另一个寄存器结果两个寄存器地址有重叠传送后源数据被覆盖了。后来查手册才发现某些品牌的数据寄存器是连续编址的D0和D1是独立的但如果你用32位传送指令DMOV它会占用D0和D1两个寄存器。如果你同时还在用D1做其他事情就会冲突。实操心得用32位指令时一定要确认它占用了哪些寄存器避免地址冲突。我习惯在程序里给32位数据预留连续的寄存器区域并且做好注释。5.2 比较指令程序的分岔路口比较指令CMP、、、、等用来判断两个数值的大小关系条件成立时输出触点动作。它是程序实现分支逻辑的核心。比较指令的常见用法判断计数器当前值是否到达设定值、判断模拟量是否超限、判断两个数据是否相等。比如一个温度控制系统温度值存在D0设定值存在D100用比较指令判断D0D100时启动冷却D0D100-5时停止冷却就能实现一个简单的回差控制。比较指令的坑在于数据类型和符号。16位有符号整数的范围是-32768到32767如果你比较的两个数超出了这个范围或者一个是无符号数一个是有符号数结果可能出乎意料。比如30000和-30000比较在无符号看来30000大在有符号看来-30000小。用之前确认数据的类型。另一个坑是浮点数比较。浮点数有精度问题两个理论上相等的浮点数实际可能差一个极小值。所以浮点数比较通常不用“等于”而是判断差值是否小于一个很小的数。比如判断D0和D100是否相等用|D0-D100|0.001来代替D0D100。5.3 数据运算指令加减乘除的边界加减乘除指令ADD、SUB、MUL、DIV在PLC里也是基本指令。但PLC的运算和计算机的运算一样有溢出和精度问题。加法指令两个16位数相加结果可能超过32767溢出后结果会变成负数。如果你没注意程序就会出错。解决办法是用32位运算或者提前判断是否可能溢出。除法指令除数为0会报错。有些品牌会直接停机有些会给出错误标志。程序里一定要做除零保护在除法之前判断除数是否为0。乘法指令两个16位数相乘结果可能很大必须用32位存放。三菱的MUL指令结果自动占用两个连续寄存器低16位在指定寄存器高16位在下一个寄存器。用的时候要注意。我个人的习惯是只要涉及运算尽量用32位指令。虽然占用的寄存器多但溢出风险小很多。现在的PLC寄存器资源一般够用没必要为了省几个寄存器冒风险。6. 程序控制指令让逻辑有“章法”6.1 主控指令MC和MCR主控指令MC、MCR用来控制一段程序的执行与否。MC指令相当于一个总开关MCR是总开关的复位。在MC和MCR之间的程序只有当MC条件成立时才执行。主控指令的好处是减少重复条件判断。比如一台设备有手动和自动两种模式手动模式下执行一段程序自动模式下执行另一段。如果不用主控每一条指令前面都要加一个模式判断触点程序冗长且容易出错。用主控把模式判断放在MC指令里后面的程序就干净了。但主控指令有个限制MC和MCR必须成对使用不能交叉不能嵌套超过规定层数。三菱的MC指令可以嵌套8层但实际项目中我很少超过2层。嵌套太多程序可读性急剧下降调试的时候找问题很痛苦。6.2 跳转指令CJ的取舍跳转指令CJ用来跳过一段程序不执行。和主控指令不同跳转是直接跳过被跳过的程序完全不扫描连输出都不刷新。跳转指令的典型应用是故障处理。设备正常运行时执行主程序出现故障时跳转到故障处理程序主程序不执行。这样可以确保故障时设备立即停止不会因为主程序还在扫描而出现意外动作。但跳转指令也有风险被跳过的程序里的输出线圈状态保持不变。如果你跳转前某个输出是ON跳转后它还是ON不会自动变OFF。所以跳转前一定要把该关的输出关掉或者用跳转指令配合SET/RST来管理输出状态。我一般不建议新手用跳转指令因为容易出逻辑漏洞。如果确实需要条件执行用主控指令更安全因为主控指令在条件不成立时内部的输出线圈会被强制复位。6.3 子程序与中断进阶但必要子程序CALL、SRET和中断EI、DI、IRET严格来说不算“基本指令”但在实际项目中几乎离不开。子程序用来把重复的逻辑封装起来减少程序长度中断用来处理需要快速响应的信号比如高速计数、位置捕捉。子程序的使用要点调用子程序时子程序内部的输出状态在返回后是否保持取决于品牌和设置。有些品牌在子程序返回后输出保持有些会复位。用之前确认清楚。中断的使用要点中断程序要尽可能短。中断程序执行期间主程序暂停。如果中断程序太长会影响主程序的扫描周期导致其他信号响应变慢。我一般把中断程序控制在几十条指令以内只做最紧急的处理复杂逻辑放到主程序里。7. 常见问题与排查技巧实录7.1 输入信号不动作程序里却显示为ON这种情况通常是输入滤波时间的问题。PLC的输入点有滤波电路用来消除抖动。滤波时间一般是10ms左右但有些品牌可以设置。如果输入信号太窄小于滤波时间PLC就捕捉不到。排查方法用编程软件监控输入映像寄存器看信号是否变化。如果物理输入点有信号但映像寄存器不变就是滤波或硬件问题。如果映像寄存器变了但程序里不动作就是程序逻辑问题。另一个可能是输入公共端接线。有些PLC的输入点是分组共阳或共阴的公共端没接对整组输入都不工作。我见过一个项目输入模块的公共端接错了导致8个输入点全部失效查了一下午。7.2 输出线圈动作了但设备不动作输出线圈动作说明程序逻辑没问题。设备不动作问题在输出侧。排查顺序输出映像寄存器是否有信号、输出模块指示灯是否亮、输出端子是否有电压、中间继电器是否动作、接触器是否吸合、电机是否得电。常见原因输出模块的公共端没接、输出模块的保险丝烧了、输出端子螺丝松动、中间继电器线圈烧了、接触器线圈烧了。我遇到最多的是输出端子螺丝松动特别是振动环境下的设备运行一段时间后螺丝就松了接触不良。7.3 定时器时间不准定时器时间不准通常是扫描周期的影响。定时器的计时是基于扫描周期的如果扫描周期波动大定时器的时间就会有误差。比如一个100ms精度的定时器设定值10理论上是1秒。但如果扫描周期是20ms实际计时可能是1秒±20ms。解决办法对时间精度要求高的场合用中断定时或者高速定时器。有些品牌有专门的高精度定时器不受扫描周期影响。另外尽量缩短程序长度减少扫描周期波动。7.4 计数器误计数计数器误计数前面说过主要是上升沿和抖动的问题。解决办法计数输入用上升沿同时在硬件或程序里加滤波。硬件滤波可以在输入点并联电容程序滤波可以用定时器做延时确认。还有一个容易被忽略的原因计数器的复位条件。如果复位条件在计数过程中短暂成立计数器会归零然后重新计数。如果复位信号有抖动计数器就会反复归零。用上升沿触发复位或者给复位信号加滤波。7.5 程序修改后设备动作异常程序修改后设备动作异常最常见的原因是修改了程序但没重新下载或者下载了但没复位PLC。有些品牌修改程序后需要断电重启才生效有些需要切换运行模式。另一个原因是寄存器的初始值。程序修改后如果新增了寄存器它的初始值可能是0也可能是随机值。如果程序里没有初始化就会出问题。我习惯在程序开头用一段初始化程序把关键寄存器赋初值确保每次上电状态一致。7.6 常见问题速查表现象可能原因排查方法解决措施输入不动作滤波时间过长、公共端接错监控输入映像寄存器调整滤波时间、检查公共端输出不动作输出模块故障、端子松动检查输出指示灯和端子电压更换模块、紧固端子定时器不准扫描周期波动监控扫描周期用中断定时、缩短程序计数器误计数无上升沿、信号抖动监控计数输入加上升沿、加滤波程序修改后异常未下载、未复位、寄存器未初始化确认下载状态、检查寄存器重新下载、复位、加初始化通信失败站号冲突、波特率不匹配检查通信参数统一站号和波特率模拟量漂移干扰、接地不良检查屏蔽线和接地加屏蔽、改善接地8. 从基本指令到稳定程序的几个习惯写了这么多年程序我越来越觉得PLC编程的难点不在指令本身而在习惯。同样的指令不同的人写出来稳定性天差地别。分享几个我坚持了很多年的习惯。第一个习惯每个输出线圈只出现一次。不管是OUT还是SET/RST同一个输出位在程序里只写一次。如果逻辑复杂用辅助继电器M做中间状态最后统一输出。这样调试的时候只要监控这个输出位就能知道它为什么通、为什么断不用满程序找。第二个习惯注释写到“为什么”而不是“是什么”。比如一个常开触点X0注释写“启动按钮”是“是什么”写“按下时允许设备启动”是“为什么”。过半年再看程序前者你可能忘了当时怎么想的后者一看就明白逻辑意图。第三个习惯关键信号加滤波。按钮、限位、光电开关这些机械或光电信号都有抖动。程序里加一个10ms到50ms的延时确认能避免很多误动作。别指望硬件滤波能解决所有问题软件滤波更灵活。第四个习惯程序分段每段一个功能。手动程序、自动程序、报警程序、通信程序分开写用主控或跳转隔开。别把所有逻辑混在一起调试的时候你会疯。第五个习惯上电初始化。程序开头用一段初始化程序把关键寄存器、计数器、定时器复位确保每次上电状态一致。这个习惯帮我省了无数次“上次运行状态残留”的麻烦。这些习惯看起来简单但坚持下来不容易。我见过太多程序功能都能实现但可读性差、可维护性差换个人接手就抓瞎。基本指令是砖习惯是水泥两者结合才能盖出稳固的房子。最后说一个我自己的教训。早年做一个项目程序写得很“聪明”用了大量SET/RST和跳转逻辑绕来绕去。调试的时候自己都绕晕了设备动作时对时错。后来全部推倒重来用最笨的OUT和自锁回路重写程序长了一倍但一次调试通过运行三年没出过逻辑问题。从那以后我就信一个理在工控领域简单可靠永远比聪明复杂重要。基本指令用好了比什么高级功能都管用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑