Skip to content

应用指令例程 ​

应用指令(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>)。

相关文档 ​

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研