主题
应用指令例程
应用指令(FNC 10~59)的 6 个常用做法:比较传送、参数初始化、四则运算、移位队列、批量复位、高速计数测速。 每段都是完整可运行的程序,代码用 IL 指令文本表示(与梯形图一一对应),可直接录入或导入上位机。
返回 例程总览。
怎么读这段代码
IL 指令文本和梯形图是一回事:LD = 从左母线开始一个常开触点,AND/ANI = 串联,OR/ORI = 并联,OUT = 线圈。 应用指令(如 MOV、CMP)写在驱动条件之后,只有前面的条件成立才执行一次。 加 P 后缀(如 MOVP)表示"脉冲执行":条件从 OFF→ON 时只执行一次,而不是每个扫描周期都执行。
例程 1:用 CMP 做上下限报警(温度越限)
场景:采集值放在 D0,低于下限或高于上限都要报警。这是现场最常见的一个判断, 但它有两个容易写错的地方:CMP 的结果占用 3 个连续位,且驱动条件为 OFF 时结果保持不变。
软元件:D0 采集值(如温度 ×10)、M0~M2 下限比较结果、M10~M12 上限比较结果、Y0 低温报警、Y1 高温报警
LD M8000 ; RUN 时常 ON,保证每扫描周期都刷新比较结果
CMP D0 K100 M0 ; 与下限 100 比:D0>100→M0;=100→M1;<100→M2
LD M8000
CMP D0 K800 M10 ; 与上限 800 比:必须用另一组位,不能再用 M0~M2
LD M2 ; D0 < 100
OUT Y0 ; 低温报警
LD M10 ; D0 > 800
OUT Y1 ; 高温报警要点
CMP S1 S2 D的结果占 D、D+1、D+2 三个连续位,分别代表>、=、<,同一时刻只有一个 ON。- 两次比较必须各用一组位:第二次若仍写
M0,会把第一次的结果覆盖掉,低温报警就再也不会亮。 - 驱动条件要常 ON(
M8000)。用LD X0这种条件驱动时,X0 为 OFF 的整个期间 M0~M2 保持最后一次的结果,看起来像"报警卡住了"。
更省元件的写法(触点比较指令,见 比较与传送):
LD< D0 K100 ; D0 低于下限
OUT Y0
LD> D0 K800 ; D0 高于上限
OUT Y1验证:用上位机把 D0 写成 50 → Y0 亮;写成 900 → Y1 亮;写成 500 → 两个都不亮。 改 D0 后报警立刻跟着变(因为 M8000 常 ON)。
注意事项
- 把下限写成
CMP K100 D0 M0(源和目的顺序颠倒):比较方向反了,M0变成"D0 < 100",报警逻辑整个反过来。 - 忘记
CMP占 3 个位,在 M1、M2 上又接了别的用途,会出现"改报警参数却动了别的输出"。
例程 2:上电初始化与配方切换(MOV / DMOV / BMOV / FMOV)
场景:设备每次上电都要有一套确定的默认参数(否则 D 区是随机值), 切换产品时再把预先存好的配方整块搬到工作区。这是"参数不用每次手动输"的做法。
软元件:D100~D109 工作参数区、D500~D509 配方 1、D510~D519 配方 2、D200~D219 运行记录区、X1 选配方 1、X2 选配方 2、M100 切换脉冲
LD M8002 ; 只在运行后的第一个扫描周期为 ON
MOV K500 D100 ; 默认温度设定 50.0℃(放大 10 倍,避免小数)
MOV K30 D101 ; 默认延时 3.0s
FMOV K0 D200 K20 ; 运行记录区 D200~D219 一次性清零
LD X1
PLS M100 ; 切换信号取上升沿,按住也只搬一次
LD M100
BMOV D500 D100 K10 ; 配方 1:D500~D509 → D100~D109
LD X2
PLS M101
LD M101
BMOV D510 D100 K10 ; 配方 2:D510~D519 → D100~D109
LD X3
PLS M102
LD M102
DMOV D300 D400 ; 32 位传送:D300-D301 → D400-D401(累计值这类大数要用 DMOV)要点
M8002是初始化脉冲,只 ON 一个扫描周期,专门用来做上电初始化;别用M8000(常 ON),否则参数每个周期都被改写,运行中改不了。BMOV S D n是成批搬 n 个字,比写 10 条MOV短得多;FMOV S D n是把同一个值填进连续 n 个字(清零、填默认值用它)。- 搬 32 位数据(累计产量、长整数)必须用
DMOV,它一次性搬两个连续寄存器。 - 切换用
PLS取边沿:直接用LD X1驱动BMOV,按住按钮期间每个扫描周期都会搬一次,白白占用扫描时间。
验证:下载后先不碰任何输入,用上位机读 D100 = 500、D101 = 30、D200~D219 全 0; 然后给 X1 一个脉冲,D100~D109 变成 D500~D509 里的值。
注意事项
MOV的目标写成常数或输入继电器(如MOV K1 X0):应用指令的目标必须是能写的软元件,X不能写。BMOV的源区和目标区重叠(如BMOV D100 D102 K10)时结果取决于实现,务必错开两段区域。- 配方值本身没人写进去:上面只搬了"配方区 → 工作区",配方区 D500 起的值要用上位机先写入或走 掉电保持 存下来。
例程 3:产量累计、剩余数与完成率(ADD / SUB / MUL / DIV)
场景:每台产品经过传感器计一件,累计产量、算还剩多少、算完成率百分比、达标就点亮指示灯。 这套"计数 → 累计 → 百分比"是报表类需求的基本骨架。
软元件:X10 产品到位、M0 到位脉冲、D0-D1 累计产量(32 位)、D2 每箱件数、D100 目标产量、D10-D11 乘法结果、D20 完成率%、D30 剩余件数、Y10 达标指示
LD M8002
MOV K200 D100 ; 目标产量 200 件
MOV K10 D2 ; 每箱 10 件(DADD 用)
LD X10
PLS M0 ; 每件产品一个脉冲
LD M0
DADD D0 D2 D0 ; 累计产量 += 每箱件数(32 位加,D0-D1)
LD M0
SUB D100 D0 D30 ; 剩余 = 目标 - 已产(16 位)
LD M0
MUL D0 K100 D10 ; 产量 ×100 → 32 位结果占 D10-D11
LD M0
DIV D10 D100 D20 ; 完成率% = D10 ÷ 目标(商在 D20,余数在 D21)
LD>= D20 K100 ; 完成率 ≥ 100%
OUT Y10 ; 达标指示灯
LD X11 ; 清零按钮
PLS M1
LD M1
RST D0 ; 产量清零(32 位要清两个)
RST D1要点
DADD是 32 位加法,结果占 D0、D1 两个寄存器;产量可能超过 32767,所以别用 16 位ADD。MUL的 16 位结果也是 32 位(占 D10-D11),读结果时取 D10;DIV的商在 D、余数在 D+1(这里 D21 是余数,别当成结果)。- 完成率先乘 100 再除,是为了保留整数百分比:
200/200*100若先除就得到 1,再乘也只有 100,但中间步骤全是整数,顺序不能反。 LD>=是触点比较指令,比CMP省 3 个位元件,这里只判一个条件用它最合适。
验证:把 D100 设为 200、D2 设为 10,给 X10 两个脉冲 → D0 = 20、D30 = 180、D20 = 10(完成率 10%); 给满 20 个脉冲 → D0 = 200、D20 = 100、Y10 亮。
注意事项
- 16 位溢出:
MUL D0 K100 D10中若产量 ×100 超过 32767,D10 会溢出成负数,完成率变成怪值。目标产量大时改用 32 位指令(DMUL/DDIV)并把所有相关寄存器都按 32 位成对分配。 - 除数为 0:
DIV的除数(这里 D100)为 0 会触发运算错误(M8067)。上电初始化里必须先给 D100 一个值,别指望它是 0 以外的数。 - 忘了
PLS:直接用LD X10驱动,产品停在传感器前时每个扫描周期都加一次,产量飞涨。
例程 4:用 SFTL 做 4 工位移位队列
场景:传送带上有 4 个工位,工件每前进一格,各工位的"有/无工件"状态整体前移一位。 用一条移位指令代替一堆"工位 1 状态传给工位 2"的传送,工位数量变了只改一个参数。
| 软元件 | 作用 |
|---|---|
X0 | 传送带前进一格(接近开关脉冲) |
X10 | 上料口有工件(移入的"新数据") |
M100 | 前进脉冲(边沿) |
M0~M15 | 工位队列(M0=工位1 … M3=工位4) |
Y0~Y3 | 各工位执行动作 |
Y10 | 末端分拣 |
LD X0
PLS M100 ; 前进一格取一个脉冲
LD M100
SFTL X10 M0 K16 K1 ; 把 X10 的当前状态左移入 M0,原 M0→M1、M1→M2 …
LD M0 ; 工位 1 有工件
OUT Y0
LD M1 ; 工位 2 有工件
OUT Y1
LD M2
OUT Y2
LD M3 ; 工位 4(末端)
OUT Y3
LD M3
AND X11 ; 末端 + 分拣条件(如色标检测到次品)
OUT Y10 ; 分拣气缸动作要点
SFTL S D n1 n2:S是移入数据的起始位,D是移位区起始位,n1是移位区总位数,n2是每次移入的位数。这里K16 K1= 16 位区域、每次移 1 位。- 移入的是 X10 在执行那一瞬间的值:上料口有工件(X10=1)就移入 1,没工件就移入 0,所以用不着另建"新工件"标志。
- 移位区长度
n1必须大于实际用到的工位数(这里用 16 位装 4 个工位),留出的位可以在加工位时直接用。
验证:先强制 X10 = ON,给 X0 一个脉冲 → M0 = ON、Y0 动作; 把 X10 强制回 OFF 再给一次脉冲 → M0 变 OFF、M1 变 ON(工件走到工位 2)。
注意事项
- 移位区
M0~M15被别的程序当成普通中间继电器用,工件状态会被莫名改写。移位区必须整段独占。 - 忘了
PLS用LD X0驱动:传送带停在感应片上时每个扫描周期移一次,整条队列瞬间被冲空。 - 移位方向搞反:
SFTL是左移(编号增大方向),要把状态往编号小的方向传请用SFTR。
例程 5:一键复位与数据整理(ZRST / BMOV)
场景:换班或换批次时,一次动作把累计值、中间标志、状态位全部清干净。 手动一个一个 RST 既容易漏,改程序时又会忘记同步。
软元件:X20 换班复位按钮、M100 复位脉冲、D0~D99 累计与临时数据、M200~M299 中间标志、S0~S99 状态位、C0~C9 计数器
LD X20
PLS M100 ; 复位只执行一次
LD M100
ZRST D0 D99 ; 数据区 D0~D99 全部清零
ZRST M200 M299 ; 中间标志全部复位
ZRST S0 S99 ; 状态位全部复位
ZRST C0 C9 ; 计数器当前值与触点一起清掉要点
ZRST D1 D2把 D1 到 D2 之间所有同类软元件一次清掉:位元件变 OFF,字元件清零,计数器的当前值和触点一起复位。ZRST的两个操作数必须同类型,且D1 ≦ D2(写反了不生效)。- 复位按钮必须用
PLS取边沿,否则按住期间每个周期都清一次,这段时间内什么数据也记不下来。
验证:先让设备跑一会儿(让 D0、C0 有值),按下 X20 → 上位机读 D0~D99 全 0、C0 当前值归零、M200~M299 全 OFF。
注意事项
- 把不该清的寄存器划进了区间(比如把设定值区 D100 一起清掉),换班后设备参数全丢。先规划好地址分区再写 ZRST。
- 用
ZRST清T(定时器)时,正在计时的定时器会被强制归零,可能打断正在执行的时序;时序相关的复位建议单独RST。 - 上电初始化(例程 2 的
M8002段)和这里的手动复位要清的范围通常不同,别图省事直接复制同一段。
例程 6:用 SPD 测转速(脉冲密度 → RPM)
场景:接近开关或编码器接到高速输入,测电机/滚筒的实际转速,用于超速报警或速度显示。 这类需求不能用普通计数器在梯形图里数 —— 扫描周期跟不上脉冲速度,必须用高速处理指令。
软元件:X0 高速脉冲输入、D0~D2 SPD 结果区、D10-D11 乘法结果、D20 转速 RPM、Y10 超速报警
LD M8000
SPD X0 K1000 D0 ; 每 1000ms 统计 X0 的脉冲数:
; D0 = 当前值(每秒脉冲数)、D1 = 剩余时间、D2 = 上次结果
LD M8000
MUL D0 K60 D10 ; 每秒脉冲数 × 60 = 每分钟脉冲数(32 位结果占 D10-D11)
LD M8000
MOV D10 D20 ; D20 = 转速 RPM(1 个脉冲 = 1 转时)
LD> D20 K1500 ; 超过 1500 转
OUT Y10 ; 超速报警要点
SPD S1 S2 D在S2毫秒内统计S1的脉冲数,占用 D、D+1、D+2 三个寄存器(当前值 / 剩余时间 / 上次结果),这三个寄存器不能再挪作他用。- 转速换算:
每秒脉冲数 × 60 ÷ 每转脉冲数。本例按"1 脉冲 = 1 转"简化成只乘 60;若编码器是 100 脉冲/转,就把DIV补上(DIV D10 K100 D20)。 SPD由硬件计数,不受扫描周期影响,所以测量窗口可以精确到毫秒级;普通C计数器做不到这一点。
验证:给 X0 输入 10Hz 方波 → D0 ≈ 10、D20 ≈ 600;把频率提到 30Hz → D20 ≈ 1800、Y10 亮。
注意事项
- SPD 的三个结果寄存器被别的程序占用,读数会莫名其妙地跳。
- 输入点必须是支持高速计数的输入(一般是 X0~X5,见 高速计数器 的端子分配),接到普通输入点测不出高频脉冲。
- 软 PLC 模拟器(LP6666)没有硬件高速输入,
SPD在模拟器上读数通常为 0,这个例程请在真机上验证,不要以模拟器结果判断程序对错。 - 结果超过 32767 时
MOV D10 D20会溢出,高转速场合要用 32 位指令(DMOV)与 32 位比较(DLD>)。