RP2040 RTC 寄存器深度解析:SETUP、IRQ、INTF 寄存器的功能与配置
树莓派 Pico 中的 RTC 外设介绍
树莓派 Pico 的 RTC 外设中时间以二进制的形式存储,以七个字段分开:

需要注意,这七个字段可读可写,在写入时需要注意写入的时间范围,RTC不检查已编程的值是否在该范围内。非法的值可能会导致意外的行为。
同时,工作日被表示为从星期天(Sun)开始的数字编码:Sun=0,Mon=1,...,Sat=6,这种编码方式称为 ISO 8601 标准的 mod 7(即七模)。RTC 不具备内置的日历功能,因此它不会自动计算一周的正确日期,而是简单地递增当前的数值。例如,如果当前是星期一(1),那么下一个周期将是星期二(2),依此类推。
我们可以通过读取 RTC_0 寄存器和 RTC_1 寄存器来获取当前时间:

也可以通过 SETUP 寄存器设置当前时间:

1.RTC 时钟输入

在 RP2040(Raspberry Pi Pico)的 RTC 外设中,使用的参考时钟是 clk_rtc,其频率可以在 1 到 65536Hz 的任意整数范围内。内部 1Hz 的参考时钟是通过内部的时钟分频器生成的,该分频器将 clk_rtc 的频率除以一个整数值。这个整数值减 1 后设置在寄存器 CLKDIV_M1 中:

需要注意的是,不建议在RTC启用时更改CLKDIV_M1的值,这会改变 RTC 的时钟频率,进而影响秒、分、时等时间单位的准确性,导致 RTC 的时间计时出现偏差,对于一些对时间精度要求很高的应用场景来说是不可接受的。
clk_rtc 可以由内部或外部时钟源驱动,并且可以通过分数分频器进行预分频:
- XOSC @ 12MHz / 256 = 46875Hz:此时要获得 1Hz 的参考时钟,
CLKDIV_M1应设置为 46874,默认使用 12Mhz 的外部晶振, - 来自 GPS 的外部参考:这种情况下,GPS 生成每秒一次脉冲,
clk_rtc配置为从 GPIO 引脚 20 的 GPIN0 时钟源运行,此时clk_rtc的分频器为 1,内部 RTC 时钟分频器也是 1(即CLKDIV_M1为 0)
所有 RTC 寄存器的读写操作都在处理器时钟域 clk_sys 中进行,并且数据在不同的时钟域之间来回同步。这意味着,当写入 RTC 寄存器时,操作并不会立即生效,而是需要经过两个clk_rtc周期才能完成同步和更新。因此,在使用较慢的参考时钟(如 1Hz)时,必须特别考虑到这一点。较慢的时钟速度会导致数据更新的延迟,因此在设计和实现 RTC 功能时,必须确保这一点不会对系统的时间精度产生不利影响。
这里,树莓派 Pico 使用的晶振为 AEL(Advanced Electronics and Logistics)公司生产的 12MHz 贴片晶振:

具体的数据手册我们并没有找到,但是对比了国产平替的扬兴 X322512MSB4SI 晶振:

预计其频率精度不大于 ±30 ppm,即在一天之内的最大时间误差可能为约 2.6 秒。
2.闰年检测
在 RTC 的 SETUP_0 寄存器中,如果年份值数据位 YEAR 能被 4 整除,则会被检测为闰年。在这种情况下,2 月 28 日之后会自动变成 2 月 29 日,而不是 3 月 1 日:

但是,这种简单的 4 年一闰的规则并不总是正确的,比如对于世纪年(如 2100 年)就不适用。为了解决这个问题,RTC 提供了一个 CTRL.FORCE_NOTLEAPYEAR 位,用于强制关闭闰年检查:

具体来说,RTC 只会在 2 月 28 日 23:59:59 时进行闰年检查。如果开发者确定某个年份不是闰年,可以在那个时间点之前设置 FORCE_NOTLEAPYEAR 位,强制将 2 月 29 日跳过,直接变为 3 月 1 日。
这种强制关闭闰年检查的功能很有用,尤其是对于 2096 年 3 月 1 日之后的年份。因为在 2100 年 2 月 28 日 23:59:59 之前,开发者需要提前设置好 FORCE_NOTLEAPYEAR 位,以确保 RTC 能准确地处理非闰年的情况,并避免时钟域交叉带来的延迟问题。
3.中断功能
RTC 可以在配置的时间点生成中断。在 IRQ_SETUP_0 寄存器中有一个全局使能位 MATCH_ENA,用于开启这个中断功能:

同时,RTC 还提供了针对每个时间字段(年、月、日、星期、时、分、秒)的单独使能位。开发者可以选择性地开启某些时间字段的中断使能,实现在指定时间产生重复性中断:


同时,我们可以通过读取 INTR 寄存器获取 RTC 原始中断,通过读取 INTS 寄存器获取 RTC 掩码中断:

也可以通过 INTF 寄存器强制触发 RTC 中断,通过 INTE 寄存器使能 RTC 中断:

当满足中断条件时,RTC 会向处理器发送中断信号,同时也会唤醒 ROSC(Ring Oscillator)和 XOSC(Crystal Oscillator)从休眠模式唤醒。总的来说,RTC 的中断功能非常灵活和强大。开发者可以根据实际需求,选择性地开启某些时间字段的中断,实现定时任务、报警等功能。同时,RTC 中断还可以用于唤醒处理器和振荡器,从而节省系统功耗。
4.RTC 唤醒功能
当设备进入低功耗模式时,RTC 外设可以继续工作并在预设时间到达时触发中断,从而唤醒设备:
- 树莓派 Pico 处于睡眠模式(
Sleep Mode):- 在此模式下,处理器会进入休眠状态,并且芯片中未使用的时钟会被停止
- 芯片在睡眠模式下可以配置为仅运行
clk_rtc(一个慢速的 RTC 参考时钟),以及一小部分逻辑以允许处理器唤醒 - 处理器会在 RTC 闹钟中断触发时从睡眠模式中被唤醒
- 树莓派 Pico 处于休眠模式(
Dormant Mode):- 在此模式下,芯片中的所有时钟都会被停止
- 要从休眠模式唤醒芯片,必须完成以下步骤:
RTC必须配置为使用外部参考时钟(通过 GPIO 引脚提供)- 设置 RTC 以运行在外部参考时钟上
- 如果处理器运行在
PLL(相位锁环)时钟下,则需将其切换到使用 XOSC/ROSC(外部振荡器/内部振荡器) - 关闭所有 PLL
- 配置
RTC以设置所需的唤醒时间(一次性唤醒或定期唤醒) - (可选)关闭大多数内存
- 调用
DORMANT模式

树莓派 Pico 的 RTC 外设中时间以二进制的形式存储,以七个字段分开:
浙公网安备 33010602011771号