有毫秒和毫秒,一个很容易,另一个很难。
我们运行一个 1ms 的硬件定时器中断循环来处理必须在实体光栅上运行的东西(例如电机控制)。我们从这个例程中增加一个全局的 32 位“滴答”值,然后可以用来对需要以亚秒间隔发生的事情进行计时(例如,每 50 毫秒轮询一次)。
这与使用微型硬件计时器作为计时参考不同,在这样的系统中,任何东西的准确性都存在问题 - 从时钟晶体的准确性到所有各种预分频器、中断延迟等。现在,我们不在乎我们的电机控制程序是每秒运行 999 次还是每秒 1001 次,或者我们是否每 49.5 毫秒而不是 50 毫秒轮询一次引脚的状态,因为它已经足够接近了,重要的是它发生在及时。在 24 小时的过程中,我们最终可能会收到比一天中毫秒数还多的“滴答声”,这会导致手表很糟糕。
例如 - 时钟预分频器计数到 N 然后复位,还是 n-1 并复位?它是立即重置还是需要一个时钟周期?这种细节在微观上让人头疼。
我会使用 RTC 作为时间参考,然后可能将 ms 计数器与秒的滴答声同步(每 1Hz RTC 中断将“滴答声”重置为 0),这意味着您的 ms 值只会非常相对于 RTC 略微偏离。您甚至可以直接读取 RTC 的输入时钟寄存器,以提取运行 RTC 的更快时钟(通常为 32.768kHz 时钟)。我们这样做是为了从 1kHz 定时器的预分频器时钟寄存器中获取微秒值。它并不完美,我们不使用它来保持时间,仅用于捕获 sub-ms 事件。
或者,看看你的应用程序是否真的需要毫秒,或者你是否可以在 100 毫秒内编出一个数字并报告,这不像 JS 是原子钟级计时明智的 - 它甚至不是米老鼠 -手表级。如果你真的需要这种准确性,那你就错了。