编程的时候除了注意指令的使用环境,还需要注意基本的运行规则,否则就会产生不必要的小BUG,这些小BUG看似简单,但是真正解决起来却不容易,因为这样的错误是根深蒂固地存在大脑的深处,看着错误可能就是觉得是正确的,这样就会怀疑其它的地方,造成方向性的错误,比如是不是CPU的操作系统有BUG,或者是指令系统有BUG,即使老司机也可能犯低级的错误。
在编写《从S7-300_400到S7-1500看变址寻址的改变》系列时做了一个小的示例程序,结果总是有问题,分析也很烧脑。好了,先介绍一下程序的功能,这是一段表查询的小程序:
例如创建一个数据块A,然后在里面再创建一个数组B,INDEX从0~100,单位是INT,这样一个表就创建完毕,然后使用一个已知的值与表中的值比较,如果查询到第一个相同的值就记录值的位置,就是数组中INDEX的值,然后清零INDEX的值并复位查询使能位,如果没有查询到,INDEX值加1,如果整个表中都没有相同的值,同样清零INDEX并复位查询使能位。程序参考图1。
图1
"Start_comp"作为查询使能位,如果 "Comp_Value"与表(数组) "A".B["Index"]的值相同,将"Index"的值存储到"Result"中,然后清零"Index"并复位查询使能位 "Start_comp";如果 "Comp_Value"与表(数组) "A".B["Index"]的不相同,将"Index"的值加1,如果查询到表的最后,还是没有相同的值,同样清零"Index"并复位查询使能位 "Start_comp"。一段小程序,非常简单,好了,再看一下程序监控吧,参考图2。
图2
查询的结果是正确的,但是"Index"的值定格为1而不是0。对于这样的结果,我首先想到的是时序的问题,是不是S7-1500编程功能扩展后程序有些变化?想起一个办法就是在S7-300中编写相同的程序,然后切换到STL,使用断点监控一下,后来还是放弃了,因为S7-300不支持数组INDEX 的方式,如果使用S7-1500做也比较麻烦。可以把程序放到循环中断中,放大扫描时间看一下结果,就是相当于慢放功能,监控程序,首先是值不相等条件满足,如图3所示。
图3
从图3中可以看到,值不相等,"Index"的值加1,然后与下一个值进行比较,直到与比较值相同,如图4所示。
图4
从图4中可以看到,比较值等于与不等于同时满足,所以上面"Index"的值清零了,下面一行又加1了,所以"Index"的值最终定格在1上,只是什么逻辑!!! 搞不明白!!!
经过一番折腾,发现问题了,比较值相等的"Index"是2,比较值不相等的"Index"是0,说明"Index"是清零了,所以会出现比较值等于与不等于同时满足的情况,就是因为比较的值不同了,所以犯了一个小错误,也是没有仔细查看,也是由于设定的扫描时间还是比较短,最后使用图片抓拍才发现。
总结一下这里的问题,主要还是时序的问题,相同程序段线圈的复位结果作用在下一个扫描周期,而赋值结果是在指令完成之后。可以把上下两行程序互换一下位置就可以解决问题了,程序参考图5。
图5
想要学习更多工业知识,欢迎访问西门子1847工业学习平台,这是一个官方的学习平台,能够帮助您高效获得实用和权威的资料。
另外,这里还有60场西门子1847工业专家会议等您来参与!点击下方链接查看会议详情。