主题
写出可靠的梯形图程序
这一页讲的不是"某条指令怎么用",而是一个程序整体该怎么写 —— 从需求到分段、从分段到完整程序的那套规矩。 看完 梯形图基本概念 和 软元件一览 之后读这一页, 再照着 编程例程 动手,写出来的程序一次就能跑通。
为什么需要这一页:写错梯形图,九成不是指令不认识,而是分段分错—— 输出直接挂母线、该互锁的没互锁、该留回差的没留。 下面这些规矩,每一条都对应现场真实程序和调试中反复踩的坑。
一、三条铁规矩
铁规矩 1:每段 = 触点开头 → 输出收尾
一段(一条梯级)必须是:触点条件在前,输出在后。 OUT(输出线圈)前面一定要有触点,不允许直接挂在左母线上。
❌ 错误写法:
OUT Y0 ; 错误:输出前面没有任何触点
END✅ 正确写法:
LD M8000 ; 常通条件:设备 RUN 期间一直 ON
OUT Y0 ; 触点开头 → 输出收尾
END想让一段程序每个扫描周期都执行,就让它以 LD M8000 开头 (M8000 是运行监视继电器,RUN 时常 ON,见 特殊辅助继电器一览)。 没有条件就写 LD M8000,绝不裸写输出。
编辑器为什么不让 OUT 挂母线
编译时校验器会报「线圈左侧必须有输入条件」(E020)。这不是编辑器刁难—— 裸输出意味着"无条件执行",逻辑上通常不是您想要的,多半是漏写了条件。
铁规矩 2:指令只从速查表里选
本机兼容三菱 FX3U 指令集,但只是它的子集。 写程序、或让 AI 帮您生成梯形图之前,先查 指令速查总表—— 表里逐条标了这条指令在本机能不能用。用表里没有的指令,编译直接报 6506(不支持的指令)。
铁规矩 3:注释用 ;,每段从 LD/LDI 起头
- IL(指令表)的行尾注释用分号
;:LD X0 ; 启动按钮。 - 每一段用
LD/LDI(或比较触点LD>=、LD<这类)起头; 上一段的输出写完后,下一段要重新从LD开始。
二、心智模型:程序就是一张反复通电的电路
PLC 每个扫描周期从上到下跑一遍您的程序(扫描周期与能流详见 梯形图基本概念)。 所以写梯形图不是在"写步骤",而是在"画电路":
- 想保持:加自锁触点(输出并上自己的常开)。
- 想互斥:串入对方的常闭触点(正转串
ANI Y1,反转串ANI Y0)。 - 想防抖:阈值控制留回差(见骨架 4)。
- 想按顺序动作:用时序步进(见骨架 3),不要用一堆定时器互相顶。
同一个输出元件(Y/M)只应在一处驱动;多处 OUT 同一个线圈, 后面的会覆盖前面的,程序互相打架,调试时极难查。
三、从需求到程序:五步
以"电机正反转"为例,走一遍完整过程。
第 1 步:列输入输出表
| 元件 | 接什么 | 说明 |
|---|---|---|
| X0 | 正转启动按钮(常开) | 按下 ON |
| X1 | 反转启动按钮(常开) | 按下 ON |
| X2 | 停止按钮(常闭) | 按下断开 |
| Y0 | 正转接触器 | |
| Y1 | 反转接触器 | 与 Y0 绝对不允许同时吸合 |
第 2 步:每个输出写一段——Y0 一段、Y1 一段,互不混写。
第 3 步:先写主回路(启保停)——启动 OR 自保持,串停止。
第 4 步:加保护——正转段串 ANI Y1,反转段串 ANI Y0,双向互锁。
第 5 步:通读一遍——上电不动作吗?两个按钮同按会怎样?停止可靠吗?
完整程序:
LD X0 ; 正转启动
OR Y0 ; 自保持
ANI X2 ; 停止
ANI Y1 ; 反转互锁:反转运行时禁止正转
OUT Y0
LD X1 ; 反转启动
OR Y1
ANI X2
ANI Y0 ; 正转互锁
OUT Y1
END程序互锁不能代替电气互锁
双向互锁防的是程序层面同时输出。接触器触点熔焊时仍可能短路, 正反转接触器外部仍须加机械/电气互锁。详见 基本回路例程 例程 2。
四、四个可以直接照抄的骨架
骨架 1:启保停 + 互锁(一切连续运行的起点)
LD 启动 / OR 自身 / ANI 停止 / ANI 对方 / OUT,五个元件固定套路。 完整例程(含单按钮启停、两地控制、闪烁报警)见 B1. 基本回路例程。
骨架 2:报警锁存与确认(瞬时故障也不能丢)
SET 锁存、RST 确认:故障哪怕只来一个扫描周期,也要保持报警到人来看。
LD X10 ; 故障输入(哪怕只闪一下)
SET M100 ; 锁存
LD X11 ; 确认按钮
RST M100 ; 人工解除
LD M100
OUT Y10 ; 报警灯
END完整版(含闪烁、确认不掉的处理)见 B1. 基本回路例程 例程 5。
骨架 3:STL 步进——按顺序动作的工艺
一台设备要"第 1 步 → 第 2 步 → 第 3 步"按序动作(搅拌机、灌装线、机床工步), 不要拿定时器互相顶,用 STL 步进:每一步是一个状态 S, SET 下一步的瞬间,上一步自动复位(它带的输出、定时器全部停止)。
场景:搅拌机——启动后 进料 3 秒 → 搅拌 10 秒 → 出料 5 秒,自动回初始等下一轮。
LD M8002 ; 上电初始脉冲,只 ON 一个扫描周期
SET S0 ; 进入初始步
STL S0 ; 初始步:等待启动
LD X0 ; 启动按钮
SET S20 ; 跳到步 1
STL S20 ; 步 1:进料 3 秒
LD S20 ; 步进位当本步的驱动条件
OUT Y0 ; 进料阀
OUT T0 K30 ; 3 秒(T0-T199 时基 100ms)
LD T0 ; 时间到
SET S21
STL S21 ; 步 2:搅拌 10 秒
LD S21
OUT Y1 ; 搅拌电机
OUT T1 K100 ; 10 秒
LD T1
SET S22
STL S22 ; 步 3:出料 5 秒
LD S22
OUT Y2 ; 出料阀
OUT T2 K50 ; 5 秒
LD T2
SET S0 ; 完成一轮,回初始步
RET ; 步进区结束
END要点
- 每步内
LD S20让步进位当驱动条件——本步的输出、定时器都由它驱动。 SET S21的瞬间 S20 自动断开:Y0、T0 随之停止,不需要手动复位任何东西。- 每步的"出口条件"独立(时间到、到位开关、人工判断都行)。
- 步进区不能用 MC/MCR,以
RET收尾;完整规则见 程序流程 (4.1) 的 STL 一节。
验证:启动后 Y0 亮 3 秒 → 熄灭同时 Y1 亮 10 秒 → Y2 亮 5 秒 → 全部熄灭。 运行中断电重启,应停在初始步等待启动,不会自动继续。
常见坑
- 用普通线圈 + 自锁拼凑顺序:步数一多就互相打架,改一步崩三步——这正是 STL 要解决的问题。
- 忘记
RET:编译报电路错误。 - 在步进区里塞子程序/中断调用(不允许)。
骨架 4:阈值控制必须留回差(恒压供水、温度上下限)
需求"水压低了启泵、高了停泵"。不要写成同一个值比较—— 到了临界点会每个周期启/停抖动(接触器快速吸放,很快就烧)。
场景:水压 D0(单位 0.01MPa)。低于 0.75 启泵,到 0.80 才停泵,中间 0.75~0.80 保持原状态。
LD< D0 K75 ; 低于下限 → 置位"运行请求"(锁存)
SET M0
LD>= D0 K80 ; 到上限 → 解除
RST M0
LD M0
ANI X1 ; 过载保护(常闭触点)
OUT Y0 ; 水泵接触器
END要点
- 启、停是两个不同的值,差值(回差)按现场允许波动选,常用 5%~10%。
- 用
SET/RST锁存请求位,再由请求位驱动输出——回差就体现在"置位值 ≠ 复位值"上。 - 驱动实际输出前串保护(过载、急停、手自动切换)。
验证:把 D0 从 90 往下调,到 75 以下泵启动;回调时在 75~80 之间泵保持运行 (这是回差生效的证据),到 80 才停。
常见坑
- 启停写同一个比较值 → 临界点抖动。
- 用
OUT代替SET/RST锁存 → 条件一消失泵立刻停,回差形同虚设。
模拟量/浮点版(RD3A 读压力、浮点比较)见 B4. 模拟量与浮点例程。
五、现场最常见的 10 个错
每一条都标了"错在哪、为什么错、怎么改"。 8、9 两条编译不拦,属于"程序跑起来了却不动作"那一类,现场最难查,写在最后特别提醒。
| # | 错误写法 | 后果 | 正确写法 |
|---|---|---|---|
| 1 | OUT Y0 直接开头,前面没有 LD | 编译报 E020「线圈左侧必须有输入条件」 | 补 LD M8000(或实际条件) |
| 2 | 用 MOV 传浮点 | 浮点占 2 个 D,MOV 只搬一半,数值全错且不报错 | 浮点传送用 DEMOV,整数转浮点用 FLT |
| 3 | T0 K10 当成 10 秒 | T0-T199 时基是 100ms,K10 只有 1 秒 | 要 10 秒写 K100;T200-T245 才是 10ms 时基 |
| 4 | 计数器到值后不再动作也不 RST | C0-C99 到 32,767 后一直停在导通态,不再计数 | 到值后 RST Cx 清零再用 |
| 5 | 阈值控制启停用同一个值 | 临界点每个扫描周期启/停,接触器抖动烧毁 | 启停留回差(见骨架 4) |
| 6 | 正反转只做单向互锁 | 另一方向仍能吸合,有短路风险 | 双向互锁 + 外部电气互锁(见骨架 1) |
| 7 | 让 AI 生成程序时不给指令边界 | AI 可能编出本机没有的指令,编译报 6506 | 先让 AI 读 指令速查总表,只用表内指令 |
| 8 | 用 # 给指令表加注释 | 编译失败:无法识别的操作数: # | 指令表的注释符只有 ; 和 // 两种 |
| 9 | OUT T0 少写设定值 | 编译不报错,但只编出一个普通线圈输出,定时器根本不计时(OUT T0 K50 才占 3 步) | 定时/计数器一律把设定值连着写:OUT T0 K50、OUT C0 K20 |
| 10 | END 之后还接着写指令 | 编译不报错、下载也成功,但 END 之后的行被静默丢弃,压根没进设备 | END 只写一次且是最后一行;要挂中断/子程序就 FEND 在前、END 收尾(见 程序流程与跳转) |
六、给 AI 的一句话口径
写 LPPLC 梯形图时:每一段以 LD/LDI(或 LD>=、LD< 这类比较触点)开头、以 OUT/SET/RST/应用指令收尾,OUT 绝不直接挂左母线; 需要常通条件就写
LD M8000。 一个输出只在一处驱动;连续运行加自锁(OR 自身)、互斥加双向互锁(ANI 对方)、 阈值控制留回差(SET/RST 两个不同的比较值)。 顺序工艺用 STL 步进,定时器按 T0-T199=100ms 换算 K 值,浮点传送用 DEMOV。 指令只从指令速查总表里选,表里没有的一律不写。
七、一个完整小例程(把上面全部用一遍)
场景:水泵控制。X0 手/自动(ON=自动)、X1 手动启动、X2 手动停止、 X3 过载(常闭)、X4 报警确认;D0 水压(0.01MPa);Y0 水泵、Y1 故障灯。
LD M8002 ; 上电初始脉冲
RST M0 ; 清运行请求,防止重启自启动
; ---- 运行请求 M0:自动按水压带回差,手动按按钮 ----
LD X0 ; 自动模式
AND< D0 K75 ; 且水压低于下限
SET M0 ; 置"运行请求"(锁存)
LD X0 ; 自动模式
AND>= D0 K80 ; 且水压到上限
RST M0 ; 解除请求——回差 = 80 与 75 之差
LDI X0 ; 手动模式
AND X1 ; 手动启动按钮
SET M0
LDI X0
AND X2 ; 手动停止按钮
RST M0
; ---- 请求 → 实际输出:串保护 ----
LD M0
ANI X3 ; 过载保护(常闭触点)
OUT Y0 ; 水泵接触器
; ---- 过载报警:锁存 + 确认 ----
LD X3
SET M100 ; 过载即锁存,哪怕只闪一下
LD X4 ; 报警确认按钮
RST M100
LD M100
OUT Y1 ; 故障灯
END要点
- 每段都是"LD/LDI 开头、输出收尾",没有一处裸输出。
- M0 是"请求"、Y0 是"实际输出",中间串保护——加保护不用改逻辑。
- 回差:SET 用 K75、RST 用 K80,两个值不同。
- 报警用 SET/RST 锁存,确认前一直保持。
- 上电
RST M0,防止断电重启后水泵自己转起来。
验证
- 自动(X0=ON):把 D0 调到 70 → Y0 启动;调到 78(回差区)→ 保持运行;调到 81 → 停。
- 手动(X0=OFF):按 X1 启、按 X2 停。
- 强制 X3 断开(模拟过载)→ Y0 断开、Y1 点亮;按 X4 → Y1 熄灭。
常见坑:忘了上电清 M0——断电前在运行的话,重新上电可能自启动。
八、现场程序实际长什么样
前面讲的都是"应该怎么写"。这一节是已经在现场跑着的程序真的长什么样—— 照着它安排自己的结构,比照着教科书安排省事。
| 现场形态 | 有多常见 | 对您意味着什么 |
|---|---|---|
梯形图整个空着,只有一句 END,逻辑全在 Lua | 约每 4 台就有 1 台 | 不是每台设备都需要梯形图。纯联网、纯转发、只算不改时序的设备,只用 Lua 更合适,别硬凑几段梯形图 |
每段都以 LD M8000 开头 | 三分之二的程序在用 | 这就是"常通执行"模型:条件恒真,动作每个扫描周期刷一次。要读传感器、要搬参数、要把值送出去,都用它开头 |
用 M8013(1 秒时钟)做周期任务 | 过半程序在用 | 想要"每秒做一次",LDP M8013 比自复位定时器省一段程序 |
程序第一条是 LDI T3 + OUT T3 K3 这一对 | 半数以上程序以 LDI 开头 | 现场习惯把自复位定时/时钟段放在最前面,后面各段再挂在这个节拍上 |
结尾是 FEND / NOP / END 三行 | 约一半的程序 | 这是编辑器导出的收尾形态。只写一个 END 也能编过,但别在 END 后面继续写东西(见第五节第 10 条) |
用 D□.bit(如 D100.3)当标志位 | 一半以上的在用程序 | 一堆报警位塞进几个 D 里传给上位机和云,比占几十个 M 省地址 |
用计数器当前值当数据源:MOV C10 D8028 | 大量在用 | 计数值不是只能看触点,可以直接搬走(详见 计数器) |
用 32 位比较触点 ANDD=、ANDD> | 上千次出现 | 阈值判断的现场主流写法是 LD M8000 + ANDD= D10 K5,不是先 CMP 再判位 |
梯形图和 Lua 怎么分工,现场收敛成一套很一致的规矩:
- 梯形图负责周期性、硬实时的部分——按节拍轮询从站、IO 联锁、时序、报警置位。它每个扫描周期都跑一遍,时序可预期。
- Lua 负责不定周期、要算要联网的部分——工程量换算、累计统计、协议解析、云端上报与下发。
- 两边只通过
D/M寄存器交接,不互相调用。 别让 Lua 去做急停联锁,也别让梯形图去拼 JSON。
完整的双引擎分工与四套可直接照抄的联网/上报套路,写在 现场程序常见架构套路。
相关文档
- 梯形图基本概念(扫描周期、能流)
- 指令速查总表(本机能不能用,逐条标注)
- 例程总览(完整可运行例程库)
- Lua 侧的同源方法论:现场程序常见架构套路