下面是我编写的一个简单的功能(FC1),然后在OB1里两次调用,其作用就是利用两个不同的外部输入端I0.0和I0.2分别置位DB1.DBX0.0和DB1.DBX0.1,但用模拟器模拟的结果是只要I0.0和I0.2有一个为1,那么DB1.DBX0.0和DB1.DBX0.1都会被置1。但是我把DB1.DBX0.0和DB1.DBX0.1换成Q4.0和Q4.1,这回模拟结果且是正常的了,也就是能分别置位互不影响。
以下是FC1里的代码:
A #chufa //#chufa是FC1里定义的一个输入型形参。
S #baojing //#baojing是FC1里定义的一个输出型形参
A #stop //#stop是FC1里定义的一个输入形参
R #baojing
NOP 0
以下是OB1里的调用两次FC1的代码:
程序段1:
A I 0.0
= L 20.0
BLD 103
A I 0.1
= L 20.1
BLD 103
CALL FC 2
start :=L20.0
stop :=L20.1
retval:=db1.DBX0.0
NOP 0
程序段2:
A I 0.2
= L 20.0
BLD 103
A I 0.3
= L 20.1
BLD 103
CALL FC 2
start :=L20.0
stop :=L20.1
retval:=db1.DBX0.1
NOP 0
手册中说调用FC时,参数的类型不同,在FC中处理的方式也不同,FC调用输出实参为数据块时的处理,与输出实参为M、I、Q、PQ不同。
在输出实参为M、I、Q、PQ时,FC输出形参(指针)指向实参实际存储地址,如果在FC中,没有对输出形参形成实质性操作,则形参指针所指向的实际存储区内容不会改变,对于参数传递过程而言,仅仅是调用时形参指向实参,调用结束时形参指针区域释放的一个过程。
在输出实参为DB块时,FC开始调用时,先在V区为该形参分配一个存储区(可能是位,也可能是字节或其它,根据形参参数类型而定),每一次调用FC,根据调用FC时所传递的实参类型不同,为输出形参分配的V区区域可能不同,比如一个FC有一个位输入形参,一个位输出形参,在第一次调用时,实参分别是I0.0,DB0.DBX0.0,则为输出形参分配的V区为V20.1;第二次调用FC,实参分别为DB0.DBX0.1,DB0.DBX0.2,则为输出形参分配的V区为V20.2,原来的V20.1被输入形参所对应的实参DB0.DBX0.1内容所填充。如果第二次调用FC时,实参为M0.1,DB0.DBX0.2,则为输出形参分配的V区仍为V20.1。
其后,FC在实际运行时,针对输出形参(数据块)的处理其实都是在对该V区进行处理,在FC结束调用后,不管在FC中有没有对该V区进行实质性处理,该V区的内容均会被拷贝至另一个存储区,比如L区,该L区与实参区对应,但不在同一区,此时并一直等到本次OB循环结束,该L区内容都不会被拷贝至实参区,所以这个时候实参区的内容还不会有变化。
等到下一个OB循环开始之前,该L区内容就会被拷贝至实参区。
我们可能会这样认为,FC的形参调用,对于输入、输出以及输入/输入形参的处理区别在于:
对于输入是只读不写,对于输出是只写不读,对于输入/输入是即读又写。
但这种认识并不确切,对于实参是M、I、Q、PI、PQ的参数传递,是指针指向,所以输入、输出以及输入/输入形参其实是一样的,但如果实参是数据块的参数传递,则不是指针指向,还是副本拷贝,所以可以这样认为。但是下面的这个程序是不是和这个想矛盾呢。
FC块
以下是FC1里的代码:
A #chufa //#chufa是FC1里定义的一个输入型形参。
S #baojing //#baojing是FC1里定义的一个输出型形参
A #stop //#stop是FC1里定义的一个输入形参
R #baojing
NOP 0
以下是OB1里的调用两次FC1的代码:
程序段1:
opn db1
A I 0.0
= L 20.0
BLD 103
A I 0.1
= L 20.1
BLD 103
CALL FC 2
start :=L20.0
stop :=L20.1
retval:=DBX0.0
NOP 0
程序段2:
A I 0.2
= L 20.0
BLD 103
A I 0.3
= L 20.1
BLD 103
CALL FC 2
start :=L20.0
stop :=L20.1
retval:=DBX0.1
NOP 0
问题是假如I0.0高电平时,仅DB1.DBX0.0为1,而DBX0.1不为1.
这这两个程序主要区别就是一个打开了DB块,一个没有.特在此请教大侠们。