使用scl编写三层电梯模拟控制,并学习for循环指令的应用。
文章目录
目录
文章目录
前言
1.指令学习
2.循环传值
3.嵌套调用
4.冒泡排序
1.排序
2.优化
二、三层电梯模拟控制
1.控制要求
2.编写思路
3.功能块部分编程
1.开门关门块
2.去1层2层3层的块
3.主程序部分
4.for循环部分(优先级)
1.上升优先
2.下降优先
3.等于楼层时
5. 完善程序
1.上升下降互锁
2.楼层限位判断
3.启动停止
6.主程序(完整)
总结
前言
本章我们一起来完成12个小项目试验中的最后一个——三层电梯模拟控制;并通过本章来学习一下for循环指令的应用,其中包括:循环传值,嵌套调用,冒泡排序,和编写电梯的思路和方法。好的,下面我们进入今天的内容!
一、for循环指令
在前面的指令篇中,我们有提到过,但具体的使用没有说,这里我们来学习一下。
1.指令学习
关于for循环,它需要有明确的循环次数,下面第一个参数是一个变量的起始值,第2个是结束值,第3个是步宽(不使用默认是1,一次走一个,如果是2就是一次走两个),for循环中是执行内容。
下面是博图中关于for循环的说明:
2.循环传值
这里简单使用for通过一个数组来对另一个数组进行传值:
建立两个数组和整型变量,在for循环中先确定变量的初始值,这里从0开始到5结束和数组的个数相同(如果变量超过数组个数,会导致溢出报错);by是1,一次一个(这里不用by也可以,默认是1);内容执行程序就是获取两个数组的下标然后进行传值。
效果:
3.嵌套调用
for循环也可以嵌套调用,简单示范的话,这里我们可以给一个二维数组进行传值;二维数组有两个参数或者叫坐标,可以看下图:
这里我们给二维数组传参数,就建立两个二维数组 ,中间用,号隔开;建立两个整型变量。
这里循环内部就是将变量w和t放在数组中,让他们不断变化,例:第一次的w为0,进入第2个for循环中,t从0循环到5,然后跳出,再走到第1个循环w为2,然后再次进入第2个循环;这样就将二维数组0到5,1到5,2到5,3到5等,全部走一遍。
效果:
4.冒泡排序
1.排序
知道for循环如何使用后,这里我们可以来看一下冒泡排序;它是一个排序方法,可以看下360百科中的解释:
算法原理:
知道原理后,我们来用SCL中for循环来实现一下:
我们建立1个数组,来存放排序过的排序值;再建立一些变量;这里我们初始变量为0;
len是我们的总个数(像0..5,就有6个数),总个数-1就是下标的值;进入循环后,将第1个数据和第2个数据进行比较,如果第1个数据大于第2个数据,就将它们两个交换一下,然后一直循环直到结束,那么排序就完成了。
这里我们提前写好数组里面的起始值,然后再执行;
效果:
2.优化
上面我们是提前写好起始值,然后进行排序的,我们这里也可以做两个数组,一个在运行时让我们输入初始值,另一个在运行时输出排序值;另外第2个循环也可以优化一下,每次让它-j,因为排序是有重复比较的,我们每次-j可以优化掉这一点;
在这个前面使用了一个peek指令,读取存储地址,然后放入到排序数组进行排序;注意:使用peek要取消块的优化,下面的np_temp是获取偏移地址的。
效果:
二、三层电梯模拟控制
前面简单学习回顾一下for循环指令,接下来我们一起来看三层电梯的控制。
1.控制要求
控制要求可以简单看一下,主要就是三个楼层来回切换上升或下降;
电梯参考:
2.编写思路
编写思路这里大家可以想一想平时的电梯都是如何工作的,其实简单的上升下降是比较好控制的,再加一个开门关门就差不多可以实现简单功能了,但是SCL写的话要用比较多的if来判断,这里我们的 上升,下降,开门关门,还有每个楼层外的按钮和电梯内的按钮这些可以都做成一个块,在使用时多次调用就可以,那么一个简单的电梯控制就差不多了,后面我们要根据电梯实际运行时的一个状态,再加一些控制,像简单的优先级,先去2层再去3层等等。
3.功能块部分编程
编程思路确定后,下面来编写具体的程序,这里我们先将多次需要使用的功能写在一个块里,将开关门做一个块,去1层2层3层做成块,最后在一个主的程序中将它们联系起来,来完成控制要求。
这里是用的FB块,建立的形参 ;
1.开门关门块
这里的要求就是,延时1s开门,延时2s关门,我们来编写一下:
变量m不等于0是触发条件,我们要执行开关门时只要让m不等0就可以了;变量HH是正在开门关门的一个标志位,开关门时不能进行其他操作;
#T[0].TON(IN := #BZ1,
PT := t#1s);
#T[1].TON(IN := #BZ2,
PT := t#2s);
#T[2].TON(IN := #BZ3,
PT := T#2s);
IF "电梯_DB".M <> 0 THEN
#HH := 1;
#BZ1 := 1;
//"电梯_DB".CLOSE := 0;
IF #T[0].Q THEN
"电梯_DB".OPEN := 1;
#BZ2 := 1;
END_IF;
IF #T[1].Q THEN
"电梯_DB".OPEN := 0;
"电梯_DB".CLOSE := 1;
#BZ3 := 1;
END_IF;
IF #T[2].Q THEN
"电梯_DB".CLOSE := 0;
#BZ1 := 0;
#BZ2 := 0;
#BZ3 := 0;
"电梯_DB".M := 0;
RESET_TIMER(#T[0]);
RESET_TIMER(#T[1]);
RESET_TIMER(#T[2]);
#HH := 0;
"数据块_1"."SZ"["数据块_1".T] := 0;
"数据块_1".T := 0;
"数据块_1".W := 0;
"电梯_DB".I := 0;
"电梯_DB".Q := 0;
"电梯_DB".O := 0;
END_IF;
END_IF;
2.去1层2层3层的块
这里我将这个块,分成了3个来写,方便后面调试或者完善;
去1层:(在2层或3层按下1层按钮时会触发)
这里就很简单了,A=1的时候,电梯下降 ,到达1层后给m赋值,执行开门关门,这里&上了一个开关门的一个标志位,代表开关门时无法执行去1层(后面的2层3层也一样)
//电梯去1层
#P[0](CLK := "电梯_DB".SQ1);
IF "电梯_DB".A = 1 & NOT "电梯_DB".BZ1 & NOT "开关门_DB".HH & "电梯_DB".C = 0 THEN
"电梯_DB".DOWN := 1;
IF #P[0].Q THEN
"电梯_DB".DOWN := 0;
"电梯_DB".M := 4;
"电梯_DB".A := 0;
END_IF;
END_IF;
去2层:(去2层有两种情况,在3层会下降,在1层会上升)
当b=1执行上升,当b1=2执行下降,到达楼层后停止;
//电梯去往2层
#P[1](CLK := "电梯_DB".SQ2);
IF "电梯_DB".B = 1 & NOT "电梯_DB".BZ2 & NOT "开关门_DB".HH THEN
"电梯_DB".UP := 1;
ELSIF "电梯_DB".B1 = 2 & NOT "电梯_DB".BZ1 & NOT "开关门_DB".HH THEN
"电梯_DB".DOWN := 1;
END_IF;
IF #P[1].Q & "电梯_DB".B = 1 THEN
"电梯_DB".UP := 0;
"电梯_DB".K := 1;
"电梯_DB".B := 0;
"电梯_DB".M := 2;
ELSIF #P[1].Q & "电梯_DB".B1 = 2 THEN
"电梯_DB".DOWN := 0;
"电梯_DB".K := 1;
"电梯_DB".B1 := 0;
"电梯_DB".M := 3;
END_IF;
去3层:(去3层是上升,不管是1层还是2层呼叫,都会上升)
这里和去1层基本相同;
//电梯去3层
#P[0](CLK := "电梯_DB".SQ3);
IF "电梯_DB".C = 1 & NOT "电梯_DB".BZ2 & NOT "开关门_DB".HH & "电梯_DB".O=0 THEN
"电梯_DB".UP := 1;
IF #P[0].Q THEN
"电梯_DB".UP := 0;
"电梯_DB".M := 3;
"电梯_DB".C := 0;
END_IF;
END_IF;
3.主程序部分
前面两个块好后,我们可以在主程序块中编写一下,让它们执行相应的动作:
开始先调用一下我们的函数块,后面用3个楼层限位来触发3个楼层标志,再根据楼层标志来触发条件执行相应的的楼层;
"开关门_DB"(); //开关门函数块
"去1层_DB"();//楼层函数块
"去2层_DB"();
"去3层_DB"();
// 用3个楼层限位的通和断,来接通或断开中继和楼层指示灯;
// 是对三个楼层的限位进行控制。
IF #SQ1 THEN
#ZJ[1] := 1;
#ZJ[2] := 0;
#ZJ[3] := 0;
#L1 := 1;
"数据块_1".U := 1;
ELSE
#ZJ[1] := 0;
#L1 := 0;
END_IF;
IF #SQ2 THEN
#ZJ[2] := 1;
#ZJ[3] := 0;
#ZJ[1] := 0;
#L2 := 1;
"数据块_1".U := 2;
ELSE
#ZJ[2] := 0;
#L2 := 0;
END_IF;
IF #SQ3 THEN
#ZJ[3] := 1;
#ZJ[2] := 0;
#ZJ[1] := 0;
#L3 := 1;
"数据块_1".U := 3;
ELSE
#ZJ[3] := 0;
#L3 := 0;
END_IF;
//在运行时进行互锁,上升时不能下降,下降时不能上升
IF #UP = 1 THEN
#BZ1 := 1;
ELSE
#BZ1 := 0;
END_IF;
IF #DOWN = 1 THEN
#BZ2 := 1;
ELSE
#BZ2 := 0;
END_IF;
//获取按钮上升沿
#P[0](CLK := #SQ1);
#P[1](CLK := #SQ2);
#P[2](CLK := #SQ3);
#PR[0](CLK := #S1);
#PR[1](CLK := #S2);
#PR[2](CLK := #S3);
#PR[3](CLK := #SU1);
#PR[4](CLK := #SU2);
#PR[5](CLK := #SD2);
#PR[6](CLK := #SD3);
这里就是楼层执行部分,在1层按下1楼按钮后,执行开门关门,如果按下2层3层按钮就执行我们的去2层去3层的块。
//一层执行
IF #ZJ[1] THEN
IF "数据块_1".T = 1 THEN
#M := 1;
END_IF;
IF "数据块_1".T = 2 THEN
#O := 1;
#B := 1;
END_IF;
IF "数据块_1".T = 3 THEN
#C := 1;
END_IF;
END_IF;
//二层执行
IF #ZJ[2] THEN
IF "数据块_1".T = 2 THEN
#M := 1;
END_IF;
IF "数据块_1".T = 1 THEN
#A := 1;
END_IF;
IF "数据块_1".T = 3 THEN
#C := 1;
END_IF;
END_IF;
//三层执行
IF #ZJ[3] THEN
IF "数据块_1".T = 3 THEN
#M := 1;
END_IF;
IF "数据块_1".T = 1 THEN
#A := 1;
END_IF;
IF "数据块_1".T = 2 THEN
#B1 := 2;
END_IF;
END_IF;
4.for循环部分(优先级)
1.上升优先
在电梯执行时,如果在1层按下3 2 1 内部按钮,那么要优先执行距离1层最近的楼层,这里就用到for循环:在循环数组时,执行3,2,1,进行循环,如果按下3再按下2,那么2会将3覆盖掉;我们再判断一下它是否大于当前楼层,如果是就将找到的最小楼层给变量T,然后再执行楼层;
//上升优先级(后按下的按钮会覆盖掉前面的)
FOR "数据块_1".W := 3 TO 1 BY -1 DO
IF "数据块_1".SZ["数据块_1".W] = TRUE THEN
IF "数据块_1".W > "数据块_1".U THEN
"数据块_1".T := "数据块_1".W;
END_IF;
END_IF;
END_FOR;
2.下降优先
这里和上升优先相反,是从1到3,依次执行,然后判断是否小于当前楼层,如果是就执行;
//下降优先级
FOR "数据块_1".W := 1 TO 3 BY 1 DO
IF "数据块_1".SZ["数据块_1".W] = TRUE THEN
IF "数据块_1".W < "数据块_1".U THEN
"数据块_1".T := "数据块_1".W;
END_IF;
END_IF;
END_FOR;
3.等于楼层时
在等于楼层时,再执行这一种情况;
//等于当前楼层时进行判断
FOR "数据块_1".W := 1 TO 3 BY 1 DO
IF "数据块_1".SZ["数据块_1".W] = TRUE THEN
IF "数据块_1".W = "数据块_1".U THEN
"数据块_1".T := "数据块_1".W;
END_IF;
END_IF;
END_FOR;
5. 完善程序
这里基本功能和简单优先级都可以实现了,我们再将各部分程序完善一下 ;
1.上升下降互锁
在上面的楼层部分加上BZ1或BZ2的常闭,就可以了。
//在运行时进行互锁,上升时不能下降,下降时不能上升
IF #UP = 1 THEN
#BZ1 := 1;
ELSE
#BZ1 := 0;
END_IF;
IF #DOWN = 1 THEN
#BZ2 := 1;
ELSE
#BZ2 := 0;
END_IF;
2.楼层限位判断
判断是否有多个限位被触发,如果有就停止所有动作;
//判断是否有两个或两个以上的限位被触发,如果有就停止当前所有动作
IF (#SQ1 & #SQ2) OR (#SQ1 & #SQ3) OR (#SQ2 & #SQ3 OR #SQ1 & #SQ2 & #SQ3) THEN
#BJ100 := 1;
#L1 := 0;
#L2 := 0;
#L3 := 0;
ELSE
#BJ100 := 0;
END_IF;
3.启动停止
//停止,按下后运行完当前楼层后停止,按下停止后再按楼层呼叫按钮就无效了
IF #OFF THEN
#TZ100 := 1;
END_IF;
//按下启动后,按钮恢复初始状态
IF #ON THEN
#TZ100 := 0;
END_IF;
6.主程序(完整)
这里还加了一个按下按钮后延时2s后再执行的定时器,主要是在多个按钮按下时有足够的时间来进行一个优先级判断,然后执行。文章来源:https://www.toymoban.com/news/detail-558312.html
//判断是否有两个或两个以上的限位被触发,如果有就停止当前所有动作
IF (#SQ1 & #SQ2) OR (#SQ1 & #SQ3) OR (#SQ2 & #SQ3 OR #SQ1 & #SQ2 & #SQ3) THEN
#BJ100 := 1;
#L1 := 0;
#L2 := 0;
#L3 := 0;
ELSE
#BJ100 := 0;
END_IF;
//停止,按下后运行完当前楼层后停止,按下停止后再按楼层呼叫按钮就无效了
IF #OFF THEN
#TZ100 := 1;
END_IF;
//按下启动后,按钮恢复初始状态
IF #ON THEN
#TZ100 := 0;
END_IF;
IF NOT #BJ100 THEN//多个限位按下就停止
"开关门_DB"(); //开关门函数块
IF #T[5].Q THEN //启动延时时间
"去1层_DB"();//楼层函数块
"去2层_DB"();
"去3层_DB"();
END_IF;
//启动延时
#T[5].TON(IN := #BZ5,
PT := T#2s);
//当按钮全部复位后,标志位清零
IF "数据块_1".SZ[1] = "数据块_1".SZ[2] & "数据块_1".SZ[2] = "数据块_1".SZ[3] & "数据块_1".SZ[3] = 0 THEN
#BZ5 := 0;
END_IF;
// 用3个楼层限位的通和断,来接通或断开中继和楼层指示灯;
// 是对三个楼层的限位进行控制。
IF #SQ1 THEN
#ZJ[1] := 1;
#ZJ[2] := 0;
#ZJ[3] := 0;
#L1 := 1;
"数据块_1".U := 1;
ELSE
#ZJ[1] := 0;
#L1 := 0;
END_IF;
IF #SQ2 THEN
#ZJ[2] := 1;
#ZJ[3] := 0;
#ZJ[1] := 0;
#L2 := 1;
"数据块_1".U := 2;
ELSE
#ZJ[2] := 0;
#L2 := 0;
END_IF;
IF #SQ3 THEN
#ZJ[3] := 1;
#ZJ[2] := 0;
#ZJ[1] := 0;
#L3 := 1;
"数据块_1".U := 3;
ELSE
#ZJ[3] := 0;
#L3 := 0;
END_IF;
//在运行时进行互锁,上升时不能下降,下降时不能上升
IF #UP = 1 THEN
#BZ1 := 1;
ELSE
#BZ1 := 0;
END_IF;
IF #DOWN = 1 THEN
#BZ2 := 1;
ELSE
#BZ2 := 0;
END_IF;
//获取按钮上升沿
#P[0](CLK := #SQ1);
#P[1](CLK := #SQ2);
#P[2](CLK := #SQ3);
#PR[0](CLK := #S1);
#PR[1](CLK := #S2);
#PR[2](CLK := #S3);
#PR[3](CLK := #SU1);
#PR[4](CLK := #SU2);
#PR[5](CLK := #SD2);
#PR[6](CLK := #SD3);
IF NOT #TZ100 THEN //按下停止后按钮无效
//根据按下的按钮传入相应的数值,然后启动bz5进行延时(目的是判断是否还有其它按钮按下,如果有在延时时间
//内进行排序,走离自己比较近的楼层
IF #PR[0].Q OR #PR[3].Q THEN
"数据块_1".#"SZ"[1] := 1;
#BZ5 := 1;
ELSIF #PR[1].Q OR #PR[4].Q OR #PR[5].Q THEN
"数据块_1".#"SZ"[2] := 1;
#BZ5 := 1;
ELSIF #PR[2].Q OR #PR[6].Q THEN
"数据块_1".#"SZ"[3] := 1;
#BZ5 := 1;
END_IF;
END_IF;
//获取数组中的按钮值,进行判断
//上升优先级(后按下的按钮会覆盖掉前面的)
FOR "数据块_1".W := 3 TO 1 BY -1 DO
IF "数据块_1".SZ["数据块_1".W] = TRUE THEN
IF "数据块_1".W > "数据块_1".U THEN
"数据块_1".T := "数据块_1".W;
END_IF;
END_IF;
END_FOR;
//下降优先级
FOR "数据块_1".W := 1 TO 3 BY 1 DO
IF "数据块_1".SZ["数据块_1".W] = TRUE THEN
IF "数据块_1".W < "数据块_1".U THEN
"数据块_1".T := "数据块_1".W;
END_IF;
END_IF;
END_FOR;
//等于当前楼层时进行判断
IF NOT #BZ1 & NOT #BZ2 THEN
FOR "数据块_1".W := 1 TO 3 BY 1 DO
IF "数据块_1".SZ["数据块_1".W] = TRUE THEN
IF "数据块_1".W = "数据块_1".U THEN
"数据块_1".T := "数据块_1".W;
END_IF;
END_IF;
END_FOR;
END_IF;
//一层执行
IF #ZJ[1] THEN
IF "数据块_1".T = 1 THEN
#M := 1;
END_IF;
IF "数据块_1".T = 2 THEN
#O := 1;
#B := 1;
END_IF;
IF "数据块_1".T = 3 THEN
#C := 1;
END_IF;
END_IF;
//二层执行
IF #ZJ[2] THEN
IF "数据块_1".T = 2 THEN
#M := 1;
END_IF;
IF "数据块_1".T = 1 THEN
#A := 1;
END_IF;
IF "数据块_1".T = 3 THEN
#C := 1;
END_IF;
END_IF;
//三层执行
IF #ZJ[3] THEN
IF "数据块_1".T = 3 THEN
#M := 1;
END_IF;
IF "数据块_1".T = 1 THEN
#A := 1;
END_IF;
IF "数据块_1".T = 2 THEN
#B1 := 2;
END_IF;
END_IF;
END_IF;
总结
上面就是for循环和最后一个项目三层电梯的所有内容了!文章来源地址https://www.toymoban.com/news/detail-558312.html
到了这里,关于【SCL】for循环指令的应用&三层电梯模拟控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!