发布于 2011-07-18 20:44:31
15楼
好不容易才把这个帖子找到。我也是初学,不对的地方希望斧正。
经过详细的比对,我发现用sfc21还真不见得就比直接用scl写省事。下面是源代码,首先请先建立一个db100,长度为1200,内容类似如下:
warning2 : BOOL :=false; //***警告输入
warning3 : BOOL :=false; //***警告输入
warning4 : BOOL :=false; //***警告输入
warning5 : BOOL :=false; //***警告输入
warning6 : BOOL :=false; //***警告输入
……
这个觉得输入麻烦,可以用excel,用他的自动填充功能,然后再复制进scl源文件或者stl源文件,按ctrl+b编译就可以了。
下面的源程序也是如此。注释部分是我比较的结果,2种方式比较结果而言,相差不大。非要说出个一二三,就是直接循环比用sfc21写起来顺畅,不用一下字母一下数字的。还有所用的字符少了点。另外,长度不是8的整数倍(也包括起始位,帮助里面没说)的情况sfc21不知道怎么实现最后的部分(比如db块长度为100,最后4条bool)?
FUNCTION FC300 : void
(*
可以用来直接输入数字:1、2、4分别代表1级、2级、3级。
如果需要清除或设置多个,那么相加就可以。
例如:
清除1、3级警报,就输入整数1+4=5;
清除1、2、3级警报,就输入整数7。
如果等级太多可以用数组。后面是2的0次方到(n-1)次方。
如果bool长度是8的整数倍直接用sfc21更简单。
当然,不是8的整数倍用这个更简单,用sfc21我没想明白怎么写。
*)
VAR_INPUT
Number :WORD ;//初始化的类型。
Sign :BOOL ;//初始化的状态。
END_VAR
VAR_TEMP
//考虑实际情况,一般每种警报总数都是固定的,
//所以用一个警报类型来确定清理的数量。这些也好读。
i:INT;//循环临时变量
w1:bool;//1级警报。
w2:bool;//2级警报。
w3:bool;//3级警报。
END_VAR
//取得警报分级。
w1:= ((number AND word#1)=word#1) AND Sign ;
w2:= ((number AND word#2)=word#2) AND Sign ;
w3:= ((number AND word#4)=word#4) AND Sign ;
//1级警报是0-50.
FOR i:=0 TO (50*8-1) DO
db100.dbx[0,i]:= w1;
END_FOR;
(*
50位的写法:
FOR i:=0 TO (50-1) DO
db100.dbx[0,i]:= w1;
END_FOR;
这个可以解决不是8整数倍的问题。
(50*8-1)是规范写法,可以直接写最终值。
使用sfc21的写法:
CALL "FILL"
BVAL :=P##w1 BOOL 8
RET_VAL:=MW100
BLK :=P#DB100.DBX 0.0 BOOL 400
论方便程度,直接循环跟用sfc21相差不大。
但是循环可以少打50多个字母。好像是54个。
w1往后8位都必须是逻辑位啊。
以下都类似,我就不写了。
*)
//2级警报是50-99.
FOR i:=50*8 TO (100*8-1) DO
db100.dbx[0,i]:= w2;
END_FOR;
(*
sfc21的用法:
CALL "FILL"
BVAL :=P##w1 BOOL 8
RET_VAL:=MW100
BLK :=P#DB100.DBX 50.0 BOOL 400
这里BLK的起始位必须是8的整数倍,50.1就会错误。
*)
//3级警报是100-149.
FOR i:=100*8 TO (150*8-1) DO
db100.dbx[0,i]:= w3;
END_FOR;
(*
一:db100可以修改为实际用来存放警报变量的db块。当然也可以做个输入参数(block_db)来动态指定,不过个人感觉实际意义不大。
二:可以增加定义自己的每级警报多少个。这里采用的是原来的说法每级50*8个。这个也可以写成数组,跟上面一样个人感觉意义不大。
三:同理警报的级数也可以做个数组,感觉意义也不大,呵呵。如果全做成动态数组就是每个数组的个数不定。
*)
END_FUNCTION
就像找找偷懒的诀窍