定时器如何在 PLC 结构化文本 (ST) 中工作?我们如何声明它们?
我一直在研究 PLC 的标准(IEC 61131-3),他们没有谈到 ST 中的定时器。我知道绝大多数 PLC 程序员都是用梯形逻辑来做的,但在这种特殊情况下,我真的需要在 ST 中声明定时器。
我正在使用罗克韦尔 PLC。
您可以在 IDE 的帮助系统中找到有关计时器以及如何使用(声明)它的说明。例如,在CODESYS帮助中,您可以阅读有关标准库的计时器的信息。
通常,您可以将定时器延迟 (TON) 声明为:
VAR
MY_TON: TON;
END_VAR
(* standard.library should be added to the project *)
然后你可以使用它:
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,可能存在细微差别。
我在 Gx-Works(Mitsubishi / FXCPU) 中这样解决了它:
TON_1(IN:= Enable_Timer,PT:= PresetTime ,Q:= Output,ET:= TimeLeft);
记得声明 TON_1 :)
计时器的工作原理是只有在至少持续高电平的情况下TON.Q
才会变为高电平。TON.IN
TON.PT
这确保TON.Q
只有TON.IN
在稳定的高电平状态下才会变高。
例如,这对于确保仅在按下按钮至少持续时间为TON.PT
.
通常,您设置预设时间并启用计时器。当它过去时,将完成某种完成位设置为真。当您重置启用时,时间也会重置。
我使用支持 ST 语言的 OMRON PLC 完成了这项工作。
PLC 中有一个定时器中断,我们用它在 ST 中构建了我们自己的定时器,然后我们可以跳过 PLC 的限制。PLC上电后,每次中断都会执行中断任务里面的代码,可以在中断处理程序里面写“A=A+1”。
当你开始使用定时器时,只记录A的当前数据。假设A1;间隔是:
Interval= Current_Data_Of_A-A1
然后比较Interval
你想要的时间。如果Interval
大于您想要的时间,则执行下一个代码。
我们还使用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;