今天看到一条程序,测试时有点问题,经监控发现是带参数调用子程序引起的,这个问题以前有人在论坛中提到过,主要原因是S7-200smart中,子程序使用的临时变量是共用一套存储区,进入子程序时也不会为分配的存储区进行初始化处理(清零)。
为验证这个现象,做了一条简单的程序:
SBR_0用来进行上限检测,测量值大于上限值,标志位置位;测量值小于(上限值-回差值),标志位复位。标志位配置为OUT变量
SBR_1内没有指令,只是通过变量配置,使OUT变量的临时地址和SBR_0中的标志位一致。
测试结果一
测试结果二
测试结果三
测试结果四
分析:在SBR_0中,存在不对OUT变量赋值的周期,赋值只有两种情况,一是测量值超出上限值,置位;二是测量值小于等于(上限值-回差值),复位;而当(上限值-回差值)<测量值<=上限值时,既没有置位也没有复位,这时候存在继承执行本段子程序之前的共用存储区的状态。
对策:子程序每次执行时,必须对OUT变量赋值;
如果子程序中存在对OUT变量无赋值的可能,可以将参数定义为IN/OUT变量,执行子程序前,先将全局变量状态传递到临时存储区,然后在执行指令,即使本次执行不对参数赋值,状态也和执行前的全局变量一致。
本例中,将SBR_0的OUT变量换成IN/OUT之后,执行结果正确。将SBR_1的OUT变量换成IN/OUT之后,也不受前面子程序调用的影响。
个人浅见,难免错误,还望指点!