PLC编程分水岭:位逻辑的时空观与状态流转实战 1. 为什么“位逻辑”才是PLC编程的真正分水岭干了十几年工控带过的徒弟少说也有二三十个我发现一个特别有意思的现象很多人学PLC卡住的地方根本不是那些花里胡哨的复杂指令。什么PID自整定、什么运动控制插补、什么SCADA数据归档这些听起来高大上的东西反而有人能啃下来。真正把人拦在门外的是位逻辑——就是那些看起来最不起眼的常开触点、常闭触点、线圈输出、置位复位。你可能会说这不就是“与或非”吗初中生都懂。但我在实际项目里见过太多这样的场景一个十字路口红绿灯PLC程序逻辑不复杂吧有人写出来就是会闪、会冲突、会死锁。一个四层电梯控制程序说白了就是楼层呼叫和方向判断但有人就是搞不定优先响应和顺向截梯。问题出在哪不是他不懂指令是他脑子里没有建立起位逻辑的时空观。什么叫位逻辑的时空观简单说就是你要清楚地知道在PLC扫描周期的每一个瞬间每一个位Bit的状态是什么它在上一个周期是什么在这个周期被谁改了下一个周期又会变成什么。这就像下棋你不能只看当前这一步你要看到三步之后的局面。绝大多数人学PLC学的是“指令怎么用”而不是“位状态怎么流”。这就是为什么我说基础位逻辑学不透后面学再多高级指令都是空中楼阁。这篇文章我想把“位逻辑”这件事彻底讲透。不管你是刚入行的新手还是已经能写一些程序但总觉得心里没底的老手我都建议你耐心看完。我会从底层原理讲到实操细节从常见误区讲到排查技巧尽量用大白话把这件事说明白。文章会涉及汇川PLC、三菱PLC、西门子PLC等常见品牌也会提到INPROSHOP这类编程环境但核心逻辑是通用的跟你用什么牌子关系不大。2. 位逻辑的本质不是指令是状态流转2.1 从“继电器逻辑”到“扫描周期”的认知跨越很多人学PLC一上来就学指令表LD、OUT、AND、OR。这没错但问题在于他把PLC当成了一个“即时响应”的设备。他觉得我按下按钮触点就闭合线圈就输出天经地义。但在PLC里这个“即时”是不存在的。PLC是周期性扫描的它一遍一遍地读输入、执行程序、写输出循环往复。我打个比方。传统的继电器控制像是一群人在一个房间里谁说话谁举手实时互动。PLC控制像是一个老师每隔一段时间进教室一次看一眼谁举手了然后根据规则在黑板上写下一轮谁该做什么写完就走。下一次进来他看的是上一次写的结果而不是你现在的状态。这个“间隔”就是扫描周期。理解这一点是理解位逻辑的第一道门槛。如果你脑子里没有这个“老师进教室”的画面你写程序就是凭感觉出了问题也不知道从哪查。我见过太多人程序里同一个线圈用了两次OUT然后问我为什么输出会闪。我说你把扫描周期画出来把每个周期的状态标出来你自己就明白了。他画完就沉默了。2.2 位逻辑的三大核心要素触点、线圈、状态位逻辑说到底就三个东西触点、线圈、状态。触点分常开常闭线圈分普通输出、置位复位状态就是0和1。但就是这三个东西组合起来能玩出无数花样也能埋下无数坑。我先说触点。常开触点就是“条件成立时导通”常闭触点就是“条件不成立时导通”。这话听起来像废话但很多人写程序时脑子里想的是“我要让这个条件成立”手上却画了个常闭因为他把“停止按钮”的物理常闭和程序里的常闭搞混了。物理常闭按钮在程序里通常用常开触点因为你不按的时候它导通你按下去它断开。这个“反逻辑”是新手最容易翻车的地方。再说线圈。普通线圈OUT是“这个周期我导通下个周期如果条件不成立我就断开”。置位SET是“我一旦导通就永远保持直到有人复位我”。复位RST是“我一旦执行就把对应的位置0”。这三者的区别决定了你的程序是“随动”还是“保持”。很多逻辑冲突就是因为该用SET的地方用了OUT或者该用OUT的地方用了SET。最后说状态。状态是位逻辑的灵魂。你要时刻问自己这个位现在是什么谁把它置1的谁把它清0的如果没人清0它会一直保持吗如果两个人同时写它谁赢这些问题就是位逻辑的核心。2.3 为什么“看懂”和“写对”之间隔着一道鸿沟我经常跟徒弟说看懂别人的程序和写出正确的程序是两码事。看懂是“读”写对是“写”。读的时候你顺着逻辑走一遍觉得通了就以为懂了。但写的时候你要考虑所有可能的输入组合、所有可能的时序关系、所有可能的边界条件。这就像看别人下棋觉得简单自己下就懵了。位逻辑的鸿沟主要体现在三个方面。第一是时序盲区你只考虑了稳态没考虑瞬态。比如一个按钮按下的瞬间输入信号可能抖动你的程序如果没做滤波就可能误触发。第二是竞争冒险两个条件同时满足谁先谁后在PLC里程序是从上到下执行的上面的先执行下面的后执行。如果你没考虑这个顺序就会出现“本该互锁的两个输出同时导通”的情况。第三是状态残留上一个循环留下的状态你没有清理导致下一个循环逻辑错乱。这三个问题都不是“指令不会用”的问题而是“位逻辑没学透”的问题。你指令背得再熟遇到这三个问题照样抓瞎。3. 位逻辑实操从红绿灯到电梯的底层拆解3.1 十字路口红绿灯最经典的位逻辑训练场红绿灯程序几乎是每个PLC学习者的必修课。但很多人写出来的红绿灯要么是“死循环”要么是“闪灯”要么是“两个方向同时绿”。问题出在哪出在他没有把“时间”和“状态”分开。正确的思路是这样的红绿灯的核心不是“灯”而是“阶段”。一个十字路口通常有四个阶段东西绿、东西黄、南北绿、南北黄。每个阶段持续一段时间时间到了就切换到下一个阶段。所以你的程序里应该有一个“阶段计数器”或者“步进状态机”而不是直接去控制灯。我见过一个典型的错误写法用三个定时器分别控制红、黄、绿然后互相串联。这种写法一旦定时器的时间设置不匹配就会出现“红灯还没灭绿灯就亮了”的情况。正确的做法是用一个定时器控制“阶段时长”然后用阶段号去驱动灯的输出。这样任何时刻只有一个阶段是激活的灯的状态自然就是确定的。具体到汇川PLC或者三菱PLC你可以用步进梯形图SFC来实现也可以用普通的位逻辑来搭。如果用位逻辑我建议用移位寄存器的思路用一个字比如D0的四个位分别代表四个阶段每个扫描周期检查当前阶段时间到了就移位。这样逻辑清晰排查也方便。注意红绿灯程序里黄灯的时间一定要留够。我见过太多人把黄灯设成0.5秒结果实际运行起来司机根本反应不过来。一般建议黄灯至少3秒具体看路口宽度和车流速度。3.2 四层电梯控制位逻辑的“状态机”思维电梯程序比红绿灯复杂但核心还是位逻辑。电梯的本质是一个状态机它有“空闲”、“上行”、“下行”、“开门”、“关门”几个状态每个状态下有对应的动作和转移条件。很多人写电梯程序喜欢用一大堆中间继电器M来记录各种状态结果程序越写越长最后自己都理不清。我的建议是先画出状态转移图把每个状态和转移条件列清楚然后再用位逻辑去实现。比如状态0空闲。条件无呼叫。状态1上行。条件有高于当前楼层的呼叫。状态2下行。条件有低于当前楼层的呼叫。状态3开门。条件到达目标楼层。状态4关门。条件开门时间到。每个状态用一个位来表示同一时刻只有一个状态位是1。这样你的程序就变成了“在什么状态下做什么动作满足什么条件切换到下一个状态”。这就是状态机思维也是位逻辑的高级应用。电梯程序里最容易出错的地方是顺向截梯和优先响应。比如电梯正在上行三层有人按了上行四层有人按了下行。电梯应该先响应三层再响应四层。这个逻辑如果你用普通的IF-THEN去写会非常复杂。但如果你用位逻辑的状态机就很简单在上行状态下只响应“上行呼叫”且“楼层大于当前楼层”的请求其他的请求先挂起。等电梯到了顶层再切换下行状态去响应下行请求。实操心得写电梯程序时一定要先做“单步调试”。手动强制每个状态位看电梯的动作是否符合预期。不要一上来就全自动运行那样出了问题你根本不知道是哪个状态错了。3.3 基于PLC的自动化包装线位逻辑的“互锁”与“联动”包装线程序是位逻辑的另一个典型应用。包装线通常有多个工位上料、封口、打码、下料。每个工位都有自己的动作但工位之间又有严格的时序关系。比如上料没完成封口就不能动封口没完成打码就不能动。这种程序的核心是互锁和联动。互锁就是“你不做完我就不开始”。联动就是“你做完了我就自动开始”。在PLC里互锁通常用常闭触点来实现把上一个工位的“完成信号”的常闭触点串在下一个工位的“启动条件”里。这样上一个工位没完成下一个工位就启动不了。但这里有个坑如果上一个工位的“完成信号”是一个脉冲而不是一个保持信号那你的互锁就会失效。因为脉冲一闪而过下一个工位还没来得及启动条件就没了。所以互锁用的信号必须是保持型的比如用SET置位一个“完成标志位”直到下一个工位启动后再RST复位。联动则要注意时序配合。比如封口动作需要2秒打码动作需要1秒。你不能让打码和封口同时开始否则封口还没到位打码就打下去了可能打偏。正确的做法是封口完成后延时0.5秒再启动打码。这个延时就是联动的时间窗口。常见问题包装线程序里经常出现“某个工位卡住整个线都停了”的情况。这通常是因为互锁条件太严格或者某个传感器的信号抖动导致误触发。排查时先看PLC的输入指示灯确认传感器信号是否稳定。如果信号没问题再看程序里的互锁逻辑是不是有“死锁”的情况。4. 位逻辑的常见误区与排查技巧4.1 误区一把“物理逻辑”和“程序逻辑”混为一谈这是新手最容易犯的错误。物理上停止按钮是常闭的你不按的时候它导通你按下去它断开。但在程序里如果你用常闭触点去接这个按钮那你不按的时候程序里这个触点就是断开的你的设备就启动不了。所以物理常闭按钮在程序里通常用常开触点。这就是“反逻辑”。我见过一个徒弟调试一个水泵控制程序怎么都启动不了。我让他把程序调出来一看停止按钮用的是常闭触点。我说你把停止按钮改成常开触点试试。他改完水泵就转了。他问我为什么我说你去看看停止按钮的接线是不是常闭的。他一看果然是。这就是典型的“物理逻辑”和“程序逻辑”混淆。记住一个原则程序里的触点状态永远以“条件成立”为导通。物理常闭按钮不按的时候是导通的所以程序里要用常开触点来“模拟”这个导通。物理常开按钮不按的时候是断开的所以程序里要用常闭触点来“模拟”这个断开。4.2 误区二忽略扫描周期导致的“双线圈”问题双线圈问题是位逻辑里的经典坑。所谓双线圈就是同一个输出线圈比如Y0在程序里被写了两次。在PLC里后面的写会覆盖前面的写。也就是说如果第一个OUT Y0的条件成立Y0被置1但第二个OUT Y0的条件不成立Y0又会被置0。最终Y0的状态取决于最后一个写它的指令。很多人写程序喜欢在程序的不同位置分别控制同一个输出觉得这样“方便”。但这样做的后果是你根本不知道Y0最终是什么状态。排查的时候你盯着第一个OUT看觉得条件满足了Y0应该亮但实际上Y0没亮因为后面还有一个OUT把它覆盖了。解决双线圈问题有两个办法。一是合并逻辑把同一个输出的所有控制条件合并到一个OUT指令里。二是用中间继电器先用M继电器分别控制各个条件最后再用一个OUT指令把M继电器的逻辑组合起来输出到Y。第二种办法更清晰也更容易排查。实操技巧在汇川PLC的编程软件里你可以用“交叉引用”功能查看某个输出线圈在程序里被用了多少次。如果超过一次就要警惕双线圈问题。三菱的GX Works也有类似功能。4.3 误区三置位复位用错导致“状态锁死”SET和RST是位逻辑里的“双刃剑”。用好了程序简洁高效用错了状态锁死设备停不下来。我见过一个程序用SET置位了一个“运行标志”但忘记写RST。结果设备一旦启动就永远停不下来只能断电重启。还有一种情况是SET和RST的顺序问题。如果SET和RST在同一个扫描周期里都被执行谁后执行谁生效。如果你把SET写在前面RST写在后面那最终是RST生效位置0。反过来就是SET生效位置1。这个顺序决定了你的程序是“优先启动”还是“优先停止”。安全原则对于安全相关的信号比如急停、超限保护一定要用常闭触点串联的方式直接切断输出而不是依赖SET/RST。因为SET/RST是程序逻辑万一程序跑飞了SET/RST可能失效。但常闭触点串联是硬逻辑只要触点断开输出就没了。4.4 常见问题速查表问题现象可能原因排查方法解决方案输出该亮不亮双线圈覆盖用交叉引用查输出线圈合并逻辑或用中间继电器输出该灭不灭SET未复位查SET指令后是否有RST补RST或改用OUT设备启动不了停止按钮逻辑反了查停止按钮的触点类型物理常闭用程序常开设备闪停输入信号抖动看PLC输入指示灯加延时滤波或施密特触发两个输出同时导通互锁逻辑缺失查两个输出的条件加常闭触点互锁状态卡死状态转移条件不满足单步调试状态位检查转移条件是否覆盖所有情况5. 位逻辑进阶从“能跑”到“跑得稳”5.1 用“状态机”重构你的位逻辑如果你已经能写出“能跑”的程序但总觉得程序乱、不好维护、容易出bug那我建议你学一学状态机。状态机不是什么高深的东西它就是把你的程序分成若干个“状态”每个状态下有明确的“动作”和“转移条件”。同一时刻只有一个状态是激活的。用状态机写程序有几个好处。第一逻辑清晰你一眼就能看出设备当前在什么状态下一步会去什么状态。第二容易排查如果设备行为不对你只需要看当前状态和转移条件不用满程序找。第三容易扩展加一个新状态只需要加一个状态位和对应的转移条件不影响其他状态。在汇川PLC里你可以用SFC顺序功能图来实现状态机也可以用普通的位逻辑来搭。如果用位逻辑我建议用一个字比如D0来存储状态号然后用比较指令、、来判断当前状态。这样你的程序就变成了“如果状态号等于1就做A如果状态号等于2就做B”。简单直接。5.2 位逻辑的“防御性编程”什么叫防御性编程就是你在写程序的时候要假设“所有可能出错的地方都会出错”然后提前做好保护。比如你写一个电机启动程序你不能只写“按下启动按钮电机转”。你还要考虑如果启动按钮卡住了怎么办如果电机过载了怎么办如果两个启动按钮同时按了怎么办防御性编程的核心是互锁和自锁。互锁是“你不满足条件我就不让你动”。自锁是“我一旦动了就保持住直到有人让我停”。这两个逻辑是位逻辑里最基础也最重要的保护机制。我举个例子。一个正反转电机控制程序正转和反转之间必须有互锁。也就是说正转接触器和反转接触器不能同时吸合否则会短路。在程序里你要把正转的输出常闭触点串在反转的启动条件里把反转的输出常闭触点串在正转的启动条件里。这样只要正转在运行反转就启动不了反之亦然。注意互锁不仅要写在程序里还要在硬件上做互锁。也就是说正转接触器的常闭辅助触点要串在反转接触器的线圈回路里。这样即使程序跑飞了硬件互锁也能保证安全。5.3 位逻辑与SCADA的衔接数据交互的底层逻辑现在很多项目PLC不是孤立的它要和SCADA数据采集与监视控制系统连接。SCADA要读PLC的状态也要写PLC的控制字。这个读写的过程本质上也是位逻辑的交互。SCADA读PLC通常是读一个寄存器比如D100然后把这个寄存器的每一位解析成不同的状态。比如D100的bit0表示“运行”bit1表示“故障”bit2表示“就绪”。SCADA写PLC通常是写一个控制字比如D200PLC的程序里再去解析这个控制字的每一位决定执行什么动作。这里有个坑SCADA的读写周期通常比PLC的扫描周期慢得多。SCADA可能几百毫秒才读一次而PLC几毫秒就扫描一次。所以如果你在PLC程序里用SCADA写的控制字去触发一个瞬时动作可能会因为SCADA还没刷新导致动作丢失。正确的做法是SCADA写一个“命令位”PLC检测到这个命令位后执行动作然后自己把这个命令位清掉。这样即使SCADA刷新慢也不会丢命令。实操经验汇川PLC和威纶通触摸屏通讯时经常遇到“驱动找不到”的问题。这通常是因为触摸屏的驱动库版本太老不支持新型号的PLC。解决办法是升级触摸屏的驱动库或者用Modbus协议直接通讯。Modbus是通用协议几乎所有PLC和触摸屏都支持。6. 位逻辑的学习路径与实战建议6.1 从“抄程序”到“改程序”再到“写程序”学PLC跟学编程语言一样有个循序渐进的过程。我建议分三步走。第一步抄程序。找一些经典的例程比如红绿灯、电梯、包装线照着抄一遍然后运行起来看效果。这一步的目的是熟悉指令和编程环境。第二步改程序。在抄来的程序基础上改一些参数加一些功能看程序会有什么变化。这一步的目的是理解逻辑的因果关系。第三步写程序。从零开始自己设计一个完整的程序从需求分析到状态机设计再到代码实现和调试。这一步的目的是建立自己的编程思维。很多人卡在第一步和第二步之间抄了很多程序但从来不改也不自己写。这样学永远学不会。因为抄程序是“输入”改程序和写程序是“输出”。只有输出才能真正掌握。6.2 用“仿真”加速学习但别依赖仿真现在很多PLC编程软件都带仿真功能比如西门子的PLCSIM、汇川的INPROSHOP仿真。仿真对于学习位逻辑非常有帮助因为你可以在没有硬件的情况下测试你的程序逻辑。你可以强制输入信号观察输出变化单步执行看每个位的状态。但仿真有个问题它太“理想”了。仿真里的输入信号是完美的没有抖动没有延迟没有干扰。而实际现场输入信号可能抖动可能延迟可能受电磁干扰。所以仿真通过的程序到现场不一定能跑。我建议仿真用来验证逻辑现场用来验证稳定性。两者缺一不可。常见问题PLCSIM Advanced启动不了报Error 11。这通常是端口被占用或者防火墙拦截了。解决办法是检查端口关闭防火墙或者重启电脑。如果还不行就重装软件。6.3 位逻辑的“手感”是怎么练出来的最后说点虚的但也是最重要的位逻辑的“手感”。什么叫手感就是你看到一个需求脑子里自动就能浮现出状态转移图你看到一个程序一眼就能看出哪里可能有问题你调试的时候不用看程序光看设备的动作就能猜出是哪个位出了问题。这种手感不是看书看出来的也不是听课听出来的是练出来的。我当年学PLC的时候没有仿真软件也没有那么多教程。我就是找了一个旧的三菱FX2 PLC接了几个按钮和指示灯然后一遍一遍地写红绿灯、写电梯、写流水灯。写错了就改改完再跑跑通了再改需求。就这样写了大概三个月突然有一天我觉得我“通了”。那种感觉就像学骑自行车突然就会了。所以如果你现在还在位逻辑里挣扎我的建议是别急着学高级指令别急着做复杂项目。找一个小PLC接几个按钮和灯把红绿灯写十遍把电梯写五遍。每写一遍你都会有新的体会。等你把位逻辑写“通”了后面的一切都会变得简单。最后分享一个小技巧写程序的时候养成“画状态图”的习惯。不管多简单的程序先在纸上画出状态转移图标清楚每个状态和转移条件。然后再打开编程软件照着图写。这样写出来的程序逻辑清晰排查也方便。我到现在还保持这个习惯哪怕是写一个最简单的启保停我也会先画一下。