Timer 在没有高/低字节锁存器的8位系统上读取16位计时器

Timer 在没有高/低字节锁存器的8位系统上读取16位计时器,timer,microcontroller,c99,Timer,Microcontroller,C99,我有一个计时器,我定期使用它来收集性能值。 现在,我已经看到,有时候,我得到的值比之前采样的值要低 我发现这一行为可以追溯到我的行为: 1) 读取较低的字节 2) 读取高位字节 value=upper首先,我要检查计数器值在读取高字节或低字节时是否锁存。很多计时器都有 您的第二种方法(读取计数器两次)是有希望的,但如果可能,请删除计时器第一次和第二次读取之间的任何计算,然后再进行所有计算。您还需要检查高字节环绕(从255到0)是否也是一个问题 如果您在问题中说明了您使用的是什么8位控制器和计时器

我有一个计时器,我定期使用它来收集性能值。 现在,我已经看到,有时候,我得到的值比之前采样的值要低

我发现这一行为可以追溯到我的行为:
1) 读取较低的字节
2) 读取高位字节


value=upper首先,我要检查计数器值在读取高字节或低字节时是否锁存。很多计时器都有

您的第二种方法(读取计数器两次)是有希望的,但如果可能,请删除计时器第一次和第二次读取之间的任何计算,然后再进行所有计算。您还需要检查高字节环绕(从255到0)是否也是一个问题


如果您在问题中说明了您使用的是什么8位控制器和计时器,这将非常有帮助,因为人们可以通过查看数据表和手册给出更具体的建议,您可以将第一种方法展开两次迭代,这样您就可以

__DI();
upper1 = CounterH;
lower1 = CounterL;
upper2 = CounterH;
lower2 = CounterL;
__EI();
if ( upper1 == upper2 )
{
    // use lower1, upper1
}
else
{
    // use lower2, upper2
}
这里假设如果
计数器在读取
upper1
upper2
之间溢出,则在读取
upper2
lower2
之间不会再次溢出


由于中断在分配块周围被禁用,因此它应该总是足够快,即使对于8位计数器也是如此。

通常,在读取数据时,您会暂时按住计时器,这样它就不会在低读和高读之间更新。停止计时器很有意义。通常您不想停止计时器,例如,如果它被用作时钟。@starblue:对。它甚至被设计成这里的时钟。我正在考虑在重新启动之前再添加损失的时间。当然,这只有在CPU以定时器频率的倍数运行时才可能实现。计时器停止时执行的操作码数量必须固定且已知。如标题中所述,没有/可能没有闩锁。谢谢你指出了环绕问题。我想为大学课程创建一个示例驱动程序,其中计时器由学生编写(是否锁定是他们的选择)。这应该是某种(防弹的)示例例程。因为我会提供给学生,我不想告诉他们太多的垃圾;)许多制造商似乎建议“只要不发生溢流就可以取样”,我称之为“溢流”。
__DI();

upper =  CounterH;
lower =  CounterL;
value1 = upper<<8 + lower;

upper =  CounterH;
lower =  CounterL;
value2 = upper<<8 + lower;

value = max(value1, value2);

__EI();
__DI();
upper1 = CounterH;
lower1 = CounterL;
upper2 = CounterH;
lower2 = CounterL;
__EI();
if ( upper1 == upper2 )
{
    // use lower1, upper1
}
else
{
    // use lower2, upper2
}