我应该多久查询一次 RTC?

电器工程 微控制器 实时时钟
2022-01-15 18:22:46

我还没有使用 RTC,所以我不完全确定读取实时时钟的“正常”方式。我想到了几种不同的方法,但希望得到一些建议。

到目前为止,我想到的阅读和使用时间的方法如下:

  1. 在通电时获取日期和时间并保存到 RAM,然后通过使用定时器中断每秒递增 RAM 值等。然后,代码将在需要知道日期/时间时使用 RAM 中的值。
  2. 通过使用定时器中断,每秒查询 RTC 并将接收到的日期和时间复制到 RAM。同样,代码将在需要知道日期/时间时使用 RAM 中的值。
  3. 每次我需要找出时间时,查询 RTC 并直接使用它的响应。

哪个是最好的方法?

4个回答

我会使用第四个选项。

大多数 RTC 芯片都有输出 1 秒脉冲的选项。您应该将该脉冲连接到 MCU 上启用中断的输入。

  • 您在程序开始时从芯片中获取一次时间,从那时起可能偶尔会 - 可能每小时一次。
  • 然后,中断信号会触发 MCU 中的中断例程,在该例程中将时间增加一秒。

这种安排使您可以精确到第二个RTC,而无需主动读取 RTC。

第3和第2更可行。

第三种方法是我在大多数情况下使用的。这样做的好处是我不必担心在 RAM 中镜像 RTC。它的潜在缺点是通过串行总线询问 RTC 会引入延迟。如果您每秒写入一次数据,则此延迟可能无关紧要。

第二种方法也很好。如果设备长时间运行,维护镜像时钟可能会引入计时错误。镜像时钟可能会偏离 RTC。如果您定期阅读 RTC,则漂移不会累积。
但是,我建议不要在中断服务例程 (ISR) 本身中进行串行通信。在 ISR 中设置一个标志并在 main() 中进行串行通信。

ps 在所有情况下,我都使用 DS1307。

一些 RTC(例如 MC68HC68T1 [公认几乎没有人应该再使用])在读取时会暂停其内部计数,以便给出一致的响应。必须尽可能少地读取它们,以最大程度地减少干扰。从它们读取一次,然后使用定时器中断来更新存储在 MCU 的 RAM 中的时间值。

我将假设 RTC 是具有自己的晶体的单独芯片,或者是与您的微控制器集成的模块,该模块再次具有与主时钟不同的时间源(例如 32 kHz 晶体)。RTC 的时间源比微控制器的时间源更准确。

要确定读取 RTC 的频率,您需要确定主时钟的最大误差。例如,如果主晶体指定为 20 ppm,则与 0.002% 相同。因此,仅基于主时钟源的时钟每天可能漂移 0.00002 * 3600 * 24 = 1.728 秒。

因此,如果您每天只读取两次 RTC,并且在这期间使用定时器中断每秒增加一次时间,那么您的关闭时间永远不会超过一秒——与 RTC 相比,您的关闭时间永远不会超过一秒。

如果,正如我之前假设的那样,您的 RTC 要么是带有自己的晶体的独立芯片,要么是与您的微控制器集成的模块,这并不意味着它是正确的。RTC 也可能有错误。例如,如果它使用容差为 5 ppm 的 32 kHz 晶振(仅比 10 ppm 的贵一点),它可能每天关闭 0.43 秒 - 或每月 13 秒。

为了解决这个问题,您需要调整 RTC,将校正因子写回寄存器。这样做可以让您将误差几乎为零。但当然,在进行调整时,您必须使用第三个外部时钟源作为参考。在美国,一个极其准确的参考是 60 Hz 交流线路,它保证在连续午夜之间的 24 小时周期内精确为 60*60*60*24 (5,184,000) 个周期要使此功能有用,您必须对整个 24 小时进行计时,因为 60 Hz 可能会在午夜之间漂移一些。

如果项目中已经有 GPS 硬件,另一个出色的时间参考是使用 GPS(10 ns 精度)。

相反,如果您的 RTC 时间来自外部来源,例如蜂窝网络时间(AT+CCLK? 调用)或使用 NTP 的网络时间服务器,那么您可以按原样使用 RTC 值,因为没有什么可以“调整” .