今天继续我们的小白教程,老鸟就不要在这浪费时间了😊。
前面一期我们介绍了CODESYS的字符串及其操作。这一期主要介绍CODESYS的定时器及触发的相关功能块特性及用法,注意本文介绍的定时器、触发器和计数器均包含在CODESYS的Standard库中。
一、定时器
CODESYS的计时器功能块有TOF、TON、TP和RTC三种。
1.时间常量
使用定时器首先需要了解CODESYS的时间常量。可以使用TIME常量来操作标准计时器模块。TIME常数的长度为32位,因此分辨率为毫秒。
<time keyword> # <length of time>
<time keyword>:TIME | time | T | t
<length of time>:( <…>d )? ( <…>h )? ( <…>m )? ( <…>s )? (<…>ms)? // ( ...)? 可选
时间单位如下:
D | d:天
H | h:小时
M | m:分钟
s | s:秒
MS | ms:毫秒
注意:
(1)时间常量前面需要加入标识T#,否则不会当做时间处理。
(2)低位的时间常量要符合时间的范围要求,即在前面有更大的时间单位时,分和秒最多为60。
(3)时间常量的给定要按照从大到小的顺序,即天(d)-小时(h)-分(m)-秒(s)-毫秒(ms),颠倒后会报错。
(4)
使用示例:
T1 : TIME := T#14ms;
T2 : TIME := T#100s12ms; //最大时间单位处允许溢出
T3 : TIME := T#12h34m15s;
timLongest := T#49D17H2M47S295MS; // 4294967295
错误示例:
timIncorrect := t#5m88s; //低位溢出(秒大于60)
timIncorrect1 := 15ms; //缺少时间标识T#
timIncorrect2 := t#5ms8d; //时间单位的顺序错误
此外,时间常数LTIME可作为高分辨率计时器的时间基础。LTIME常数的长度为64位,因此分辨率为纳秒。其使用格式与TIME类似,只是关键词为“LTIME”或“ltime”,还有附加的时间单位:US | us-微秒,NS | ns-纳秒。
示例:
ltim1 := LTIME#888d8h8m8s8ms8us8ns;
ltim2 := LTIME#999m1999999999999ns;
2.TON
具有开启延迟的计时器。
IN:输入,上升沿启动延迟计时器,下降沿重置计数器。
PT:输入,延迟计数器的时间,默认为ms。
Q:输出,IN为FALSE,输出为FALSE;IN为TRUE且延迟时间PT已过,输出为TRUE。
ET:输出,从IN出现上升沿起到Q输出所经过时间。
TON的时序如下图所示:
注意:
(1)TON的输出状态与IN的状态相关。如果延时导通之后IN一直保持为TRUE,则输出Q的值一直为TRUE;如果在延迟开启后IN变为FALSE,则输出变为FALSE。
(2)PT的默认单位为ms,可以使用INT_TO_TIME()函数将INT类型转换为时间类型。
使用示例:延时5s输出
delay : TON ;
delay (IN := TRUE, PT:= T#5s);
out := delay.Q
3.TOF
具有关闭延迟的计时器。
IN:输入,下降沿启动延迟计时器,上升沿重置计数器。
PT:输入,延迟计数器的时间,单位默认为ms。
Q:输出,IN为TRUE,输出为TRUE;IN为FALSE且延迟时间PT已过,输出为FALSE。
ET:输出,从IN出现上升沿起到Q输出所经过时间。
TOF的时序如下图所示:
注意:当IN由FALSE变为TRUE时,输出Q由于FALSE变为TRUE,并开始保持Q输出为TRUE;当IN由TRUE变为FALSE时,捕获到下降沿,开始延迟关闭,输出Q保持为TRUE,直到延迟关闭时间到,输出Q才变为FALSE。IN的高电平需要保持一定的时间才能保证TOF重置成功。
使用示例:延时5s关闭
delay : TOF ;
delay (IN := TRUE, PT:= T#5s);
out := delay.Q
4.TP
脉冲计时器。
IN:输入,上升沿启动脉冲计时器并将Q设置为TRUE。
PT:输入,时间上限。
Q:输出,脉冲信号,IN为上升沿则在PT时间内设置为TRUE。当延迟时间PT已过,则为FALSE。
ET:脉冲计时器启动后所经过时间,单位ms。到达PT后,ET值保持恒定。
TP的时序如下图所示:
4.RTC
计算自给定开始时间以来的经过时间。当PDT设置为DT#1970-01-01-00-00:00或未连接时,此功能块可用作工作小时计数器。
EN:输入,TRUE则将CDT设置为PDT,CDT以秒为单位开始计时,并且只要EN为TRUE,就以CDT返回。FALSE则CDT设置为初始值DT#1970-01-01-00:00:00。
PDT:输入,预设日期和时间。
Q: 输出,只要CDT正在计数则为TRUE,否则为FALSE。
CDT:输出,从PDT以来经过的时间。EN为FALSE时为从DT#1970-01-01-00:00:00以来的时间,即当前日期和时间。
使用示例:返回自2023-01-10-14:00:00以来经过的时间。
RTC(EN:=bFlag, PDT:=DT#2023-01-10-14:00:00, Q=>bOut, CDT=>VarTimeCur);
二、触发器
CODESYS的触发器功能块有下降沿触发F_TRIG和上升沿触发R_TRIG两种。
1.F_TRIG-下降沿触发
检测布尔信号的下降沿。
CLK:输入,待检测的布尔信号。
Q:输出,TRUE为检测到下降沿。
注意:检测到CLK有下降沿(TRUE->FALSE)时变为TRUE,持续一个周期,下一周期变为FALSE。
使用示例:
trig : F_TRIG ;
trig(CLK:= bIn);
bOut:= trig.Q;
2.R_TRIG-上升沿触发
检测布尔信号的上升沿。
CLK:输入,待检测的布尔信号。
Q:输出,TRUE为检测到上升沿。
注意:检测到CLK有上升沿(FALSE->TRUE)时变为TRUE,持续一个周期,下一周期变为FALSE。
使用示例:
trig : R_TRIG ;
trig(CLK:= bIn);
bOut:= trig.Q;
三、计数器
CODESYS的计数器功能块有递减计数器CTD、递增计数器CTU和双向计数器CTUD三种。
1.CTD-递减计数器
CD:输入,检测到上升沿则CV值减1直至为0。
LOAD:输入,为TRUE时则重置计数器,将CV设为初始值PV。
PV:输入,计数器的初始值。
Q:输出,CV为0时输出TRUE。
CV:输出,当前计数值。
使用示例:从100递减计数
decCnt : CTD ;
decCnt (CD:= bIn, LOAD:=bReset , PV:= 100);
bOut := decCnt.Q ;
curCnt := decCnt.CV;
2.CTU-递增计数器
CU:输入,检测到上升沿则CV值加1直至大于等于PV。
RESET:输入,为TRUE时则重置计数器,将CV设为0。
PV:输入,计数器的上限。
Q:输出,CV>=PV时输出TRUE。
CV:输出,当前计数值。最大值为65535(16#FFFF)。
使用示例:从0开始计数,最大1000。
cnt: CTD ;
cnt(CD:= bIn, LOAD:=bReset , PV:= 1000);
bOut := cnt.Q ;
curCnt := cnt.CV;
3.CTUD-双向计数器
CU:输入,检测到CU上升沿则CV值加1。
CD:输入,检测到CD上升沿则CV值减1。
RESET:输入,为TRUE时则重置计数器,将CV设为0。
LOAD:输入,为TRUE时则重置计数器,将CV设为初始值PV。
PV:输入,计数器的初始值或者计数上限。
QU:输出,CV>=PV时输出TRUE。
QD:输出,CV为0时输出TRUE。
CV:输出,当前计数值。
注意:CODESYS中用于PV的数据类型WORD与IEC标准不匹配,IEC标准为PV定义了数据类型INT。
cnt: CTD ;
cnt(CU := bCU, CD:= b,CD RESET := bReset, LOAD:=bLoad , PV:= 1000);
bQU := cnt.QU ;
bQD := cnt.QD ;
curCnt := cnt.CV;
四、结论
定时器和触发器应该说是PLC里面使用频率很高的功能。定时器功能比较好理解,对于初学者需要弄清楚的其实是怎么输入定时时间,以及如何判断定时时间到了。触发器功能主要用来检测信号的变化,需要搞清楚信号持续时间,以及触发后的状态变化。计数器功能也比较好理解,但是实际上用的不是很多(ST里面很多时候都是用变量代替了)。这些功能块都可以在仿真模式下运行,写个小程序仿真跑一下基本就清楚怎么用了^-^。
------------------
原创不易,感兴趣的多支持!