马上注册,享受更多特权
您需要 登录 才可以下载或查看,没有帐号?立即注册 
x
本帖最后由 jiaxf 于 2022-6-11 19:14 编辑
1 ST语言中 IF,CASE中使用 TON
以星三角启动正反转为例
1.1 变量定义部分
PROGRAM PLC_PRG
VAR
iB_Hot :BOOL; // 热继电器常闭
iB_Forward :BOOL; //正转按钮
iB_Reverse :BOOL; //反转按钮
iB_stop :BOOL; //停止按钮
oB_Forward :BOOL; //KM 正转接触器吸合;
oB_Reverse :BOOL; //KM 反转接触器吸合;
oB_Y_run :BOOL; //电动机 Y启动;
oB_I_run :BOOL; //电动机 ▲启动;
t1 :TIME := T#3S; //默认转化时间 3s;
t10 :TIME; //
TON_0: TON;
TON_1: TON;
step :INT := 0; //0, 停止或待机; 11,正转Y; 21,正转Y; 31,正转/反转▲;
tmpBit :ARRAY[0..1]OF BOOL; //临时变量
END_VAR
1.2 程序部分
//正转
IF NOT iB_Hot AND NOT iB_Reverse AND NOT oB_Forward AND NOT oB_Reverse AND NOT oB_I_run AND NOT oB_Y_run AND iB_Forward THEN
step := 11;
END_IF
//反转
IF NOT iB_Hot AND NOT iB_Forward AND NOT oB_Forward AND NOT oB_Reverse AND NOT oB_I_run AND NOT oB_Y_run AND iB_Reverse THEN
step := 21;
END_IF
//停止
IF iB_stop OR iB_Hot THEN
step := 0;
END_IF
CASE step OF
0: //停止
oB_Reverse := FALSE; oB_Forward := FALSE; oB_I_run := FALSE; oB_Y_run := FALSE;
tmpBit[0] := FALSE; tmpBit[1] := FALSE;
11 : //正转Y
oB_Reverse := FALSE; oB_Forward := TRUE; oB_Y_run := TRUE;
TON_0(IN:=oB_Y_run, PT:= t1 , Q=> tmpBit[0] , ET=>t10); //正转Y->▲过渡延时
IF tmpBit[0] THEN
step := 31;
oB_Y_run := FALSE;
END_IF
21 : //反转Y
oB_Forward := FALSE; oB_Reverse := TRUE; oB_Y_run := TRUE;
TON_1(IN:=oB_Y_run, PT:= t1 , Q=> tmpBit[1] , ET=>t10); //反转Y->▲过渡延时
IF tmpBit[1] THEN
step := 31;
oB_Y_run := FALSE;
END_IF
31 : //正转或反转 ▲
IF NOT oB_Y_run THEN
oB_I_run := TRUE;
ELSE
oB_I_run := FALSE;
END_IF
END_CASE
1.3 运行程序
运行程序发现,第一次启停没有问题,重复运行是直接跳过 Y 到 ▲ ,监控发现,iB_stop 后, TON_0 TON_1 中 t10 没有变为 0 ,而是 T#3s ;
1.4 代码优化
<mark>把 TON_0 TON_1 从IF ,CASE 移出<mark>后正常;
//正转
IF NOT iB_Hot AND NOT iB_Reverse AND NOT oB_Forward AND NOT oB_Reverse AND NOT oB_I_run AND NOT oB_Y_run AND iB_Forward THEN
step := 11;
END_IF
//反转
IF NOT iB_Hot AND NOT iB_Forward AND NOT oB_Forward AND NOT oB_Reverse AND NOT oB_I_run AND NOT oB_Y_run AND iB_Reverse THEN
step := 21;
END_IF
//停止
IF iB_stop OR iB_Hot THEN
step := 0;
END_IF
TON_0(IN:=oB_Y_run, PT:= t1 , Q=> tmpBit[0] , ET=>t10); //正转Y->▲过渡延时
TON_1(IN:=oB_Y_run, PT:= t1 , Q=> tmpBit[1] , ET=>t10); //反转Y->▲过渡延时
CASE step OF
0: //停止
oB_Reverse := FALSE; oB_Forward := FALSE; oB_I_run := FALSE; oB_Y_run := FALSE;
tmpBit[0] := FALSE; tmpBit[1] := FALSE;
11 : //正转Y
oB_Reverse := FALSE; oB_Forward := TRUE; oB_Y_run := TRUE;
IF tmpBit[0] THEN
step := 31;
oB_Y_run := FALSE;
END_IF
21 : //反转Y
oB_Forward := FALSE; oB_Reverse := TRUE; oB_Y_run := TRUE;
IF tmpBit[1] THEN
step := 31;
oB_Y_run := FALSE;
END_IF
31 : //正转或反转 ▲
IF NOT oB_Y_run THEN
oB_I_run := TRUE;
ELSE
oB_I_run := FALSE;
END_IF
END_CASE
2 反思
- 关于这种异常,应该是程序在下个扫描周期, 当
TON_0(IN := false...) 时,TON_0 应该被复位时, 即TON_0(...ET => T#0S) ,但是因为此时条件判断不为真,所以无法复位,第一次是没有问题的,第二次以后就有问题;
- 基于这种测试,是不是官方封装好的函数,如<mark>上升沿检测,计时器,计数器都不能用在 if、 for、 case 、while 中使用 <mark>
- 基于这种测试,是不是官方封装好的函数,如<mark>运动控制,通讯指令不能用在 if、 for、 case 、while中使用 <mark>
- 基于这种测试,是不是自己封装的函数,如<mark>FB,FC 不能用在 if、 for、 case 、while中使用<mark>
|