Timer PLC中的定时器-结构化文本

Timer PLC中的定时器-结构化文本,timer,plc,st,Timer,Plc,St,定时器如何在PLC结构化文本(ST)中工作?我们如何申报 我一直在研究PLC的一个标准(IEC 61131-3),他们没有提到ST中的计时器。我知道大多数PLC程序员都是用梯形图逻辑来实现的,但在这种特殊情况下,我真的需要在ST中声明计时器 我使用的是罗克韦尔PLC。通常,您可以设置预设时间并启用计时器。当它经过时,会有一个done排序的done位设置为真。当您重置启用时,时间也将重置。我在Gx Works(三菱/FXCPU)中这样解决了它: 记住声明TON_1:)您可以在IDE的帮助系统中找到

定时器如何在PLC结构化文本(ST)中工作?我们如何申报

我一直在研究PLC的一个标准(IEC 61131-3),他们没有提到ST中的计时器。我知道大多数PLC程序员都是用梯形图逻辑来实现的,但在这种特殊情况下,我真的需要在ST中声明计时器


我使用的是罗克韦尔PLC。

通常,您可以设置预设时间并启用计时器。当它经过时,会有一个done排序的done位设置为真。当您重置启用时,时间也将重置。

我在Gx Works(三菱/FXCPU)中这样解决了它:


记住声明TON_1:)

您可以在IDE的帮助系统中找到有关计时器以及如何使用(声明)计时器的说明。例如,在“帮助”中,您可以阅读有关标准库计时器的信息

通常,您可以将计时器延迟(吨)声明为:

然后您可以使用它:

MY_TON(IN:= IN_VALUE,PT:= TIME_SET);
(*IN_VALUE - is BOOL variable that activates your timer
  TIME_SET - is TIME variable*)

SOME_OUTPUT := MY_TON.Q;
(*Q - is the timer's output, and it can be used as BOOL variable. *)
您还可以使用常量设置计时器:

MY_TON(IN:= True, PT:= t#5s);
作为BOOL变量,计时器的输出可用于IF和WHILE语句:

IF MY_TON.Q THEN
    (*Some statements...*)
END_IF

WHILE MY_TON.Q DO
    (*Some statements...*)
END_WHILE

所有示例都在CODESYS v3.5 SP5和v2.3中运行。对于其他IDE,可能存在细微差别。

我使用支持ST语言的欧姆龙PLC完成了这项工作

PLC中有一个定时器中断,我们用它在ST中构建我们自己的定时器,然后我们可以跳过PLC的限制。当PLC通电时,每次中断都会执行中断任务中的代码,您可以在中断处理程序中写入“A=A+1”

当您开始使用计时器时,只需记录A的当前数据;时间间隔为:

Interval= Current_Data_Of_A-A1

然后将
Interval
与所需时间进行比较。如果
Interval
大于您想要的时间,则执行下一个代码。

计时器工作,以便
TON.Q
仅当
TON.IN
TON.PT
的持续时间内持续高时才会变高

这确保只有当
TON.IN
处于稳定的高状态时,
TON.Q
才会变高


例如,这可能有助于确保仅当按下按钮的持续时间至少为
吨时才启用输出。PT

我们还使用PLC提供的毫秒计数器构建了自己的计时器结构,因此我们可以在需要时制作计时器阵列(施耐德电气),并超过PLC限制

TTIMER
 Count: UINT 
 timclock :INT 
 OUT :BOOL
 IN: BOOL 
END_STRUCT;
TIM_SOD=ARRAY[0..1] OF TTIMER;

(*This part runs every cycle of PLC*)
FOR I:=0 TO 1 DO
  IF TIM_SOD[I].IN (*timer on*)
  THEN
   IF (TIM_SOD[I].Count)>0 (*number of seconds left*)
   THEN
    IF ABS_INT(IN:=timclock-TIM_SOD[I].CLK)>=100 (*timclock -mSec counter*)
    THEN aTIM_SOD[I].Count:=TIM_SOD[I].Count-1;
     TIM_SOD[I].CLK:=TIM_SOD[I].CLK+100;
    END_IF;
   ELSE
    TIM_SOD[I].IN:=0; (*timer off*)
    TIM_SOD[I].Out:=1; (*Timer have run out*)
   END_IF;
  END_IF;
 END_FOR;
(*-------------------------------------------------*)

(*This part runs once when we need start timer*)
  TIM_SOD[0].COUNT:=H690; (*delay in seconds*)
  TIM_SOD[0].CLK:=TIMCLOCK; (*current value of mSec counter*)
  TIM_SOD[0].IN:=True; 
(*-------------------------------------------------*)

(*This part runs once when we need stop timer*)
  TIM_SOD[0].IN:=False;


(*Checking timer*)
IF TIM_SOD[0].OUT
THEN
  (*doing smth......*)
END_IF;

不是真的,至少据我所知。IEC 61131-3“标准”是您将要了解的内容,它更像是一个松散的指南。每个PLC都是不同的-梯形图对于每个制造商是以稍微不同的方式完成的,ST对于每个制造商是以稍微不同的方式完成的,助记符对于每个制造商是不同的,等等。一些PLC甚至不支持ST中的计时器,即使它们的ST符合IEC标准。罗克韦尔使用了
TONR
TOFR
,以及
CTUD
,等等……欧姆龙使用了
TIMX
CNTRX
,等等。该死,我不知道这一点。你能告诉我罗克韦尔公司的定时器是怎么工作的吗?我想知道,至少在一个平台上,“它们如何工作”是一个非常模糊的问题。建议您学习罗克韦尔手册。如果你打算对PLC进行编程,你会发现随附的手册具有不可估量的价值。学习阅读和理解PLC手册可能是您需要的最重要的技能之一。如果你想要罗克韦尔定时器的摘要,也许考虑一下:当我说“它们是如何工作的”是在一个ST程序中,你如何初始化它和类似的东西。对不起,我没有说清楚。我有一个问题与您的解决方案@sonysun密切相关。回答这个问题将有助于改进已经提供的信息。在MY_TON()之后,执行会一直等到MY_TON.Q变为真或通过,并且必须返回到该点进行多次检查,然后才为真。或者我需要用一段时间使执行在循环中旋转,直到Q为真,并在它为真后继续执行。我相信你能帮助我更好地理解这一点。(我正在使用罗克韦尔Micro850和CCW环境。)@avi这取决于您的环境和控制器。我不熟悉罗克韦尔Micro850的CCW环境。在我的情况下(Codesys v3.5 SP5和v2.3以及我当地制造商的控制器),程序在无限循环中运行,它多次检查输入变量的状态。所以我不需要使用WHILE或任何循环命令。在您的情况下,您应该检查您的程序如何执行。然后决定使用循环。
Interval= Current_Data_Of_A-A1
TTIMER
 Count: UINT 
 timclock :INT 
 OUT :BOOL
 IN: BOOL 
END_STRUCT;
TIM_SOD=ARRAY[0..1] OF TTIMER;

(*This part runs every cycle of PLC*)
FOR I:=0 TO 1 DO
  IF TIM_SOD[I].IN (*timer on*)
  THEN
   IF (TIM_SOD[I].Count)>0 (*number of seconds left*)
   THEN
    IF ABS_INT(IN:=timclock-TIM_SOD[I].CLK)>=100 (*timclock -mSec counter*)
    THEN aTIM_SOD[I].Count:=TIM_SOD[I].Count-1;
     TIM_SOD[I].CLK:=TIM_SOD[I].CLK+100;
    END_IF;
   ELSE
    TIM_SOD[I].IN:=0; (*timer off*)
    TIM_SOD[I].Out:=1; (*Timer have run out*)
   END_IF;
  END_IF;
 END_FOR;
(*-------------------------------------------------*)

(*This part runs once when we need start timer*)
  TIM_SOD[0].COUNT:=H690; (*delay in seconds*)
  TIM_SOD[0].CLK:=TIMCLOCK; (*current value of mSec counter*)
  TIM_SOD[0].IN:=True; 
(*-------------------------------------------------*)

(*This part runs once when we need stop timer*)
  TIM_SOD[0].IN:=False;


(*Checking timer*)
IF TIM_SOD[0].OUT
THEN
  (*doing smth......*)
END_IF;