恭喜,你发布的帖子
发布于 2022-12-09 22:04:12
16楼
1、程序要先说明功能,才能判断是否存在问题。直接讨论程序是否存在问题,没有意义。
编程者使用立即输出,他必须有明确的目的。
而且,立即输出实际上取消了输出缓存机制,这种情况下,没有双线圈问题,所有的输出直接反应在外界电路中。
比如:
网络1
LD Always_On:SM0.0
MOVD AC0, AC0
粗看没有产生任何有用的结果。但是,如果加上注释(功能说明),情况就不一样了:
LD Always_On:SM0.0
MOVD AC0, AC0 // NOP指令,短延时
2、关于中断引发的问题。
主帖中已经有提到,如果中断和主程序间存在变量共享,始终存在相互配合的问题,不限于Q点,存在于任何的共享变量中。如果不予重视,随时随地会埋下地雷。
也通过一个例子来说明问题:
程序实现如下逻辑式:
Q0.0=(M0.0 and I0.0) or (!M0.0 and I0.1),其中的“!”是“逻辑非”的意思。
这是一个二选一的数据选择逻辑:
当M0.0=0时,Q0.0=I0.1
当M0.0=1时,Q0.0=I0.0
程序如下:
网络1
LD M0.0 // 读取
A I0.0 // 实现 M0.0 and I0.0
LDN M0.0 // 二次读取
A I0.1 // 实现 !M0.0 and I0.1
OLD // 完成 or
= Q0.0 // 输出
有人认为这个写法有问题吗,需要禁止这样写吗?
如果,M0.0与中断存在共享,也就是说,M0.0的值由中断程序给定,那么,上述写法就埋下了一个地雷。
网络1
LD M0.0 // 读取
A I0.0 // 实现 M0.0 and I0.0
// 发生中断,中断改变了M0.0的值
LDN M0.0 // 二次读取
A I0.1 // 实现 !M0.0 and I0.1
OLD // 完成 or
= Q0.0 // 输出
程序爆雷时,Q=0或Q=I0.0 or I0.1
改变一下写法,如下:
网络1
LD M0.0 // 一次性读取
LPS // 入栈
A I0.0 // 实现 M0.0 and I0.0
LDS 1 // 出栈
NOT // 逻辑非
A I0.1 // 实现 !M0.0 and I0.1
OLD // 完成 or
= Q0.0 // 输出
这一段,无法转成对应的LAD。入栈、出栈可以用中间变量M0.0实现。
上述写法,与中断互动,不会有埋地雷了。
但是,显然不能因为中断的需要,类似“双线圈”的问题,创设一个位变“双读取”、多读取问题。
我认为编程中的确是要考虑这些事情的,通过建立变量副本可以有效规避此类问题,包括使用功能块定义输入输出变量,在S7-300/400/1200/1500西门子的编程规范中不建议从外部访问FB的静态变量,也是防止在中断中改写变量后产生意外的逻辑。
逻辑变量在一个扫描周期内被多次改写,我不认为这是什么好习惯好做法。
请填写推广理由:
分享
只看
楼主