我们日常编程中在使用定时器后,发现定时器并没有按照自己的意图去计时,出现了不计时的错误,进而怀疑是否是硬件故障,CPU是否正常等等,浪费了很多的时间去排查,实际上就是由于我们对定时器的特性不了解所造成的误解,下面我们来看看几个例子:
![245e4ad2b065eb614d4df1b1d43f093a.png](https://i-blog.csdnimg.cn/blog_migrate/bab84115407e01443da31396c025f7b2.jpeg)
程序设计的本意是:I4.2的上升沿触发T50和T60定时器,并在T60定时结束后复位M12.0。
可是在仿真发现,I4.2可以触发T50和T60定时器,但有时即使I4.2再次将M12.0置位为1,但T50不计时,现象如下图:
![245e4ad2b065eb614d4df1b1d43f093a.png](https://i-blog.csdnimg.cn/blog_migrate/bab84115407e01443da31396c025f7b2.jpeg)
问题分析:首先明确不是硬件故障,也不是语句错误引起的,而是定时器使用不正确引起的:
1 某个扫描周期:I4.2的上升沿置位M12.0,I4.2恢复为0
2 数个扫描周期后,假设第N个扫描周期,当T60计时到时,网络2中的M12.0被复位(注意在SD T50语句的后面),此扫描周期末M12.0由1变为0。网络3中的T50和T60被复位。
3 在第N+1个扫描周期,如果此时I4.2恰好出现上升沿,尽管M12.0在上个扫描周期曾经变为0,但在本周期开始就变为了1,定时器T50在上个扫描周期接受到M12.0状态为1,定时器T50在本扫描周期接受的M12.0的状态也为1,所以T50不会工作。
定时器的错误分析如下图所示:
![df01699b0f089cb38833b91761babb88.png](https://i-blog.csdnimg.cn/blog_migrate/d2b4d17b17507490b625a468c960e186.jpeg)
定时器的正确使用应如下图所示:
![d8ada459ef933c7b6ec60fe54962541d.png](https://i-blog.csdnimg.cn/blog_migrate/67963f7b74c2fa2a04465d8eedc1cb08.jpeg)
说的再明白些就是定时器的使用在扫描周期N和N+1之间正确接收到上升沿的变化,这样定时器才会正确工作。
本例中的故障很隐蔽,在我们使用中可能几天运行都不会有定时不工作的情况,突然偶尔出现一次,排查起来很费劲,所以在我们编程中要遵守定时器要想计时工作必须接收到输入端上升沿的变化。
那么遇到这种情况应该怎么改呢?
小编这里提供个思路:可以在置位M12.0之前增加一些限制条件。
另外要说的就是定时器的定时与程序扫描周期
在S7系列CPU中,定时器的最小时基为10ms,也就是说,S7CPU的最小定时时间为10ms,如果用户程序的代码量比较大,程序扫描周期过了10ms可能会出现如下情况:尽管定时时间已经到了,但CPU还没有执行到相关的程序逻辑。
针对这种情况:当用户程序需要非常短的定时功能时,需要考虑程序扫描周期对定时器状态读取的影响,由于CPU中的定时中断是由硬件来保证的,并且高于0B1的优先级,所以这种情况下,考虑使用定时中断功能来替代定时器的功能。
另外的问题就是当编程时遇到CPU提供的硬件定时器不够用的时候,这时候可以使用系统提供的软定时器,例如SFB4,此功能块需要一个背景数据块。
![2849b487b4f67c34f8d291148048f421.png](https://i-blog.csdnimg.cn/blog_migrate/594d59e712a811d6ae9f970621a60e9d.jpeg)
时序图如下:
![a963fca44594416c12d2acefaf55693e.png](https://i-blog.csdnimg.cn/blog_migrate/a31a929eb6e85783861058ca3ab2df3f.jpeg)
在使用SFB4的时候要注意的一个问题就是CPU重启后软定时器复位的问题。
由于SFB的定时,计时值存在DB中,由于CPU断电或停机后,DB数据时保持的,如果定时器计时到在停机前已经计时,那么当CPU重新运行后(定时器输入端仍然为1的情况),定时器将会在原来计时位置继续计时,为了避免这种情况的出现,可以在0B100中添加如下语句来初始化SFB4的背景数据块
![1ab8a7cf9119a85721a68dee73ae1c2a.png](https://i-blog.csdnimg.cn/blog_migrate/11f1696cc8e91dd794bfe84b82896974.jpeg)