不是这样的。这是社会分功的原理。安排别人做不等于自己不能做不会做。在这个社会分工上没有能力高低的区别。
我请你做一个简单的实验。要求是给子程序一个输入点。一个输出点。要求子程序做翻转的动作。0变1,1变0。而且这个子程序要多次调用互不影响。
你用仿真软件应该可以模拟的了。你就模拟用I0.0翻转Q0.0。用I0.1翻转Q0.1。就两个。
我的程序一定是用SM0.0调用的。这个毫无疑问。当整个程序只有你的这个子程序和主程序相应的指令外没有其他东西了。此时程序无疑是正常的。这个我不否认。但是像我前面说的,主程序中紧跟你的子程序后加这个子程序。那么……。
不存在什么提前返回。<子程序输出赋值给主程序变量就相当于把结果保存! >这个不等于的。保存IN/OUT是双向可操作可读可写。OUT只能输出,以后要是子程序要求知道输出的状态,是不可能的,他没有反向的过程。覆水难收。所以我说“这个不等于的”。
我能够加一个子程序可以完全颠覆你的程序。足可以证明我的确知道你程序的漏洞。<至于你所说的 IN_OUT 类型 是用来保存值的, 呵呵, 你竟然这样理解保存值啊>这个我暂时保持沉默。待你自己再模拟一下后,我们再研究研究。
说说一个正面的问题。有一个我对你有佩服。不说其他事情。你的程序可以净用触点指令可以完成所有程序。是我意料之外。我以为会用到很多边缘指令和置位复位。其实没有,这个应该是一个很易读的程序。
呵呵,我说过了IN_OUT 和 out 变量是很不同的. 我说了半天感情你没听懂我的意思! IN_OUT 变量是有必要用到时候再用,你觉得那么简单的子程序有必要用吗? 我知道IN_OUT 类型,说白了,是传指针(地址), 可以改变外部变量值,你不用怀疑我对这个变量类型的理解及应用! 我觉得我没必要说太多!
你说的连续调用 子程序会出错, 我不理解, 除非你重复调用,我没有硬件,我不敢说我的程序没漏洞! 我没有在硬件上模拟!
"你的程序可以净用触点指令可以完成所有程序。是我意料之外。我以为会用到很多边缘指令和置位复位。其实没有,这个应该是一个很易读的程序。"
难道你看到了我的程序! 哪西门子加密文件也太垃圾了!
我只是在一个廿多人的机械厂里做编程的。只是有时候工作太挤了想找外协。但是又不能把全部的工作外判。因为有售后的问题。所以只能用部件的形式购买程序。中心的控制还是必须自己做的。
横向传递和破坏两个概念组合起来书本上只用了,引用
<
S7-200PLC给主程序分配64字节个局部变量,给每级嵌套子程序分配64个字节局部变量存储器,给中断程序分配64个字节局部变量存储器。
使用局部变量存储器规定,子程序不能访问分配给主程序、中断程序和其他子程序的局部变量,子程序和中断程序不能访问主程序的局部变量存储器,中断程序也不能访问主程序和子程序的局部变量。
>
和<进入和退出子程序后的值都是不定的>之类的文字。
在以上描述中并没有否定子程序和子程序之间 “能” 互相访问。这就是[横向传递]。还有要留意:
<给每级嵌套子程序分配64个字节>这里说的是“每级”,不是每个,也不是公用。每级有不同的64个字节使用。级和级之间是公用的。第一级嵌套子程序共用64字节。第二级嵌套子程序共用另外64字节。第三、四、五、六、七、八级嵌套子程序共用另另另另另另外64字节。这样的方式很显然把程序结构画成树型结构的话是只能水平方向上的子程序共用相同的64字节。而垂直方向是没有看见相同的东西的。真正可以表述为[横向传递]。(相反累加器AC就是中断程序和其他程序的横向隔离。)
传递的方向只能按照扫描方向传递。
要知道L取也是储存空间。上电初始值都是零的,更改了之后要是没有在修改都是不变的。为何<进入和退出子程序后的值都是不定的>呢?到底是什么东西什么时候写了值呢?
文章中没有说为什么。只是要求你不要乱使用。先辅值再使用。值是不定的。之类的话。
你的程序在实验的过程中始终保持只有你一个子程序。并没有任何横向的东西。所以任何写到L上的数值都得以保存,也就所以你不需要额外的辅助保存动作,子程序仍然可以记忆过去的值。同时主程序也不可能破坏这个记忆。横向吗,纵向是隔离的。
当我增加后面的子程序后……(给每级嵌套子程序分配64个字节局部变量存储器,)我的程序和你的程序是同一级。我可以改写你的L区。之后你的子程序就没有了当初的记忆了。
这种情况就是书本上归纳为<进入和退出子程序后的值都是不定的><先辅值再使用。>并没有再详细解释了。
或许这个概念很难理解好象跟书本上的描述都完全不一致。
再举一例
复制后保存为*.AWL文件就可以导入了。模拟软件应该可以模拟的。
ORGANIZATION_BLOCK 主程序:OB1
TITLE=程序注释
// SBR0对一级嵌套的子程序所使用的L区写值。
// SBR 1 2 3 4 都是一级子程序,都读取共享区数据并输出。
//
// SBR5是二级嵌套的子程序。对二级共享的L区域写值。
// SBR 6 7 都是二级子程序,都读取共享区数据并输出。
//
// 在此。一 二级的共享区使用了相同的编程符号。LB0。但通过上机运行,显然互不干涉。
BEGIN
Network 1 // 网络标题
// 网络注释
LD SM0.0
CALL SBR0
CALL SBR1
CALL SBR2
CALL SBR3
CALL SBR4
END_ORGANIZATION_BLOCK
SUBROUTINE_BLOCK SBR_0:SBR0
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD SM0.5
EU
LD SM0.5
ED
OLD
INCB LB0
Network 2
LD SM0.0
CALL SBR5
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_1:SBR1
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD L0.0
= Q0.0
Network 2
LD SM0.0
CALL SBR6
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_2:SBR2
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD L0.1
= Q0.1
Network 2
LD SM0.0
CALL SBR7
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_3:SBR3
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD L0.2
= Q0.2
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_4:SBR4
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD L0.3
= Q0.3
Network 2 // 网络标题
// 网络注释
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_5:SBR5
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD SM0.5
EU
INCB LB0
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_6:SBR6
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD L0.0
= Q1.0
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_7:SBR7
TITLE=子程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
LD L0.1
= Q1.1
Network 2 // 网络标题
// 网络注释
END_SUBROUTINE_BLOCK
INTERRUPT_BLOCK INT_0:INT0
TITLE=中断程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
END_INTERRUPT_BLOCK
例如一个程序:
主程序
LD SM0.0
MOVB 10 LB0
CALL SBR0
CALL SBR1
END
子程序1
LD SM0.0
MOVB 12 LB0
RET
子程序2
LD SM0.0
MOVB LB0 MB0
RET
然后你监控一下MB0.
这的确表明子程序1中12的这个值毫无影响地[横向传递]到子程序2了。中途的主程序并没有干涉到。
你的LB0是系统分配给主程序的 TEMP 存储区的零时变量, 在主程序中共享TEMP (L区), 你所说的横向传递就是这样的啊!呵呵!
你改变调用顺序,你看看主程序会不会影响LB0, 例如:
主程序
LD SM0.0
CALL SBR0
MOVB 10 LB0
CALL SBR1
END
显然MB0是10 ;
当我仔细看了系统手册后,我发现我的库文件是失败的! 这样的要求应该用IN_OUT类型指定外部公共变量,调用不同的实例,就指定不同外部共享变量;
看看,系统手册上说的, 局部存储器在分配时PLC不进行初始化! 初值可能是任意的,当在子程序调用中传递参数时,用子程序的局部存储器中由cpu 替换其被传递的参数值,局部存储器在参数传递过程中值,在分配时不被初始化, 可能包含任意值.
这说明,每个子程序的 L区,只有一份存储区(60byte ), 而且这个区是编译时系统自动分配的, 不论你调用多少次子程序,其共享60byte L区, 不同的子程序有各自的 L 区, 它们互不干扰! 当子程序调用大于2次调用时,第2次调用是 L区 保持上一次调用的值! 一次类推! 始终保持上一次调用的 L区值! 系统手册已经解释的很清楚了! 这是标准的子程序的定义! 子程序调用是压栈方式进行的! 它不同于某些品牌PLC 的功能块 !
我是懒得去看系统手册! 呵呵,有时间再改了!