quote:以下是引用yanxiao在2011-05-23 07:14:28的发言:
我从这个测试中,弄明白一件事:定时器当前值清零,可以用复位,也可以直接送0,但是有点区别。复位(R和TON使能为0)就是让定时器回复到停止状态,因此第一次执行定时器指令时,仅作启动,会忽略当前周期的100ms时间增量;而直接送0,并未使定时器回到停止状态,因此送0后的第一个定时器指令,不会忽略当前周期的100ms定时器增量。
这个结论没多少实践意义,对于100定时器的使用,我们需知道一它不是实时更新的,二存在首尾非整数时间单位的问题(可能产生100ms和扫描周期中较大者的误差)。所以定时器要根据精度要求降级使用,如要求100ms的精度,至少应该使用10ms的定时器。100ms的定时器,应该应用于秒级定时,比如按某键延时5秒才能执行其它动作,那这个延时是4.9还是5.1是不重要的。
对于100ms的定时器系统后台大概可以抽象成如下代码:
系统初始化
...
if(启动上升沿)
{
状态 = ON;
复位定时器(当前值=0, 定时位=OFF); // TON
}
else if( 启动位下降沿 ) // 文档支持
{
状态 = OFF;
复位定时器;
}
else if( 状态 == ON )
{
if( 复位指令 ) // 文档支持
{
状态 = OFF;
复位定时器;
}
else
{
if(当前值 < 最大值 )
当前值=当前值 + 去尾取整(已逝去的时间单位); 定时位 = 当前值 >= 预置值 ? ON : OFF;
}
}
这个抽象结构跟后台程序功能应该大同小异,只是结构安排上可能会有差别。
对于是否会“
忽略当前周期的100ms定时器增量”,跟设计者的当初的思路有关,比如上面这个抽象结构中红色的 else 是否存在,就会影响这个结果。
无论我们现在测试的结果是什么,对于这种un-document的东西,都不能作为普通准则应用,只能针对性临时使用。作为软件设计者,我们经常需要un-document某些东西(某性能或用法存在,但文档中不会说明),就是因为这个设计可能随时会变更或不再支持。而对于文档中已经说明的东西,则很少会改变,即使软件升级或底层设计方法改变,只要可能,都会兼容文档的说明。作为最终用户,应该尽可能避开un-document的东西。
跑题了,回来说定时器,从这个抽象结构可以看出,标准的复位是
OFF启动位或复位指令。
“送0复位”是非结构化的,是人为的介入定时器的运行状态,它具有类似“复位”的效果(
当前值=0),但不能将它当常规复位方式来用。因为定时器不是实时更新的,定时器位并不会跟着OFF,要等到扫描到定时器时才会更新。如果扫描周期很长,而定时预置值很小(比如1),从抽象结构上看,定时位可能永远不会OFF。