梯形图怎么读:Stop 按下之后,端子还多亮一个扫描
程序说开、HMI 说开,端子还亮着一个扫描。梯形图不是电路图:三个网络、八个扫描,把四层状态分开。
一段梯形图里,最容易被看错的不是指令,是时间。
Stop 采样到 0 的那个扫描,程序已经把输出映像清掉了;但端子上的电还要等到下一个扫描开始时的输出传送才断。也就是说:程序说"停了"和现场真"停了"之间,隔着一个扫描。这不是实现瑕疵,是过程映像的默认更新边界。
下面这段来自英文技术索引 Atlas of Engineering 的《Reading and Testing PLC Ladder Logic》。它只用三个网络——一个起保停、一个接通延时定时器、一个输出赋值——把"输入映像、内部存储、输出映像、物理输出"这四层逐扫描拆开。原文在最后给了一句判断标准:梯形图是一份可执行的状态转换规格,读得懂它,意味着你能在看在线监视之前就预测出这次变化。
先定输入语义,再选触点
对梯形图的触点来说,"常开"和"常闭"描述的是逻辑判断:
| 指令 | 什么时候判为真 | 布尔含义 |
|---|---|---|
| 常开触点 | 它对应的位是 1 | x |
| 常闭触点 | 它对应的位是 0 | ¬x |
| 普通输出线圈 | 把进入的梯级结果写下去,包括 0 | 赋值 |
串联实现与,并联实现或。一个常闭指令并不能证明它对应的物理开关是常闭的。指令语义以 Siemens S7-1200 位逻辑文档 为准。
把教学用的输入这样定义:
| 变量 | 为 1 的含义 | 为 0 的含义 |
|---|---|---|
Start |
采样到启动按钮被按下 | 采样到启动按钮已松开 |
StopOK |
停止回路处于允许状态 | 有停止请求,或允许条件缺失 |
设想一个物理上是常闭的停止按钮,接线后松开时输入为 1、按下时为 0。于是程序里用一个逻辑常开的 StopOK 触点来放行。同一个位上用常闭指令,放行的就是相反的状态。这个命名选择让想要的逻辑变得明确。
也要看到反例:一根断线同样能让 StopOK = 0;一个跨接在开关两端的短接可以掩盖一次按下。一个输入既不能诊断所有故障,也不构成安全性能等级。逻辑极性只是控制设计的一部分。
把扫描约定写清楚
这个例子遵循 Siemens S7-1200 在 V20 文档中描述的默认循环过程映像顺序:一个周期开始时,控制器先把已有的输出映像传送到配置好的物理输出;然后采集输入,执行循环程序。程序指令在这段执行里更新内存和输出映像。参见 RUN 模式下扫描周期的处理。
原文的模拟器刻意只选一个任务、每个扫描各更新一次输入/输出映像、不做立即读外设,它的理想扫描间隔恒定。中断、分布式 I/O 调度、模块时延都在这个模型之外。
对扫描 n,要分开四样东西:
- 输入映像:本次执行全程使用的
Start与StopOK采样值。 - 内部存储:指令执行过程中被读写的值。
- 输出映像 Q_n:扫描 n 里程序执行完的结果。
- 扫描 n 期间的物理输出:本次输入采集之前传送出去的那份更早的映像 Q_{n−1}。
后面网络的一条指令可以读到同一个扫描里前面网络刚写过的内部位。但这不等于一个普通物理输出会在同一时刻变化。不同控制器配置的更新边界不一样——在把这套时序解释搬过去之前,先确认你手上这台用的是哪一种。
网络 1:把自锁写显式
把 StopOK 串在 Start 与 Run 的并联组合之前,再串一个普通 Run 线圈。令 K_n 为 StopOK、S_n 为 Start、R_n 为新赋值的 Run 状态:
R_n = K_n ∧ (S_n ∨ R_{n−1})
自锁触点读到的是上一轮的值,因为在这个例子里没有任何更早的指令写过 Run;随后线圈把它替换掉。这就是自锁(seal-in):记忆通过布尔反馈路径保存,而不是靠一条专门的置位指令。
| StopOK | Start | 上一轮 Run | 新 Run | 解释 |
|---|---|---|---|---|
| 0 | 任意 | 任意 | 0 | 停止同时封锁两条路径 |
| 1 | 1 | 任意 | 1 | 启动建立 Run |
| 1 | 0 | 1 | 1 | 自锁分支维持 Run |
| 1 | 0 | 0 | 0 | 没有启动、也没有已存下的请求 |
停止之所以优先,是因为它在并联分支的外面。如果那个并联分支跨过了 StopOK,自锁路径就能压过停止。如果去掉反馈触点,Run 会跟着按钮走,Start 一松手就消失。

逻辑网络,不是接线图。从左往右读,按 1、2、3 的顺序执行。图中所有触点都在测 1。网络 1 里的 Run 触点读的是旧内存;网络 2 和 3 里的 Run 触点读的是新值。TON0 每个扫描都会被算一次,包括 Run 为假的时候。
网络 2:每个扫描都要调用接通延时定时器
IEC 风格的 TON 是把一个真输出往后延。把 Run 接到它的 IN,给一个固定的预设 PT,把输出 Q 拷给 DelayDone;已过时间输出是 ET。用专用的定时器实例 TON0,免得它的计时状态被别处无意共享。
对 Siemens 的 TON 指令:IN 上升沿开始延时;PT 走完且 IN 仍为真时 Q 变真。IN 为假会复位 Q 与 ET。这个例子每个扫描都调用定时器,所以当停止把 Run 清掉时,它能看到那个假输入。
不要写成"只有 Run 为真时才调用 TON",然后假设跳过调用等价于输入为假。定时器有状态,更新它是一次被执行的操作。Siemens 在定时器工作原理里说明了它的时基和更新点。
原文的教学模型在第一次为真的调用时记下起始时间戳。之后每次 Run 为真的调用:
ET_n = min(PT, t_n − t_start)
D_n = (ET_n ≥ PT)
Run 为假时把 ET_n 置 0、D_n 置 0。这里 D_n 就是 DelayDone。定时器不是在数扫描次数:已过时间来自时钟;扫描间隔恒定只是让这个例子的采样时间戳好算。
取 PT = 30 ms、间隔 10 ms。如果第一次为真的调用发生在扫描 1,它的 ET 是 0;扫描 2、3 报 10 和 20 ms;扫描 4 到 30 ms。把第一次为真的调用算成 10 ms,就会早一个扫描就使能。
如果 PT 改成 25 ms,调用仍然每 10 ms 一次。第一个达到或超过阈值的调用在起始后 30 ms,所以采样到的 DelayDone 相对理想阈值晚了 5 ms。这个观测延迟,和随后的输出传送是两件不同的事。
网络 3:给输出映像赋值
把 Run 和 DelayDone 串联,结果赋给一个普通的 MotorCmd 输出线圈:
Q_n = R_n ∧ D_n
显式写上 Run 条件,让"使能意图"在图上看得见。网络 3 读到的,是网络 1 和 2 在这个扫描里产生的值。因此观察到停止的那个扫描,输出映像就已经被清掉——即便定时器此前已经到时。
每一个这样的位,只保留一个赋值位置。如果两个普通线圈在同一个扫描里写同一个位,后执行的赋值会盖掉先前的。同样,交换网络顺序能让一段梯级作用在过期状态上。没有执行顺序,一个梯形图页面的视觉连通性不足以作为程序行为的证据。
走一遍完整的启停
把非保持型 Run、定时器状态和输出映像初始化为 0。在这条指定的轨迹里,Start 只在扫描 1 为真;StopOK 在扫描 7 为假、其余为真。时间戳间隔 10 ms,定时器 PT = 30 ms。
| 扫描 | Start | StopOK | 网络 1 之后的 Run | ET (ms) | DelayDone | 输出映像 | 物理输出 |
|---|---|---|---|---|---|---|---|
| 0:初始化 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| 2 | 0 | 1 | 1 | 10 | 0 | 0 | 0 |
| 3 | 0 | 1 | 1 | 20 | 0 | 0 | 0 |
| 4 | 0 | 1 | 1 | 30 | 1 | 1 | 0 |
| 5 | 0 | 1 | 1 | 30 | 1 | 1 | 1 |
| 6 | 0 | 1 | 1 | 30 | 1 | 1 | 1 |
| 7 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 8 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
扫描 2 时 Start 已经是假,但 Run 保持住了。扫描 4,指令映像变真,端子到扫描 5 才跟上。扫描 7,程序已经响应了停止,但端子还带着扫描开始时传送出去的那份映像;到扫描 8 它才变假。真实的输出模块和执行机构还会再加延迟,这张表不计算机器停止时间。
原文的实验台:四件要盯的东西
原文配了一个可逐步回放的实验台,默认参数是:扫描间隔 10 ms、接通延时预设 30 ms、第一次停止发生在扫描 7、停止保持 1 个扫描、启动在扫描 1 之后松开(只给一个扫描的脉冲)。它按初始化的内存把十个扫描全算一遍,不是往运行中的 PLC 注入实时输入;理想固定间隔是指定的,不是对 CPU 性能的预测。
实验台有两张曲线、四条说明,值得原样保留:
- 01 · Run 存储器与输出状态:蓝线是网络 1 之后的
Run;粉色虚线是网络 3 之后输出映像里的MotorCmd;绿色是在本扫描开始时传送之后的理想输出端子。一个扫描的差,就是所选映像更新约定的一部分。 - 02 · TON 调用报告的已过时间:第一次为真的调用报 0,之后的调用把时钟已过时间和 PT 比较,
IN为假的那次扫描复位定时器。阶梯状的轨迹画的是调用时报告的值,不是只按扫描数推进的时钟。
四句话总结这段:
- 用扫描 1、2、4、5、7、8 看。启动在扫描 1 之后松开,但自锁分支保住了
Run;映像在扫描 4 变真、端子在 5;停止在扫描 7 清映像,端子在 8 跟随。 - 在这套逻辑里停止优先。
StopOK在Start/Run并联分支的外面。它为假时,启动和保持两条路径同时被封;普通Run线圈写入假,无条件的 TON 调用复位ET和Q。 - 按住不放的启动按钮可以再启动。第四个预设里,停止在扫描 3 清掉
Run;扫描 4StopOK回来时Start还按着,于是Run再次置位、定时器从零重来。要求"必须重新按一次"的话,需要额外的状态和一个明确定义的重启策略。 - 模型的选择要说出来。它按 Siemens V20 帮助里 S7-1200 的默认循环过程映像顺序:输出传送、输入采集、程序执行;忽略网络执行时间;不含直接读外设、中断任务、网络 I/O 调度和模块时延。它不是一个通用 PLC 仿真器,也不是安全功能。
测的是转换,不只是稳态
先写预测轨迹,再拿所选程序与模拟器去对照。有用的测试都作用在存储状态发生变化的时刻:
| 测试 | 在这个例子里的预期 | 它能暴露的故障 |
|---|---|---|
| 启动只给一个扫描,然后松手 | Run 保持为真直到停止 |
自锁分支缺失或接错 |
| 启动与停止在同一扫描被采样 | Run 保持为假 |
停止被放到了分支可以绕过的位置 |
| 超时前停止 | ET 与 DelayDone 复位;输出从不使能 |
定时器没有用假输入被调用,或用的是过期结果 |
| 超时后停止 | 映像立刻清;端子在下次传送时跟随 | 把映像状态与端子状态混为一谈 |
| 松手的状态下松开停止 | Run 保持为假 |
出现意料之外的保持或另处置位 |
| 按住启动时松开停止 | Run 再次置位,计时重新开始 |
假设自锁必然要求重新按一次按钮 |
最后一条行为在这段小布尔程序里是有意为之,在真实机器上可能不可接受。如果需求是"必须有一次明确的新启动动作",那就加一个明确定义的边沿/复位重臂(rearm)或重启许可设计,并且测它。仅仅把按钮叫"点动",并不能阻止它被按住或卡住。
启动测试是另一件事:配置并验证哪些变量保持值、哪些被初始化、输出的替代状态是什么、有哪些启动逻辑会执行。原文的实验台永远从它声明的零状态开始,它不主张热重启、恢复供电或下载项目会让真实 PLC 的每个变量按同样方式复位。
工程意义
梯形图是一份可执行的状态转换规格。一段读得懂的程序,把输入极性、竞争请求的优先级、每个状态位的归属、每次观测的时机都写明。这样别人才可能在看在线监视之前先预测出这次变化。
它同时给故障定位:如果输入映像从来没有记录到一个脉冲,改自锁表达式也救不回一个任务从未观测到的事件(原文另有丢脉冲案例,讲输入滤波、采集与任务时序)。如果映像里的指令是对的、执行机构却不响应,那该查输出传送、硬件和物理过程,而不是先怀疑这段梯级写错了。
最后一句边界:逻辑上的停止优先不是一项安全主张。普通程序不评估容错、诊断覆盖率、独立停机路径和物理停止包络。那些属于另行设计的安全功能,对应的是另一种证据边界(原文的安全联锁定期试验讲的是这条线)。
附答案的小练习
- 物理按钮是常闭的,为什么程序里用逻辑常开的
StopOK?因为StopOK为 1 才表示允许运行。指令测的是采样到的位,不是开关的构造。 - 调用间隔 5 ms、PT = 25 ms,扫描 1 启动后映像第一次在哪扫描使能?扫描 1 + 25/5 = 6,前提是
Run保持为真。按所选更新约定,端子在扫描 7 跟随。 - 非保持型 TON 在停止 20 ms 后还记得吗?不记得:
IN为假的那次调用复位ET与Q,新的一次Run从零开始计时。 - 扫描 3 出现一个扫描的停止,而
Start一直被按住,会怎样?Run在 3 清零、在 4 重新置位,ET = 0。在默认的 30 ms / 10 ms 例子里,映像在 7 重新使能、端子在 8 跟随。这套逻辑并不要求一个新的启动边沿。
把这段逻辑放进真实的博途工程
上面所有结论都建立在一个前提上:你手上那段程序的执行顺序、映像更新边界、变量极性,和你以为的一致。原文的实验台是纸面推演;要落到自己工程里,缺的正是"把纸面的东西和工程里实际的东西对齐"这一步——而这恰好是 TIA Portal 工程各自不同的地方:同一个网络在别人电脑上可能是三个 FC 拼起来、可能挂在循环中断里、Run 也可能是个 DB 里的静态位而不是 M 位。
TiaLink 就是补这一段的:它通过 TIA Portal Openness 驱动你本机已经打开的博途工程,读块、读变量、读硬件组态、编译,并在 PLCSIM Advanced 里跑。按下面五步走,纸面模型就变成有证据的判断:
第一步,先只读,把差异找出来。把这三个网络对应的块读出来,对照原文的假设逐项核对:Run 是 M 位还是 DB 静态位?TON0 是不是每扫描都被调用(有没有被包在条件里)?网络执行顺序和图纸一致吗?这一步用只读方式做,不改工程。想先看"这段梯形图到底长什么样",LAD 在线查看可以在浏览器里打开块,不必开博途。
第二步,改之前先看覆盖范围。要改的标签、要动的网络,先跑一次预览,让工具把"会写入哪些对象"列出来。默认规则是不覆盖同名对象、不自动保存——这两条是防止一次 AI 生成把别人上周的修改抹掉。
第三步,编译只算第一层证据。编译能证明语法、类型、块引用是对的;它不检查逻辑是否正确,也不检查某个标签是否真的接到了物理通道上。这一步过了就往下走,别停在"0 错误"。
第四步,在仿真里跑那六个转换测试。把上面那张表里的六种情形依次灌进去,重点看两个状态:输出映像和物理输出(端子)在一个扫描里的差。这正是原文整篇在讲的东西——只有把它们分开看,"程序说停了、端子还亮着"才不是一句传说,而是一个可以被复现的时间点。仿真环境用 PLCSIM Advanced,TiaLink 负责启动、下载、按变量表读写。
第五步,现场之前留回滚点。改完的逻辑要在真实 CPU 上验证,就先备份当前工程、记下版本与日期,再下载;验证时至少两个人看同一份证据(一个盯映像、一个盯现场)。任何 F 程序、任何来源不明的块,都不要走这条自动化路径。
要做到哪一步、什么时候该停手,也写清楚:只读查看和一致性核对可以全自动;生成候选代码、改现有块,需要人看 diff 再确认;下载到真实 CPU、切换运行模式、改安全相关逻辑,必须人做决定。这三级的分界线,比工具本身重要。
来源
- 原文:Reading and Testing PLC Ladder Logic(Atlas of Engineering,Automation and Control Engineering 分区)
- 指令语义与扫描周期:Siemens S7-1200 系统手册 · 位逻辑指令、RUN 模式下扫描周期的处理、TON 生成接通延时
- 原文延伸阅读:丢脉冲案例、安全联锁定期试验
编者补充
原文只给了纸面推演,没回答"我这段程序到底属于哪种更新边界"。补一张速查表,按它在工程里对一遍,比通读手册快:
| 你要确认的 | 在哪里看 | 不一致会怎样 |
|---|---|---|
| 映像更新边界 | CPU 属性里的循环/过程映像设置 | 端子跟随的扫描数会比原文多或少 |
| 网络执行顺序 | 块内网络编号与调用链(OB → FB → FC) | 同一扫描里读到"上一轮"或"这一轮"的值全变 |
| 定时器是否每扫描都调用 | 包住 TON 的那层条件 | 跳过调用 ≠ 输入为假,计时可能不复位 |
Run 的存储位置 |
M 位 / DB 静态位 / 临时变量 | 临时变量跨扫描不保持,自锁直接失效 |
| 是否挂在循环中断 | OB 编号与循环时间 | 上面的"每扫描一次"根本不成立 |
两条边界:其一,原文那个模拟器是教学模型,它自己就写明不含直接读外设、中断任务、网络 I/O 调度和模块时延,别拿它的数字当性能预测。其二,这篇里的所有时序结论都依赖"输出传送→输入采集→程序执行"这个默认顺序;换成别的控制器或改成立即读外设,重新推一遍再下结论。
本文由 汇智网 · Software 2.0 编译整理,转载请注明出处。
这是「AI × 工业 / PLC」专题的一部分。完整地图见:AI × 工业 / PLC 完全指南