计数器指令是保持型的输出指令,当梯级条件跳变时实施计数操作,计数范围为-2147483648~2147483647,这正是32位寄存器的DINT数据类型可表达的正负数据范围,计数器指令使用COUNTER结构数据类型的标签,如图5-20所示。
图5-20 COUNTER结构数据类型标签
计数器结构数据标签的元素:
●PRE预置值 设定计数预定值;
●ACC累加值 按照梯级条件跳变进行的计数积累;
●CU增计数使能 增计数指令梯级条件跳变置位;
●CD减计数使能 减计数指令梯级条件跳变置位;
●DN完成位 当累加值大于等于预置值时置位;
●OV上溢出位 当累加值达上限值2147483647时计数加1后,该位被置位,且回归到计数下限值-2147483648,此时完成位仍置位;
●UN下溢出位 当累加值小下限值-2147483648时计数减1后,该位被置位,且回归到计数上限值2147483647,此时完成位仍复位。
增计数指令CTU完成加1的操作,如图5-21所示。增计数指令的梯级条件跳变,位地址UP_Pluse从0变为1时,增计数使能位CU置位,累加值加1,梯级条件消失;位地址UP_Pluse从1变为0时,增计数使能位CU复位,等待下一次的计数。显然,是CU位的置位引起了增计数。每次增计数完成,计数器都要测试,比较累加值ACC和预置值PRE,以决定完成位和上溢出位的状态。
图5-21 增计数指令完成加1的操作
减计数器指令CTD完成减1的操作,如图5-22所示。减计数指令的梯级条件跳变,位地址Down_Pluse从0变为1时,减计数使能位CD置位,累加值减1,梯级条件消失;位地址Down_Pluse从1变为0时,减计数使能位CD复位,等待下一次的计数。显然,是CD位的置位引起了减计数。每次减计数完成,计数器都要测试,比较累加值ACC和预置值PRE,以决定完成位和下溢出位的状态。
图5-22 减计数器指令完成减1的操作
计数器指令在控制器中的作用跟计时器指令一样,都是最基本的功能,但是它的执行却完全不同,这主要表现在对梯级条件的要求不同,计数器指令的执行,全靠梯级条件跳变来触发,不管是增计数还是减计数。计数器计不计数只跟梯级条件跳变有关,跟DN位置位不置位无关,完成位在这里只是一个标志位,表示当前累加值大于等于预置值;跟上溢出位置位不置位无关,那只是累加值ACC的进位状态;跟下溢出位置位不置位无关,那只是累加值ACC的借位状态。总而言之,只要梯级条件跳变,计数器指令必定计数,然后经比较判断后给出状态位。
计数器是否计数不受状态位的影响,而计时器是否计时跟状态位紧密相关。
计数器有时用来记录产品的产量,如图5-23所示是一个产品数量计数器,每当产品通过时触发感应器,感应器状态位Touch_Bit作为计数器的梯级条件发生跳变,计数器就计数一次。当计数需要重新开始,可由操作员的外部操作来清零计数器,只要在人机界面设置针对位标签Reset_Counter_Products按钮操作便可得到复位的梯级条件。同时,计数器的累加值也可以送到人机界面显示。
图5-23 产品数量计数器
按照计数器指令的工作过程,通常的情况下,计数器指令前面必定是要一个梯级条件来作为计数的脉冲,可是一个例程中却看到了一个没有梯级条件的计数器指令,甚至连预置值都没有设置,如果这个例程正在运行,你会看到计数器在飞快地在计数!这真令人不解!如图5-24所示。
图5-24 无计数脉冲触发的计数
这时,你不妨使用一下编程软件的搜索功能,可能在离这个梯级的很远之处,或者根本就在例程末端处,你会看到一个这样的梯级,如图5-25所示,原来躲在暗处一直给计数器指令复位的就是它。这回,你总算看透了计数器,只要它的状态位使能被触发就会计数。原来,提供一个正向脉冲梯级条件使能计数器和复位计数器的常使能位,对计数器产生的作用都是一样的。这个例子编程实现的显然是在计算例程被扫描的次数,因为这样的复位方式让计数器指令所在梯级每逢扫描就会加1,无条件的梯级是每次扫描都会执行的。
图5-25 计数器使能复位
计数器不尽然都是用来计数的,也可以利用它不断变化的累加值来达到某种目的。例如某个自动控制系统中,有一个主控制器和多个从控制器,为了保证它们的联动准确无误,必须让每个从控制器时刻了解主控制器的工作状态,确定主控制器正在运行中。因此,主控制器需要发出一个连续变化的数据作为脉搏信号让从控制器读知。不妨采用一个计数器来产生这个连续变化的数据,就用刚才的方法,编写梯级逻辑如图5-26所示,计数器的预置值没有确定的意义,仅仅是为了让数据连续变化的重复,即使没有设定预置值也不会影响计数器的连续计数,到一定的时候,累加值自然会溢出翻转。
图5-26 产生连续变化的数据的梯级逻辑
计数器指令所在的梯级每次被扫描时,会完成加1的操作,如果设定预置值,并令完成位DN位置位时复位计数器,此时运用趋势曲线Trend来观察计数器的累加值Counter_RUN.ACC,可以观察到一个锯齿波的图形,如图5-27所示。关于趋势曲线显示组态的详细介绍,可参考《ControlLogix系统实用手册》一书。
图5-27 一个锯齿波的图形
如果觉得每次扫描计数累积太快,不妨用一个位分频来产生计数脉冲,分频的梯级逻辑编写如图5-28所示。注意看第一个梯级,自动地实现了0和1的翻转,在早期的程序中这种方式常被使用,也许是深受硬件方式的影响,这分明就是触发器的翻转动作,也许是当时太注重节约内存,或者是特别喜欢用位来完成一些技巧性的编程。观察这个位指令变化的梯级,总会折服于它的简单和精巧,显然每两次扫描将会产生一个计数脉冲。如果想要再一次分频,只须对这个地址再增添同样的一个梯级,重复一次这样的操作,计数器使用最后一个结果的变化位即可。(www.xing528.com)
分频产生的计数脉冲,给计数器提供了触发条件,连为计数器复位的梯级也可免去。
图5-28 分频的计数
同样采用趋势曲线监视这个计数脉冲分频后的计数器累加值数据,可以看到更为稀疏的锯齿波形,频率正好是原来的一半,如图5-29所示。
图5-29 分频后的锯齿波形
如果我们想要得到一个可逆的双向计数器,编写如图5-30所示的梯级逻辑即可,虽然我们一直强调,不可重复使用标签地址,否则将出现不可预料的结果,但是在这个例子中你可以看到,我们正是利用增计数指令和减计数指令两个不同的梯级条件跳变,共同修改同一个计数器结构数据标签,才实现了可逆双向计数器的功能。无独有偶,类似的例子在后面的章节中堆栈数组处理还能再次见到。
增计数和减计数是不同的梯级条件,更不能同时跳变,否则计数器的累加数将看不到变化。
图5-30 可逆计数的梯级逻辑
再看一个比较特别的实例,这是满足人机操作界面的一个下层处理,设定固定的设置值。在控制器中编写梯级逻辑如图5-31所示。
当人机界面PB按下按钮时,计时器开始计时,计时器的预置值时间作为操作的滞留时间,计时器完成位提供了一个计数脉冲,计数器加1。对于外部来说,按住设置按钮,设定一个预期的数值,这个数值设置成功后被反馈到人机界面PB的屏幕上,让操作员看到被设定值后松开设置按钮。此处计数器的预置值没有使用意义。
图5-31 设定固定设置值的梯级逻辑
后面梯级的两条MOV指令分别传送了两个不同的设置值,它们的梯级条件是计数器的ACC值的最低位,作为不断计数的累加值也遵循二进制的计数规则,每增加1,此位要翻转一次,一次为0,一次为1,轮番交替。ACC值最低位的0和1的状态为两条MOV指令提供了不同的梯级条件,输入位指令一个是常开另一个是常闭。
这样区分了两种设置值的设定情况,对于操作员来说,他所感受的是每当他按下按钮时,就会显示出他选定的设置值,只有两个数据供他选择,他可以翻转着寻找。0.2s的滞留时间对于操作员来说,只是按了一下按钮,即使按住更长的时间,也不会影响操作的结果。这种做法是可以类推到多个选择的,至少我们知道,原来我们使用的选择参数界面,底层有着如此的处理。
这段摘抄的梯级逻辑,初看时我也感到有点疑惑,既然是人机界面的按钮操作引起计数器计数,然后用计数器的ACC值去区分两种操作,为何不直截了当地将按钮作为计数器梯级的条件呢?细比之下,惟一的差别在于,这样的做法在操作上是有点延时的,也许在这个实例中,需要一点儿延时,于是采用了这个方式。也许这是出于保护的目的,这样人机界面偶尔的一次触碰是不会改变数字设置的,只有操作员有意地停留延时时间,才有数据重设的结果。正如我们操作手册上写着的,按住按钮1s,更换设置数据,诸如此类。
从另外一个方面来看,这是一个通信极为节约的方式,只要一个按钮的通信,就解决了多个设置,如果每个按钮对应一个设定值,就需要多个通信连接了。早期由于资源的紧缺,在节约上真是不遗余力地施展技巧。也许现在的编程无须这样追求节约资源,改为直截了当的通信,让更多的人更容易明白编程者的意图。抑或这根本就是一个早期的人机界面操作的处理模式,一个流传至今的巧妙的翻转选择数据的方式。
不管怎么样,作为学习者愿意看到更多样式的梯级逻辑执行形式,这对我们解读前辈们编写的程序大有好处。如今前辈们编写的程序还大量地运行在系统中,作为系统维护人员的新手们需要了解各种各样的思维模式。我们不采用这种编程方式并不等于我们不要了解这种编程方式。
有时看上去笨拙的处理,却是现场调试的结果,有些动作处理在逻辑上是很简单的,但在现场实施却因硬件或机械的限制,或者现场信号的原因,我们不得不改用妥协的处理方式。
图5-32 亮灯的变化过程
这里再例举一个比较原始的编程方式,了解一下过去是多么地喜欢利用位来操作。这是利用计数器的累加值ACC的二进制数的特征来编写的梯级逻辑,需求是要实现一个这样的亮灯变化过程,如图5-32所示。设整个周期时间是7s,2s后右边的两盏灯亮,过2s后左边的两盏灯亮,再过3s后4盏灯全亮。
根据需求编写梯级逻辑如图5-33所示,这原本是早期的一道计时器的训练题,利用时基为1s的计时器ACC值的位状态来编写梯级条件的逻辑,由于Logix控制器没有时基为1s的计时器,改为计数器来做,不过,利用ACC值的位状态编程,在道理上是一样的。
这属于不规则的时间动作,采用ACC二进制的识别方式,不需要用多个计时器来完成,一个ACC值就可以分辨出几个时间点,并在时间点上执行相应的动作。ACC值低三位所表达的7s的二进制以及在数轴上3个时间点的表达如图5-34所示。
选择任意3个时间点,使得它们满足2s、2s、3s的变化规律。完整地表达这3个时间点应该是3位二进制位状态,考虑本例中我们只用到3个时间点,各用2位便可令它们不冲突,故使用的位状态如图5-33中的梯级逻辑所示。这种方式特别适合不规则的时间点操作。
图5-33 根据需求编写的梯级逻辑
点灯的动作也是可以讨论的,每次点两盏灯或者4盏灯,点两盏灯,用位指令设定也未尝不可,点4盏灯用位指令就有点累赘了,不如用MOV指令传送给4个位。
图5-34 ACC值低三位7s的二进制以及在数轴上3个时间点的表达
MOV指令是直接传送立即数,可以借助于数据表的数据形式换算出来,先将一个双整字打开,改变成二进制的数据形式,将相应位置成1后,改为十进制的数据形式,这就是将要对MOV指令的目标地址传送的立即数。请注意MOV指令传送的立即数是十进制数。采用这样的方法,不管传送的双整字的状态位是多么的没有规律,总能换算出要传送的立即数。
顺便提及,计数器的ACC值的最低位,有时也用作奇偶判断,这正是二进制计算机特征的实用价值,刚才谈论的人机界面的设置实例,就是利用的奇偶关系。早期的工程师们似乎更在意我们使用的是一个二进制的计算机,对寄存器的依赖性更强,谋求了不少位状态编程的利用价值。如今的编程人员过度地依赖计算机的智能形式,反而对计算机最原始的本质视而不见,编程风格也就迥然不同了。
早期PLC的计数器还担任了一个重要的任务,就是用来管理文件操作指令,批量数据的处理需要设置文件的长度和记录正在执行当中的位置(称为指针),在第二代产品PLC5/SLC500中演变为文件操作指令专用的控制器文件,在Logix控制器的指令系统中,则称为控制结构数据,也就是下面章节我们将要学习的数组操作指令中用到的控制结构数据标签。控制结构数据所表现的特征跟计数器结构数据是极其相似的,乃至控制结构数据指针的增加和减少的触发也呈现了计数器的本性,充分理解计数器的工作原理,有助于我们今后学习数组操作指令时对控制结构数据的运用。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。