news 2026/9/19 5:06:43

汇川InoProShop定时器指令TON/TOF/TP工程实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
汇川InoProShop定时器指令TON/TOF/TP工程实战解析

做PLC项目这些年,一个最深的感受是:定时器这种指令,看着不起眼,却是整套时序逻辑的骨架。尤其是用汇川InoProShop做H5U、AM系列这类中型PLC时,TON、TOF、TP三条定时器指令的时序行为,如果不彻底吃透,程序写出来是一回事,现场跑起来又是另一回事。我见过不少新手把这三条指令当成“差不多的东西”混着用,结果设备启动顺序错乱、停机延时丢失、互锁信号抢时间,最后全得拉回程序重新捋逻辑。

这篇文章不打算讲那些手册里已经写烂了的定义,而是从工程实战的角度出发,把TON/TOF/TP的时序逻辑、InoProShop里的实操要诀、以及现场联调时的排查路径完整过一遍。内容偏实战,适合刚接触InoProShop、被定时器时序绕晕的新人,也适合想把手头程序再优化一遍的老工程师。看完之后,你至少能明白三件事:这三条指令分别在什么场景下用、怎么写才不容易出问题、出了问题怎么快速定位。

1. 定时器在工程里的位置:为什么单拎出来讲

1.1 定时器解决的从来不是“时间”问题,而是“顺序”问题

很多初学者会把定时器单纯理解成“等一会儿再动作”,这个理解没有错,但太浅了。在真实设备里,定时器承担的更多是“时序约束”——谁先动、谁后动、谁要保持多久、谁要在什么条件满足后才能停下来。比如一条产线上的三台输送带,启动时必须按逆流方向依次延时启动,防止物料堆积;停止时必须按顺流方向依次延时停止,防止物料卡在交接位。这个“依次延时”背后就是靠TON完成的。

再比如设备停机后,润滑泵、冷却风机往往不能立刻断电,需要继续运行一段时间,把残热散掉、把润滑到位,这时候TOF就派上用场了。还有那些需要固定脉冲宽度输出的场景,比如气缸点动、报警闪烁、定量喷吹,用TP一把梭反而最省事。

所以说,定时器的本质是“把时间这个维度注入逻辑控制”,让设备从“条件触发”变成“条件+时间触发”。时序逻辑一旦设计得潦草,轻则影响节拍,重则造成设备碰撞、物料堵料、机械冲击,这在现场都是实实在在的安全隐患。

1.2 InoProShop的定时器家族:三条指令干完一个时序闭环

汇川InoProShop对应的主要是中型PLC平台,比如H5U、AM系列,内核基于CODESYS V3,遵循IEC 61131-3标准。标准库里提供的定时器功能块就是我们在编程时最常用的三个:TON(接通延时定时器)、TOF(断开延时定时器)、TP(脉冲定时器)。

这三条指令不是孤立存在的,它们组合起来能覆盖工程里绝大部分的时序需求:

  • TON负责“事件发生后延时输出”;
  • TOF负责“事件消失后延时复位”;
  • TP负责“触发一次,固定输出一段时长”。

再加上它们都能通过ET引脚输出当前计时值,你还可以把计时值拿去做显示、做报警阈值判断、做数据采集,能力边界比很多人想象的宽得多。我在实际项目里,把定时器的ET接出来做设备运行时长统计、保养提醒,一次都没有额外写过计时逻辑,全是靠标准定时器做到的。

2. TON/TOF/TP 三条指令的时序逻辑拆解

2.1 TON接通延时:从输入为真开始数秒

TON的输入引脚是IN和PT,输出引脚是Q和ET。IN是触发信号,PT是设定时间,Q是延时输出,ET是当前累计的计时值。逻辑说起来很简单:当IN从FALSE变成TRUE,定时器开始计时,ET不断增加,当ET累计到PT时,Q从FALSE翻成TRUE。只要IN一直保持TRUE,Q就一直保持TRUE。一旦IN变回FALSE,ET立刻清零,Q跟着变回FALSE。

这里有一个细节经常被忽略:TON不是边沿触发的,它是电平触发的。意思是只要IN保持TRUE,即便Q已经为TRUE,定时器也不会重复计时,ET会被钳制在PT附近不再增长。这种特性决定了TON适合用来做“保持型延时”——只要条件持续存在,输出就一直保持。

举个最常用的例子:电机启动。按下启动按钮,按钮信号作为IN,如果按钮一直按住,3秒后Q才为TRUE,接触器才吸合。实际工程里我们不会让操作员一直按着按钮,所以会用启动信号的自锁或者中间变量做IN,把“一键启动”变成“条件满足后延时启动”。

还有一个工程细节值得注意:TON的计时精度完全依赖于PLC的扫描周期。它不是硬件中断级的定时器,而是在每个扫描周期被调用一次,然后根据当前时刻与上次调用时刻的差值累加ET。所以如果程序扫描周期是10ms,那么TON的理论精度也就到10ms量级,这对绝大多数工业设备已经足够。真要做到微秒级、亚毫秒级,就不能依赖普通任务里的定时器功能块,得考虑硬件中断或专用定时模块。

2.2 TOF断开延时:输入消失后才开始数秒

TOF的逻辑刚好和TON相反,但又不完全相反。输入IN从FALSE变成TRUE的那一刻,Q立刻变为TRUE,不需要等计时。只有当IN从TRUE变回FALSE,TOF才开始计时,ET从0逐渐增加,当ET累计到PT,Q才从TRUE变回FALSE。换句话说,TOF是把“信号消失”这件事延时执行。

这个特性在工程上非常有用。比如冷却风机:只要设备在运行,风机就要转。设备停止后,风机不能马上停,需要继续吹10秒把柜内余温散掉。用TOF写,IN接设备运行信号,PT设为T#10s,Q输出接风机接触器。设备一停,IN消失,但Q还要保持TRUE直到10秒计时结束,风机自然就把残热吹散了。

TOF还有个容易被忽略的用法:信号防抖。现场按钮、接近开关、光电传感器在动作瞬间往往会产生抖动,信号在TRUE和FALSE之间来回跳几次才稳定。如果在IN端加一个TOF,把PT设成50ms或者100ms,那么即便输入瞬间掉电,Q也不会立刻跟着翻,能有效滤除短暂毛刺。我在做气缸到位检测时,就经常用这个方法过滤气缸缓冲瞬间的抖动误信号。

这里要特别提醒:TOF计时过程中如果IN再次变成TRUE,会发生什么?计时会停止,ET清零,Q回到TRUE。这是标准行为,很多初学者在这里踩坑——他们以为TOF计时一旦开始就必须计时到PT结束。实际上不是的,TOF可以被“重新触发打断”,所以设计互锁逻辑时,一定要注意输入信号的稳定性,否则延时输出随时可能被拉回。

2.3 TP脉冲定时器:触发一次,输出一段固定时长

TP是我个人最喜欢用的一条指令,但在初学者里知名度反而最低。它的逻辑是:当IN从FALSE变成TRUE的一瞬间(上升沿),Q立刻变为TRUE,并且保持PT设定的时长,计时结束后Q自动变回FALSE。在Q保持TRUE的这段时间里,无论IN怎么变化,哪怕是再次来一个上升沿,Q都不会被影响,必须等当前这段计时走完,下一次IN上升沿才会重新触发新一轮输出。

这个“触发一次,固定输出”的特性,非常适合做单次动作控制。比如喷胶系统的喷枪,每次检测到工件到位信号,只需要喷0.5秒,不管工件是否提前离开、信号是否抖动,喷胶动作都要固定持续0.5秒。用TP,IN接工件到位信号,PT设T#500ms,Q直接控制喷阀。

用TON去做这个功能也不是不行,但会绕很多:你得先做上升沿捕捉、做自锁、做复位,逻辑量翻了一倍还不止。用TOF更是做不到,因为TOF不会自动产生一个固定宽度的“先有后无”的波形。所以TP存在的意义就是:把“可重复触发的单稳态定时”这个高频需求,用一条指令给你封装好,省掉自己手写上升沿和自锁的功夫。

2.4 三条指令的时序行为对照

整理成一张表,大家平时查起来方便:

指令触发条件Q何时变TRUEQ何时变FALSE计时中断条件典型用途
TONIN为TRUE持续计时计时达到PT后IN变FALSE时IN一旦变FALSE立即清零启动延时、顺序启动
TOFIN由TRUE变FALSE开始计时IN变TRUE时立即计时达到PT后IN变TRUE时停止并复位停止延时、信号防抖
TPIN上升沿触发触发瞬间计时达到PT后计时期间新触发无效固定宽度脉冲、单次动作

这三条指令的时序逻辑,光看表格是不够的,一定要在InoProShop里实际拉出来跑一下,用仿真模式看着ET和Q的变化去对应理解。我当年就是在软件里把三条指令并联在一起,用同一个开关去触发,把Q和ET全部拉到监控列表里,对比着波形图才彻底想明白。

3. InoProShop 实操落地:从调用库到现场联动

3.1 工程里怎么把定时器“请”出来

InoProShop的编程界面和CODESYS系列的IDE很像。在程序组织单元(POU)里写结构化文本(ST)时,可以直接写入TON、TOF、TP这些关键字,然后按代码提示自动生成功能块实例。也可以从左侧的库管理器里找到标准库,把Timer相关的功能块拖拽到程序中。

以ST语言为例,一条TON的调用是这样写的:

TON_1(IN := StartBtn, PT := T#3s); MotorRun := TON_1.Q;

第一行把StartBtn赋值给TON_1的IN输入,PT设为3秒,然后这个功能块就开始工作。第二行把功能块的Q输出赋给MotorRun变量,当计时到3秒时,MotorRun自动变为TRUE。

这里有个新手容易犯的错误:直接写“TON(IN := StartBtn, PT := T#3s)”而不创建实例。TON是一个功能块,不是普通函数,它必须有一个实例名来保存内部状态。每条定时器在自己的扫描周期之间都要“记住”当前ET计到哪了、Q当前是什么状态,这些信息就存在实例里。如果没有实例名,程序根本编译不过去。InoProShop一般在输入TON后会自动弹出一个提示,让你填实例名,或者自动生成一个,千万别把它删了。

除了ST,InoProShop也支持梯形图(LD)和功能块图(FBD)。梯形图下定时器会被拉成一个方框,左边是IN和PT输入,右边是Q和ET输出,图形化程度更高,对从三菱、西门子转过来的工程师更友好。不过我个人建议逻辑复杂以后尽量用ST,方便做版本对比和团队评审。

3.2 时间单位与扫描周期的“精度账”

定时器的PT和ET都是TIME类型,TIME在IEC标准里是一个32位整形数据,单位是毫秒。工程里写T#3s、T#500ms、T#1m30s都可以,InoProShop会自动换算成毫秒。

ET的读数也是TIME类型,可以直接拿去和常量比较,比如:

IF TON_1.ET >= T#2s THEN bTimerReach := TRUE; END_IF;

这个能力很多人没用起来,其实很实用。比如你要在启动延时未到2秒时点亮一个“正在准备”的指示灯,到2秒后改成“即将启动”闪烁,到3秒后直接进入运行状态,全靠对ET的分段比较就能实现,不需要额外写好几个定时器。

但是TIME类型也有一个隐含坑:它是32位,最大能到大概49天的毫秒数。对绝大多数设备来说根本用不满,但如果你的项目涉及长时间累积计时,比如设备累计运行时间,就不要直接拿TON去跑,很容易溢出。正确的做法是定时器到点后让计数器自加,用DINT或者更大范围的变量去累加。

再来说精度账。PLC是周期性扫描执行程序的,TON/TOF/TP的ET累加,依赖的是两次调用之间的时间差。InoProShop里每个任务都有固定周期,比如主任务设成10ms,那么程序里的定时器实际就是在10ms粒度上跳动。你PT设成T#1s,理论上是1秒后Q翻真,但实际触发可能发生在1000ms、1005ms、或者995ms,偏差在一个扫描周期以内。这个精度对设备保护、联锁、顺序控制都绰绰有余。但如果你想做计米器、高速计数、精确测速,那就不该指望普通定时器了。

如果你有一个特别重要的时序节点,比如伺服运动过程中需要在中断里快速响应,建议把这一小段逻辑放到独立的高速任务里,把任务周期调成1ms或更小,再把定时器放在这个任务里调用。每个InoProShop工程可以有多个任务,优先级和周期分开配置,这是很多老工程师优化程序帧率、提高时序精度的重要手段。

3.3 一个完整案例:电机启动+风机延时关停

用一个实际案例把TON和TOF串起来。假设现场有一台主电机,启动时需要先点动润滑泵3秒,润滑建立后再启动主电机;主电机停止后,冷却风机需要继续运行10秒。用InoProShop写起来是这样的:

// 润滑泵延时启动:按下启动按钮3秒后,允许主电机启动 TON_Lube(IN := StartBtn, PT := T#3s); bLubeReady := TON_Lube.Q; // 主电机启动条件:润滑延时完成 且 没有急停 IF bLubeReady AND NOT bEStop THEN bMotorRun := TRUE; ELSE bMotorRun := FALSE; END_IF; MotorContactor := bMotorRun; // 冷却风机延时停止:主电机停止后继续运行10秒 TOF_Fan(IN := bMotorRun, PT := T#10s); FanContactor := TOF_Fan.Q;

这段代码里,TON_Lube负责润滑建立延时,TOF_Fan负责停机后风机的延时关停。按下启动按钮,3秒后bLubeReady为真,主电机接触器吸合;主电机一旦运行,bMotorRun为真,TOF_Fan的IN为真,Q立即为真,风机直接启动。主电机停机后,bMotorRun变假,TOF_Fan才开始计时,10秒后风机接触器断开。

这里面有个值得琢磨的点:风机在启动阶段为什么也跟着直接转了?因为TOF的Q在IN为真时是立即输出的,不需要延时。这就保证了设备一运行风机就运行,而停机后又能延时关停,一组逻辑同时覆盖了两个需求,比单独写两个定时器干净得多。

3.4 用定时器组合实现交替闪烁与双向延时

定时器组合起来还能实现一些看似复杂的功能,比如两台设备交替运行、指示灯来回闪烁。常见做法是让两个TON互相触发循环:

// TON_A计时到3秒后触发TON_B,TON_B计时到2秒后再反过来触发TON_A TON_A(IN := NOT TON_B.Q, PT := T#3s); TON_B(IN := TON_A.Q, PT := T#2s);

第一段:当TON_B.Q为假时,TON_A开始计时,3秒后TON_A.Q为真;第二段:TON_A.Q为真后,TON_B开始计时,2秒后TON_B.Q为真;但TON_B.Q一旦为真,TON_A的IN变成假,TON_A立刻清零复位,Q变回假,TON_B的IN跟着变假,又开始下一轮循环。两个定时器互相掐着对方的脖子,形成周期性交替输出,A亮3秒、B亮2秒,非常适合做工艺段之间的交替进料或者双工位节拍控制。

用TP做类似交替效果就更快了。把TP的PT设成总周期,Q作为触发源分频,再配上升沿计数,半个周期翻转一次输出,波形就是一个占空比50%的方波。我做过一个输送带振打器,就靠TP+一个交替变量,实现了连续振打和间歇振打的切换,整个逻辑不到十行,比专门写一个脉冲发生器省事得多。

4. 定时器现场的常见问题与排查思路

4.1 我亲手踩过和帮别人排过的坑

把我在现场遇到的高频问题整理成一张速查表,大家调试设备时可以直接照着排查:

故障现象可能原因排查方向
Q一直不翻转IN信号根本没有为真先看IN的实际值,再查PT设置
ET一直显示0定时器没有被周期调用检查程序是否在循环任务里执行
输出乱跳、时序不稳扫描周期不一致,定时器所在任务周期过长调整任务周期,或把核心逻辑移到高速任务
定时器复位不彻底输入信号抖动,导致TOF反复重置在IN端加滤波,或用TP做去抖
PT改了没反应程序未在线下载,或表达式写错检查PT引脚是否被其他变量覆盖赋值
多个地方同时用同一个实例触发了重入调用,内部状态混乱一个实例只在一个POU里统一调用
长时间计时溢出TIME类型32位到达上限改用计数器叠加的方式累计时长

实际调试里,我最常被拉去解决的问题就是“定时器Q明明条件到了就是不翻真”。大部分情况下,打开监控表一看,IN信号压根没有变成TRUE。很多人被DF/DFI上升沿、自锁逻辑绕晕了,以为自己给了信号,实际信号早就被前面的逻辑吃掉了。所以排查定时器问题,第一件事永远是看输入,而不是盯着Q纠结。

4.2 联调时最容易忽视的时序冲突

项目联调阶段,定时器的问题往往不只是定时器本身的问题,而是多个环节之间的时序冲突。最常见的有三类。

第一类是启动阶段互锁冲突。设备启动时,多个定时器同时计时,有些信号在下一个扫描周期就要互相使用,结果出现“抢跑”现象。比如A定时器到点后置位了某个输出,B定时器到点后又把这个输出复位了,谁后执行谁就赢。解决办法是把定时器的输出集中到程序末尾统一赋值,避免在多个POU里直接写同一个输出变量。

第二类是触摸屏上修改时间参数后不生效。很多项目把PT参数做成变量,让操作员在HMI上改延时时间。这时候一定要检查变量是否被程序里其他逻辑反复覆盖,尤其是有没有在扫描周期内把它复位了。我遇到过有人把PT变量既做了HMI输入,又在程序里用了MOV指令给它赋值,结果HMI改半天,程序里一扫描又被强制改回去,现场还以为定时器坏了。

第三类是伺服、变频器联动时的假信号。伺服使能、变频器运行反馈这类信号,在电气上往往有一定延迟,如果定时器直接拿它们的常开触点做IN,很容易造成时序错位。正确做法是让定时器在逻辑层驱动,电气层的反馈信号只做监控确认,不要在定时器链路里直接串联。

4.3 把定时器用“活”:一个可以立刻上手的技巧

最后分享一个小技巧,这个技巧让我在好几个项目里少写了几十行逻辑。InoProShop的TON定时器ET引脚,除了用来监控计时,还可以直接当“时间进度条”用。比如你要做设备预热倒计时,不想用一堆M变量去判断阶段,直接拿TON的ET和PT做除法:

rProgressPercent := TIME_TO_REAL(TON_Heater.ET) / TIME_TO_REAL(TON_Heater.PT) * 100.0;

然后把这个rProgressPercent送给HMI的进度条控件,操作员就能实时看到预热进度到多少了。在定时器到点前,你想提前亮一个“即将完成”的提示灯,只需要判断:

bAlmostDone := rProgressPercent >= 80.0;

这样一来,一个T#30s的预热定时器不仅完成了延时输出,还承包了进度显示、提示灯、乃至后续动作的预判,逻辑全部收敛在一个功能块周围,维护起来特别清晰。

定时器这种指令,看着是入门级,实际用好了能帮你在程序结构和故障定位上省下大量心思。我在带团队的时候一直强调:先把TON、TOF、TP的时序在仿真里玩透,再上现场。因为时序逻辑不像PID有参数可调,它是一票肯定制的东西——对就是对,错就是错。基础打扎实了,后面陈年烂账一样的复杂时序,一层层拆开看,其实都逃不过这三个指令的排列组合。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 5:21:12

PyTorch MNIST下载404与DataLoader读取实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 5:24:14

基于全卷积网络的船舶检测与船牌识别方案

简介:这份PDF文档为《基于全卷积神经网络的船舶检测和船牌识别系统》原文,面向深度学习、计算机视觉研究者及港口智能监控相关从业者。文档针对船舶轮廓复杂、船牌位置不固定、船牌文本多样等挑战,系统阐述SDR-FCN方案:利用SDNet完…

作者头像 李华
网站建设 2026/9/19 5:20:35

同一把 TaoToken Key,从 Google Home MCP 到 Antigravity

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 5:20:21

第五代i3老本装Windows11 26H2:CPU、内存与续航实测调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华