三菱PLC五大功能指令详解:SUM、BON、DECO、ENCO、ZRST实战指南

📅 发布时间:2026/9/9 15:24:12
三菱PLC五大功能指令详解:SUM、BON、DECO、ENCO、ZRST实战指南 做三菱PLC项目这些年我总结了一个规律程序写到一定复杂度真正决定效率的不是那几个常开常闭触点而是功能指令用得好不好。尤其是在设备联调、上位机对接、数据统计这种场景里SUM、BON、DECO、ENCO、ZRST这五条指令出现的频率极高。它们单独拿出来都不难但很多新手只会用MOV和SET/RST一遇到“统计某段寄存器里有多少个报警位”“把一个按钮编号翻译成对应输出点”就卡住了。这篇文章我就把这五条指令的用法、原理、实战案例和踩坑经验一次说透建议你收藏后跟着敲一遍。1. 这五条指令到底在帮你解决什么1.1 从“继电器思维”切换到“字处理思维”PLC程序最开始是继电器逻辑一个X对应一个开关一个Y对应一个接触器这种思维非常直观。但当设备到了三十个点位、五十个报警、八个工位之后你再一个一个点位去SET和RST程序会变得又长又乱而且很容易漏。这时候就要引入“字”的概念。三菱FX系列里一个D寄存器是16位一个32位寄存器就是两个连续的D组合起来。SUM、BON、DECO、ENCO、ZRST这五条指令本质上就是在“位”和“字”之间快速切换的工具。它们不是用来替代基本逻辑的而是帮你把一批位当做一个整体来处理程序量能减少很多。我见过不少工程师把几十个报警用几十个触点逐个去统计程序写出来几百行后来换成SUM一条指令就解决了。这就是思维方式的差异。1.2 五条指令的分工速览先看一张表心里有个轮廓再往下看指令核心功能典型场景SUM统计16/32位中ON状态的数量报警点数、合格品计数、信号强度判断BON检测指定某一位的状态并输出到线圈解析状态字、把寄存器某一位变成M点DECO把数值解码成对应编号的位ON工位选择、多路输出控制ENCO把位的位置编码成数值按钮编码、工位号提取、优先权判断ZRST对一段连续区间批量复位一键复位、数据区清零、设备停止时清状态从这张表能看出来SUM和BON偏“统计和解析”DECO和ENCO偏“编码和解码”ZRST则是收尾清理的利器。后面我会一个一个拆开讲。2. 指令逐个拆解格式、原理、实例2.1 SUM统计16位里有多少个“1”SUM的指令格式是SUM S DS是源可以是字元件也可以是位元件D是结果寄存器存放ON的数量。如果源是字元件D0那么SUM就是统计D0这16位里为ON的位数。例如D0 H00FF也就是低8位全部为ON高8位全部为OFF那么执行SUM D0 D10之后D10的值就是8。如果源是位元件比如SUM X0 D10那么统计的是从X0开始的16个连续输入点X0到X15里ON的个数。这一点特别常用比如你有一组传感器输入想判断当前有几个工位在运行直接一条SUM就出来了。32位模式使用DSUM源跨越两个寄存器统计结果最大是32。注意DSU M的源如果是位元件需要从指定的位开始连续32个位比如DSUM X0 D10统计的是X0到X31。这条指令最需要注意的地方是结果范围。16位模式下结果只能是0到16不会超过这个值。不要以为D10能装下很大的数就乱用它会按16位源来计算。实际项目里我用SUM做报警统计时会先把报警点整理到连续的M区然后一次性统计非常方便。2.2 BON按位取状态做定位判断BON的格式是BON S D n意思是检测源S的第n位是ON还是OFF然后把结果输出到D。D一般是位元件比如M、Y。举个例子BON D0 M10 K5如果D0的第5位bit5为ON则M10为ON如果为OFF则M10为OFF。D0本身的值不会被改变它只做只读检测。这条指令特别适合解析通讯数据。伺服驱动器、变频器、智能仪表通过MODBUS或CC-Link通讯返回的状态字一般是按bit定义的比如bit0是准备好、bit1是运行中、bit2是报警。你用BON直接把每一位拆到M点触摸屏上就能直接显示状态不需要写一堆WAND和CMP去比较。32位模式对应DBON可以检测32位寄存器里的任意一位n的范围是0到31。实际使用中我见过有人把BON当成位判断的“瑞士军刀”什么状态都往BON上靠其实它的正确定位是“把寄存器里的某一位拎出来变成独立信号”用于减少通讯协议处理和梯形图判断逻辑。2.3 DECO把数字翻译成位DECO的格式是DECO S D n它做的事情是把源S的低n位看作一个数值然后让目标D开始的第“这个数值”个位变为ON其他位都变为OFF。这里需要区分目标D是位元件还是字元件两种情况差别很大。先看位元件的情况。如果D是M或Y这类位元件n可以取1到8。例如DECO D0 M100 K4源D0的低4位如果数值是5那么M105变为ON而M100到M115这16个位里其他15个全部变为OFF。再看字元件的情况。如果D是D寄存器那n固定取0。例如DECO D0 D1 K0这条指令把D0的低4位数值解码到D1的16个bit中。如果D0低4位是5那么D1的bit5变为ON也就是D1 H0010。DECO最有价值的地方是它一条指令就代替了十几个比较指令。比如你要根据工位号D0去选择8个气缸动作用一堆CMP去判断D0等于0、等于1、等于2程序写得很痛苦。用DECO D0 M0 K3直接让M0到M7里对应位置为ON后面每路动作就用对应的M点去控制梯形图清爽很多。2.4 ENCO把位的位置编码成数字ENCO和DECO正好相反格式是ENCO S D nS是源位元件D是目标字元件n是编码位数。它会在从S开始的2的n次方个位里找到编号最大的那个ON位然后把这个编号写到D的低n位。举例ENCO M100 D0 K4源范围是M100到M115一共16个位。如果M103、M110、M115都是ON那么ENCO会取编号最大的M115对应的位置编号是115减100等于15所以D0的结果就是15也就是二进制的1111。如果只有M103为ON则D0等于3。这里有个容易踩的坑如果所有位都是OFFD0的结果是0如果只有第0位也就是M100为OND0的结果也是0。这两种情况的结果看起来一样程序里无法区分。所以使用ENCO时最好先加一条判断确认源范围内至少有一个位ON再去取编码结果。ENCO在按键抢答、工位输入合并这种场景下非常实用。多个按钮同时按下时它会自动取编号最大的那一个你可以利用这个特性做优先权处理不用额外写联锁。2.5 ZRST区间批量复位ZRST的格式是ZRST D1 D2它会把从D1到D2这段区间内的同类元件全部复位。D1和D2可以是位元件也可以是字元件但必须类型相同不能M和D混着来。例如ZRST M0 M50会把M0到M50这51个位全部变为OFF。再比如ZRST D0 D99会把D0到D99这100个寄存器的值全部清零。这条指令最大的价值就是“一键复位”。设备停止时你需要把一批中间继电器、状态标志、计数器、数据寄存器全部清干净用ZRST一次搞定。以前用RST逐条写几十个RST放在程序里既不美观也容易漏。ZRST本身没有32位版本但你可以对连续的字范围操作例如ZRST D100 D199这相当于把100个16位寄存器全部清零对32位计数器来说一次性清零连续两个寄存器即可。ZRST对定时器T和计数器C也能起作用。例如ZRST T0 T5可以让定时器线圈和当前值都复位。但要注意计数器C200以后是32位计数器复位的区间范围要按32位计数器所在寄存器对的个数去推算最好查阅对应系列手册。3. 实战三条指令组合成一套完整的控制逻辑3.1 案例一8工位转盘用DECO ENCO做工位选择我做过一个8工位转盘设备每个工位有一个到位传感器操作台上有8个按钮工人按下某个按钮就要求转盘停到对应工位并且把该工位的夹具松开。第一步是按钮编码。8个按钮接在X0到X7上执行ENCO X0 D0 K3按下X5D0等于5按下X7D0等于7。如果同时按下多个它自动取编号最大的那个这符合“优先靠后”的操作习惯。第二步是工位选择输出。执行DECO D0 M100 K3D0等于5时M105变为ON这个M点直接驱动工位5夹具松开。M100到M107分别对应8个工位的选择状态梯形图里逻辑非常清晰。第三步是转盘动作完成后清理。转盘到位并结束动作后执行ZRST M100 M107 ZRST D0 D0把所有工位选择位和工位号清零为下一次运行做准备。这三条指令合在一起替代了我原来写的二十多行比较和复位逻辑而且调试时通过监控M100到M107一眼就能看到当前选择了哪个工位非常直观。3.2 案例二用SUM统计报警点位配合ZRST做一键复位设备上有一组32个报警点分布在M0到M31。触摸屏首页要显示“当前报警数量”同时按钮按下后要一键清除所有报警。统计数量用32位SUMDSUM M0 D200因为源是M0开始的连续32个位D200里就是当前报警总数。触摸屏直接读取D200显示不需要在触摸屏里写任何脚本。一键复位用ZRSTX20 ----| |----( PLS M500 ) M500 ----| |----------------------------[ ZRST M0 M31 ]---X20是触摸屏或面板上的复位按钮按下后M500产生一个扫描周期的脉冲ZRST把M0到M31全部复位。这里用PLS脉冲是有讲究的如果不用PLSZRST会在整个按钮按下期间反复执行虽然结果一样但会让程序扫描周期变长用PLS只执行一个扫描周期逻辑更干净。这个案例最实用的一点是报警点必须整理在连续区间内。如果报警点散布在M0、M10、M200那SUM没法一次统计ZRST也没法安全复位。所以我在项目初期分配M区时会专门划出一段连续区间给报警比如M0到M63所有报警统一映射到这里。这样后面统计和复位都会非常省事。3.3 案例三用BON拆设备状态字对接触摸屏和上位机伺服驱动器通过MODBUS返回一个状态字到D100bit定义如下bit0是准备好bit1是运行中bit3是报警bit7是原点回归完成。如果靠上位机或触摸屏去解析这个字每次都要做位运算通讯压力大而且不直观。我在PLC里用四条BON指令把它拆成四个独立M点M8000 ----| |----[ BON D100 M200 K0 ]--- M8000 ----| |----[ BON D100 M201 K1 ]--- M8000 ----| |----[ BON D100 M202 K3 ]--- M8000 ----| |----[ BON D100 M203 K7 ]---M200是准备好M201是运行中M202是报警M203是原点回归完成。触摸屏直接读M200到M203显示状态指示灯非常简单。上位机如果要用LabVIEW或者其他组态软件读也只需要读这几个M点不需要去解析MODBUS寄存器里的bit。这个思路也可以反过来用。你有一批散乱的输入点要发给上位机先用BMOV把M区的16个位组合成一个字上位机收到一个寄存器就能知道16个点位的状态这就是状态字压缩。上位机界面里的“按位显示”就是这个原理比如Grafana面板上的一些告警项也是通过类似方式把位状态展开的。4. 现场最容易踩的坑我帮你总结成了“排错清单”4.1 操作数范围设错程序编译不过去这是新手最容易犯的问题。DECO和ENCO的n不是随便取的n决定了参与运算的位数量是2的n次方。比如DECO中n取4目标位区就是16个位从M100到M115n取8目标位区就是256个位从M100到M355。如果写成DECO D0 M100 K8那就要求M100所在区间能覆盖256个连续位一旦超出该软元件类型的最大范围GX Works编译时会直接报错。还有一种情况是程序能编译过但运行时行为不对。比如ENCO的源位范围不够你写的源是M10 K8理论上源范围是M10到M265共256个位但FX3U的M区可能被前面用了很多后面的位牵连到了其他程序导致编码结果异常。所以用这类指数型指令前先数一数自己划定的位区间是否完整。4.2 索引变址与ZRST连用区间关系可能被“翻转”ZRST支持用变址寄存器Z去修饰D1或D2。例如ZRST D0Z0 D10Z1如果Z0当前值为5Z1当前值为3那实际复位范围是D5到D13这个没问题。但如果Z0改成5Z1改成1实际范围就变成了D5到D11还是正常的。问题出在D1的最终地址大于D2的情况。比如Z0当前值为10Z1当前值为0范围是D10到D10这没毛病。可一旦你用循环程序去修改Z0让它大于D2的最终地址三菱的ZRST不会帮你自动交换区间它只会按从D1到D2的方向执行结果就变成只复位D1一个地址或者干脆没有达到预期效果。所以我的习惯是只要ZRST参与了变址就在执行前用比较指令判断Z0和Z1的关系确保D1最终地址不大于D2。如果两个端点都是固定地址那只要D1的编号小于等于D2就可以。4.3 仿真通了现场不行扫描周期与输入滤波差异GX Works2的仿真功能对这几条指令的运算结果模拟得很准确但现场和仿真最大的区别在于物理信号的真实时序。我之前做过一个抢答器项目用ENCO X0 D0 K3去编码8个抢答按钮GX Works仿真里一切正常但现场调试时按钮按下后编码结果偶尔会跳变。后来查了很久发现是两个按钮被同时按下时它们之间的时间差只有几毫秒而PLC的输入滤波默认时间是10毫秒左右。在滤波窗口内X输入状态可能瞬间出现两个ONENCO取编号最大的那一个所以结果会出现“跳号”现象。解决方法是两种。第一种是调整PLC输入滤波时间X0到X7统一设置成1毫秒或更短。第二种是在ENCO后面加一个“确定键”联锁只有按下确认按钮才把编码结果锁存到D寄存器这样即使输入有抖动也不会影响最终工位号。4.4 常见问题速查表现象可能原因处理办法SUM结果明显偏大源位区间里有未使用的位常ON把多余位手动置OFF或改用只包含有效位的字寄存器DECO输出位置不对n取错实际区间不是2的n次方按2的n次方反推区间检查编译范围ENCO结果和按钮位置对不上多个按钮同时ON取的是最大编号增加联锁或按需求调整优先级ZRST执行后仍有位为ON复位后程序马上又SET了该位检查逻辑顺序确认复位指令在置位逻辑之后通讯状态字解析错误BON的n写错位编号从0开始先看手册的bit定义再从0开始编号这张表基本覆盖了我这几年现场调试遇到的主要问题。你如果遇到其他奇怪现象优先打开监控模式把源寄存器的当前值和目标M点的状态逐个对照通常几分钟就能定位。5. 除了以上案例这几条指令还能这样用5.1 状态字压缩与远程监控现在很多项目都要接MES、SCADA或者自建监控平台。上位机读PLC点位点位越多通讯负担越重。如果现场有几百个输入点每个点都单独建通道上位机配置量非常大。我的做法是用MOV指令把连续M区的16个位打包成一个字再用MODBUS去读这个字。例如MOV M0 D100就把M0到M15打包到了D100。上位机收到D100后按bit展开就能得到16个点位状态。如果需要做更复杂的统计比如监控面板上显示“当前有几个报警”那就用SUM对打包后的字再统计一次上位机只需要读D200这一个寄存器就够了。BON则是反过来用当上位机把状态字写过来时PLC端用BON拆成M点。这种双向处理的思路在对接LabVIEW、组态王、Grafana这类工具时特别实用。5.2 步进电机与HMI联动中的典型用法控制步进电机时经常要做速度档位选择和当前位置判断。比如设备上有8个速度档位物理上是一个8位拨码开关接到X0到X7用ENCO X0 D0 K3就能把档位号直接读出来然后通过比较档位号去调用对应的脉冲频率参数。如果不用ENCO就得写8行CMP去判断档位。ZRST在步进屏控制里也常用。设备停机时需要把当前脉冲累计寄存器、方向标志、运行中标志、暂停标志全部清掉一条ZRST把连续分配区的寄存器和M点一次性复位避免下次启动时残留数据导致误动作。和HMI联动时触摸屏上如果有很多报警指示灯对应的M点建议全部放在一个连续区段。这样ZRST一键复位报警灯时只需要一条指令不需要在触摸屏脚本里逐个复位。这个设计在项目前期分配软元件地址时就要想好。5.3 FX系列和Q系列的区别这套指令在FX和Q系列里都支持Q系列的功能更强大操作数范围更大。比如Q系列中软元件的编号范围和FX不同M区、D区的可用地址更多DECO和ENCO的位数范围也可能有细微差异。换平台时不能只改PLC型号必须把指令手册翻一遍确认软元件编号、操作数边界、双字指令对应关系。另外Q系列里有些指令支持文件寄存器、支持多维数组访问ZRST对特定存储区可能还需要额外的操作。我的建议是项目从FX迁移到Q系列时先用小程序把每一条指令在模拟环境里跑一遍确认结果和FX一致后再批量移植。最后再分享一个小技巧我每次教徒弟用这五条指令都会让他们做一个小练习用X0到X7接8个按钮用Y0到Y7接8个指示灯要求按任意按钮时只有对应指示灯亮同时用D0显示当前按钮编号。这个练习把ENCO、DECO、ZRST全部用上了一小时内基本能掌握核心用法。我个人的体会是功能指令不是背得越多越厉害而是要在项目里真正用上一次才会形成肌肉记忆。这篇文章里提到的几个案例建议你在GX Works里逐个敲一遍甚至故意把n写大、把范围写错多看几次报错信息你就真正理解了。下次做项目再遇到类似需求你会回来感谢这几个指令的。