楼主最近还看过
我于3月22日在№22楼贴出“swading”网友的 8行 INC D0 的程序,并称是当时(3月22日)来讲“迄今为止”最好的方案。并希望有人来参与,写出更好更简练的解决楼主提出的问题的程序。
这不!引起了“芳季”网友的兴趣。贴出一个用“循环语句”和“移位命令”结合的解决方案来让我们大开了眼界!
不过,“芳季”网友的程序有一些错误。所以我在№25楼贴出了我的一个程序,这个程序写得繁了一些,但是,它却是能够正确统计出报警点数来的。它的这个“繁”,事实上是我有意为续下来的讨论打下的伏笔。让网友们挑挑“破绽”好引出更深层次的话题。
接下来我就开始回答“芳季”网友这样的提问:“干吗要占个K9呢?一移过来第一个是1的话已经可以加1了。何必要通过M0启动呢?
还有更短的程序吗? ”
用“循环语句”在程序的每个扫描周期里都要循环重复8次执行“位右移”指令,如果出现报警的点数达到8个的话,还要重复执行8次“INC D0 ”指令。这样是很费时间的,使程序的扫描周期拖得很长。扫描周期太长就不利于PLC实时的控制设备的运行!所以我们要设法缩短程序的扫描周期。
报警点的信息并不是经常或快速不断在变动的,而是很久才可能有报警信息的变动。所以我们没有必要让程序每一个扫描周期都去循环执行“统计报警点数”的任务。把时间腾出来让PLC去执行它主要的控制任务!
我“干嘛要占个K9呢? ”我占个K9是想在统计出“报警点数”之后再重复利用“K2M1”这个字节的内容,把它与“K2X10”进行比较,当“K2M1”与“K2X10”的内容一致时,就让程序跳过循环的这一段程序去执行主要的控制任务,不必每个周期都去重复统计“报警点数”从而提高PLC对设备控制的“实时性”!当报警信息出现新状态时,通过比较“K2M1”与“K2X10”的信息有不同时,又才去执行“报警点数”的统计任务。
贴在№52楼的程序的编写思路是:平常没有报警时,“k2m1”字节的内容是“0000”与“K2X10”字节的内容“0000”是一致的。通过“接点
比较”(<> K2X10 K2M1 )得出:“传送(MOV k2X10 K2M1 )指令”及“清零( RST D0 )指令”的执行条件“不成立”。
于是,这时程序是不执行这两条指令的。我认为:程序不执行这两条指令,因而这两条指令在这种情形下就不会占用程序的扫描周期时间(不知道我的
理解对不对,谨供网友们参考)。再通过第3行的“反相(INV )指令”构成“跳转(CJ P0 )指令”的执行条件“成立”,使程序直接跳过“循环范
围”,避免毫无意义的循环重复8次执行“位右移(SFTR MO M0 K9 K1)指令”,因为这时“K2M1”字节内各个“位”均为“0”,
完全没有去统计这一字节内有多少个“ON”的“位”的意义!
在设备运行中,倘若设备的某些构件或局部出现问题,送出了报警信号,这时通过“接点比较(<> K2X10 K2M1 )指令”得出:“传送
(MOV k2X10 K2M1 )指令”及“清零( RST D0 )指令”的执行条件“成立”。于是,程序把“K2X10”字节的报警信息传送给“K2M1”字节,接着把
存贮报警点数的统计数据的寄存器“D0”的内容“清零”。这第1次的“清零”虽然没有意义,但是,我们也没有必要刻意避免这一次的“ RST
D0 ”因为这条指令执行一次只占“3步”除这第1次之外倘若“K2X10 ”字节的报警信息发生改变(或报警排除,抑或产生新的报警),我们要“刷
新报警统计数据”,对“D0 ”执行“RST指令”就是最简的必不可少的措施!程序对“D0 ”执行“RST指令”则意味着这时“跳转(CJ P0)指
令”的执行条件“不成立”。所以,程序进入循环范围,反复执行8次“位右移(SFTR M0 M0 K9 K1 )指令”及有条件的重复执行
“INC D0 ”,进行报警点数的统计过程。这一过程是相当费时间的。循环结束之后数据寄存器“D0”内容就被刷新成现时的报警统计数据了(这个数
据也有可能是:所有“报警”被完全排除的状态数据)。