Embedded 我如何在没有累积误差的情况下保持时间?

Embedded 我如何在没有累积误差的情况下保持时间?,embedded,idioms,Embedded,Idioms,在一个简单的嵌入式系统中,如果您需要以秒为单位的时间的定点表示,并且计时之间的时间不能以定点格式精确表示,您如何跟踪时间?在这些情况下,如何避免累积错误 这个问题是对slashdot的回应 0.1秒不能精确地表示为二进制定点数字,正如1/3不能精确地表示为十进制定点数字一样。任何二进制定点表示都有一个小错误。例如,如果该点后有8个二进制位(即使用按256缩放的整数值),则0.1乘以256等于25.6,将舍入为25或26,分别导致-2.3%或+1.6%的误差。在点之后添加更多的二进制位可以减小此错

在一个简单的嵌入式系统中,如果您需要以秒为单位的时间的定点表示,并且计时之间的时间不能以定点格式精确表示,您如何跟踪时间?在这些情况下,如何避免累积错误

这个问题是对slashdot的回应

0.1秒不能精确地表示为二进制定点数字,正如1/3不能精确地表示为十进制定点数字一样。任何二进制定点表示都有一个小错误。例如,如果该点后有8个二进制位(即使用按256缩放的整数值),则0.1乘以256等于25.6,将舍入为25或26,分别导致-2.3%或+1.6%的误差。在点之后添加更多的二进制位可以减小此错误的规模,但无法消除它

重复相加,误差逐渐累积


如何避免这种情况?

一种方法不是通过重复添加0.1秒常数来计算时间,而是保持一个简单的整数时钟滴答数。根据需要,此滴答计数可以转换为以秒为单位的定点时间,通常使用乘法和除法。如果中间表示中有足够的位,这种方法允许任何合理的缩放,并且不会累积错误


例如,如果当前滴答数为1024,我们可以通过将当前时间乘以256,然后除以10,或者等效地乘以128,然后除以5来获得当前时间(在固定点中,该点后有8位)。无论哪种方式,都存在误差(除法中的余数),但由于余数始终小于5,因此误差是有界的。没有累积误差。

在整数乘法和除法被认为代价太高的情况下,另一种方法可能会很有用(现在这种情况应该越来越少了)。它借用了我的一个想法。您可以将当前时间保持在固定点(而不是刻度计数),但也可以保留一个错误项。当错误项增长过大时,将对时间值应用更正,从而防止错误累积

在点后8位示例中,0.1秒的表示为25(256/10),错误项(余数)为6。在每个步骤中,我们向错误累加器添加6。基于此,目前为止,前两个步骤是

Clock  Seconds  Error
-----  -------  -----
 25    0.0977    6
 50    0.1953   12
在第二步,错误值已溢出-超过10。因此,我们增加时钟,从误差中减去10。每次错误值达到10或更高时都会发生这种情况

因此,实际的顺序是

Clock  Seconds  Error  Overflowed?
-----  -------  -----  -----------
 25    0.0977    6
 51    0.1992    2      Yes
 76    0.2969    8
102    0.3984    4      Yes

几乎总是存在误差(只有当误差值为零时,时钟才准确无误),但误差由一个小常数限定。时钟值中没有累积误差。

唯一的硬件解决方案是安排硬件时钟滴答声的运行速度稍微快一点-精确到足以补偿重复添加的滴答声持续时间值的舍入所造成的累积损失。也就是说,调整硬件时钟滴答声速度,以便定点滴答声持续时间值准确无误


这仅在时钟使用一种定点格式时有效。

为什么不使用0.1秒计数器和每十次递增的秒计数器,并将0.1计数器包装回0?

在这种情况下,我只需将时间计数保持在十分之一秒(或毫秒,或任何适用于应用程序的时间刻度)。我总是在小型系统或控制系统中这样做

因此,100小时的时间值将存储为
3_600_000
ticks-zero error(硬件可能引入的错误除外)

这种简单技术带来的问题有:

  • 您需要考虑较大的数字。例如,您可能必须使用64位计数器而不是32位计数器
  • 所有的计算都需要知道使用的单位-这是最有可能导致问题的区域。我尝试通过使用统一单位的时间计数器来帮助解决这个问题。例如,这个特定计数器只需要每秒10个刻度,但另一个计数器可能需要毫秒精度。在这种情况下,我会考虑der使两个计数器都达到毫秒精度,因此它们使用相同的单位,即使其中一个并不真正需要该精度
我还不得不对非“常规”计时器玩一些其他把戏。例如,我在一台设备上工作,该设备要求每秒进行300次数据采集。硬件计时器每毫秒触发一次。无法缩放毫秒计时器,以获得精确的1/300秒单位。因此,我们必须有能够每3、3和4个刻度执行一次数据采集,以防止采集漂移


如果您需要处理硬件时间错误,那么您需要多个时间源,并将它们一起使用以保持总体时间同步。根据您的需要,这可能是简单的,也可能是相当复杂的。

我在过去看到的实现:增量值不能以定点格式精确表示,但可以是e表示为分数。(这类似于“跟踪错误值”解决方案。)

实际上,在本例中,问题稍有不同,但概念上类似。问题并非固定点表示,而是从并非完美倍数的时钟源中派生计时器。我们有一个硬件时钟,其滴答声为32768 Hz(常见于基于手表晶体的低功耗计时器).我们想要一个毫秒计时器

毫秒计时器应每32.768个硬件刻度递增一次。第一个近似值是每33个硬件刻度递增一次,标称误差为0.7%。但是,请注意