ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

RP2040 RTC寄存器详解:SETUP、IRQ_SETUP与INTF踩坑指南

RP2040 RTC寄存器详解:SETUP、IRQ_SETUP与INTF踩坑指南 做嵌入式这么多年我很少为一个 RTC 熬夜但 RP2040 的 RTC 确实让我破例了。它没有独立备用电源域寄存器命名也和我们习惯的 STM32 不太一样SETUP、IRQ_SETUP、INTF 这几个寄存器第一次接触时很容易被绕进去。你照着 SDK 示例把时间写上去了读出来却是错的你配置了闹钟中断却压根不触发你清中断标志发现写 0 根本没反应。这篇记录把 RP2040 RTC 核心寄存器逐个拆开重点放在 SETUP、IRQ实际叫 IRQ_SETUP、INTF 三个寄存器上把它们的功能、配置顺序和容易踩的坑一次说清楚。适合正在用树莓派 Pico / RP2040 做低功耗计时、定时唤醒或日历功能的开发者也适合刚入门想搞懂 RTC 底层逻辑的朋友。1. 先搞懂 RP2040 RTC 的“特殊体质”不是所有 RTC 都有备用电池引脚1.1 RTC 的时间来源与分频链路RP2040 的 RTC 模块和 STM32 那种独立 RTC 有很大区别。STM32 通常有 VBAT 引脚主电源断了 RTC 还能靠纽扣电池继续走RP2040 没有类似设计它内部没有独立的 RTC 电源域也没有 VBAT 引脚。换句话说RP2040 的 RTC 掉电即丢失重新上电后时间会回到默认状态。这是设计低功耗产品时一定要提前意识到的问题。RP2040 的 RTC 想要在睡眠时继续跑核心是时钟源。RTC 的时钟来自clk_rtc它一路可以来自系统内部参考时钟另一路可以来自外部 32.768kHz 晶振。具体来说RP2040 的 XOSC 支持两种频率12MHz 和 32.768kHz。如果你用 32.768kHz 晶振在SLEEP甚至DORMANT模式下RTC 依然可以靠这个低频时钟继续计数如果只用内部 12MHz 时钟睡眠模式下 RTC 会跟着停走因为整个时钟树都断了。所以项目选型阶段就得决定你的设备是否需要“睡眠时保持时间”如果需要必须在硬件上预留 32.768kHz 晶振位置软件里也要把 XOSC 初始化成低频模式。这个决定越早做越好否则板子量产之后发现时间只能在上电期间走改板子的成本很高。1.2 RTC 寄存器地图SETUP / CTTL / IRQ_SETUP / INTF 是怎么咬合的RP2040 RTC 寄存器基址是0x4005C000从上到下依次排布偏移寄存器名一句话说明0x00RTC_SETUP_0写入日期年、月、日0x04RTC_SETUP_1写入时间时、分、秒0x08RTC_CTRLRTC 使能、加载时间、激活状态0x0CRTC_INTE中断使能寄存器0x10RTC_INTF中断标志寄存器写 1 清除0x14 ~ 0x30RTC_IRQ_SETUP_0~IRQ_SETUP_78 组闹钟匹配寄存器0x34RTC_IRQ_SETUP_XOR匹配 XOR 状态用于调试0x40 ~ 0x48RTC_CLKDIV_M0/M1/M2分频配置一般由时钟初始化流程设置把它们串起来理解RTC 的完整工作链路是这样的先通过RTC_SETUP_0和RTC_SETUP_1装载一个基准时间再把RTC_CTRL的使能位打开RTC 内部就开始以秒为单位累加。之后每一秒硬件会把当前时间和 8 组RTC_IRQ_SETUP里配置的“闹钟条件”做比较匹配上了就把RTC_INTF的中断标志位置 1同时向 NVIC 发出中断请求。RTC_INTE则控制这个中断是否被允许传递到处理器核心。所以 SETUP 负责“设定起点”IRQ_SETUP 负责“设定闹钟”INTF 负责“告诉 CPU 闹钟响了”。三者职责完全不同但都很容易因为寄存器名字相似而搞混尤其是 IRQ_SETUP 和 INTF 里都有“IRQ”字样实际一个是配置闹钟条件一个是中断状态标志。2. SETUP 寄存器写入时间不是“写进去就完事”还差一条 LOAD 命令2.1 SETUP_0 与 SETUP_1 的字段构成RTC_SETUP_0用来写日期包含年、月、日三个字段RTC_SETUP_1用来写时间包含时、分、秒三个字段。这些字段在官方寄存器定义里都有对应的宏比如RTC_SETUP_0_YEAR_BITS、RTC_SETUP_0_MONTH_BITS建议直接引用头文件里的宏不要自己硬编码位偏移。这里有一个非常反直觉的点这些字段的内容不是普通二进制数而是 BCD 码。BCD 的意思是“用 4 位二进制表示一位十进制数字”。比如十进制的 25普通十六进制是 0x19但 BCD 是 0x25。年份 2025 在 BCD 下是 0x2025月份 12 月是 0x12日期 31 日是 0x31。如果不做 BCD 转换直接把十进制值写进去比如年份字段直接写 2025最终读出来的时间会完全对不上。你在串口里看到0x07E9这种东西马上要反应过来这不是时间不对是编码方式搞错了。2.2 BCD 编码为什么 0x2025 不是正常的十六进制 2025很多新人会把 BCD 和十六进制混为一谈因为它们都长得像“数字加字母”。区别在于BCD 每个十进制位占 4 bit0x2025 在 BCD 下表示“20 年 25 年”的年份字段其实年份字段里写的是完整年份所以 0x2025 表示数字 2025只是每一位都被单独编码了。为了方便理解可以做一个简单的十进制转 BCD 操作对年份 2025把千位 2、百位 0、十位 2、个位 5 分别转成 4 bit2 - 0x20 - 0x02 - 0x25 - 0x5拼起来就是 0x2025。月份 12 月十位 1、个位 2拼成 0x12。秒 59 秒拼成 0x59。如果你想用代码做转换最直接的方式是按位拆static uint8_t dec_to_bcd(uint8_t dec) { return ((dec / 10) 4) | (dec % 10); } static uint8_t bcd_to_dec(uint8_t bcd) { return ((bcd 4) * 10) (bcd 0x0F); }需要特别注意的是年字段在 RP2040 的数据手册中是一个 12 位字段能表达的范围比普通 BCD 大很多。普通 BCD 年份 0x2025 在这个 12 位字段里是放得下的但如果你用 16 位寄存器操作时不小心把其他位也带进去了可能会污染月份字段。所以写寄存器的时候一定要先读回当前值再按位或上目标字段或者直接用 SDK 提供的数据结构。2.3 正确写时间的完整序列SETUP → LOAD → 等待SETUP 寄存器写完之后时间并不会立刻生效。还需要往RTC_CTRL的 LOAD 位写 1硬件才会把 SETUP 里的值真正加载到 RTC 内核计数器。这一步是很多人第一次调 RP2040 RTC 时最容易漏掉的。LOAD 位的特点是写 1 触发加载加载完成后硬件会自动清零不需要软件再写 0。所以正确的初始化序列是使能 RTCRTC_CTRL.RTC_ENABLE 1。等待 RTC_CTRL 的RTC_ACTIVE置 1确认 RTC 开始工作。设置RTC_SETUP_0和RTC_SETUP_1填入 BCD 格式的年月日时分秒。设置RTC_CTRL.LOAD 1触发时间装载。稍等片刻然后用rtc_get_datetime()或直接读寄存器验证时间。下面是一段基于寄存器直操作的示例改编自我在项目里的初始化代码#include hardware/regs/rtc.h #include hardware/structs/rtc.h #include hardware/structs/clocks.h static uint8_t dec_to_bcd(uint8_t dec) { return ((dec / 10) 4) | (dec % 10); } void rtc_reg_set_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) { // 1. 使能 RTC rtc_hw-ctrl RTC_CTRL_RTC_ENABLE_BITS; while (!(rtc_hw-ctrl RTC_CTRL_RTC_ACTIVE_BITS)) { // 等待 RTC 真正运行 } // 2. 写入日期和时间注意 BCD 编码 rtc_hw-setup_0 (dec_to_bcd(year 0xFF) RTC_SETUP_0_YEAR_LSB) | (dec_to_bcd(month) RTC_SETUP_0_MONTH_LSB) | (dec_to_bcd(day) RTC_SETUP_0_DAY_LSB); rtc_hw-setup_1 (dec_to_bcd(hour) RTC_SETUP_1_HOUR_LSB) | (dec_to_bcd(min) RTC_SETUP_1_MIN_LSB) | (dec_to_bcd(sec) RTC_SETUP_1_SEC_LSB); // 3. 触发 LOAD rtc_hw-ctrl RTC_CTRL_RTC_ENABLE_BITS | RTC_CTRL_LOAD_BITS; // 4. 等待 LOAD 完成LOAD 位自动清零 while (rtc_hw-ctrl RTC_CTRL_LOAD_BITS) { // 极短等待通常一个周期就完成 } }上面的代码用了寄存器结构体访问这样读起来比直接操作裸指针要清晰很多。如果你用的是 Pico SDK也可以直接用官方封装的rtc_set_datetime()它的底层就是帮你完成了这整条链路。但理解链路仍然很重要因为后续排查问题的时候你得知道是哪一步没执行。2.4 写入不生效的常见原因与测试方法我在调试中遇到过“时间写进去读出来是 1970 年”的情况。这类问题通常有三个原因。第一是 SETUP 寄存器里填了非 BCD 值。比如直接填了十进制 2025硬件把这个值当成 BCD 解析结果就是非法数据内部逻辑会走默认值。第二是没有执行 LOAD或者 LOAD 之前就把 RTC_ENABLE 关掉了。第三是时间写入之后外部 32.768kHz 晶振没有起振RTC 虽然显示 ACTIVE但内部的秒计数没有真正前进读回来永远是装载之后的状态。验证方法很简单写一个 10 秒左右的延时然后连续读几次时间看秒字段是否在变。如果秒一直不变优先检查时钟源如果时间跳到很离谱的值优先检查 BCD 编码。3. IRQ_SETUP 寄存器8 组闹钟匹配到底怎么配置3.1 8 个 IRQ_SETUP 寄存器只有一组中断RTC_IRQ_SETUP_0到RTC_IRQ_SETUP_7一共 8 个寄存器但它们在中断层面共用一个中断标志位。也就是说无论哪一组匹配成功最终都会置位RTC_INTF的同一个 bit。这样的设计好处是可以配置多个不同时刻的闹钟比如早上 8:00 唤醒采集数据、12:00 上报状态、18:00 关机维护三组闹钟可以同时挂在不同 IRQ_SETUP 寄存器上。坏处是中断服务函数里需要主动判断到底是哪一组触发的否则不知道当前该干什么。判断来源有两种常见做法。第一种是软件维护一个“哪个闹钟应该先响”的队列触发后依次处理第二种是读RTC_IRQ_SETUP_XOR寄存器这个寄存器会反映当前哪些匹配字段和当前时间不一致通过 XOR 结果可以反向推导哪一组寄存器匹配成功了。实际项目里我倾向于第一种因为更直观而且不容易被硬件细节绕晕。3.2 字段使能与匹配值的搭配逻辑每个 IRQ_SETUP 寄存器里都有一组匹配值字段和一组使能字段。匹配值包括 YEAR、MONTH、DAY、HOUR、MIN、SEC使能位包括 YEAR_ENA、MONTH_ENA、DAY_ENA、HOUR_ENA、MIN_ENA、SEC_ENA。关键在于“没有使能的字段不参与比较”。举例来说如果你只想每天早上 8:30 响一次不想关心年份、月份和日期那就只使能 HOUR_ENA 和 MIN_ENA然后把 HOUR 填 8MIN 填 30。SEC_ENA 不使能的话秒字段不参与比较所以这一分钟内的任何一秒都会满足条件中断会连续触发多次。大多数应用要求精确到秒级触发所以通常会把 SEC_ENA 也打开然后 SEC 填 0。这个行为和带掩码的比较器非常像。你可以把它理解为使能位就是“比较掩码”只有使能了的字段才需要和当前时间严格相等。所以配置闹钟之前先列个表确定你关注的是年、月、日、时、分、秒中的哪几位再动手写代码否则很容易配出“每天都响”“每秒都响”这类诡异行为。3.3 推荐配置顺序先写匹配值再使能最后激活配置 IRQ_SETUP 寄存器有一个推荐顺序目的是避免写到一半的时候产生中间状态导致误触发中断先把RTC_CTRL.RTC_ACTIVE确认置 1保证 RTC 正在运行。对某一个RTC_IRQ_SETUP_n先写入匹配值YEAR/MONTH/DAY/HOUR/MIN/SEC。再写入使能位YEAR_ENA/MONTH_ENA/DAY_ENA/HOUR_ENA/MIN_ENA/SEC_ENA。最后把该寄存器的ENABLE置 1激活这一组闹钟。打开RTC_INTE的 RTC_IRQ 中断使能位以及 NVIC 中对应的中断通道。为什么要把 ENABLE 放最后因为如果一开始就把它置 1硬件会在每次寄存器写入时都拿当前时间和“不完整的匹配条件”做比较可能你刚写完小时字段、还没写分钟字段的瞬间条件已经满足了中断就提前触发了。虽然概率不高但在时间敏感的应用里这种偶发中断很难排查。下面配置一个每天 09:30:00 准时触发的中断示例void rtc_alarm_daily_9_30(void) { // 假设 RTC 已经初始化并运行 rtc_hw-irq_setup_0 (9 RTC_IRQ_SETUP_0_HOUR_LSB) | (30 RTC_IRQ_SETUP_0_MIN_LSB) | (0 RTC_IRQ_SETUP_0_SEC_LSB) | RTC_IRQ_SETUP_0_HOUR_ENA_BITS | RTC_IRQ_SETUP_0_MIN_ENA_BITS | RTC_IRQ_SETUP_0_SEC_ENA_BITS; // 最后才使能这一组闹钟 rtc_hw-irq_setup_0 | RTC_IRQ_SETUP_0_ENABLE_BITS; // 打开中断使能 rtc_hw-inte RTC_INTE_RTC_IRQ_BITS; NVIC_EnableIRQ(RTC_IRQn); }有一点需要说明Pico SDK 自带的rtc_set_datetime只负责设置时间不负责闹钟。闹钟配置官方建议用rtc_enable_alarm()但它封装的粒度比较粗有些场景比如多组闹钟还是直接操作寄存器灵活。上面这段就是寄存器级实现。3.4 IRQ_SETUP 寄存器里的 RTC_ACTIVE 与 MATCH_ACTIVE 是干嘛的每个 IRQ_SETUP 寄存器内部还有两个只读状态位RTC_ACTIVE和MATCH_ACTIVE。这两个位不是配置项而是硬件给你的状态反馈调试时非常好用。RTC_ACTIVE表示这个 IRQ_SETUP 寄存器已经看到了 RTC 的使能状态MATCH_ACTIVE表示这一组寄存器的匹配功能已经激活。如果ENABLE已经置 1但MATCH_ACTIVE迟迟不置 1说明前面的配置顺序有问题或者你误清了 RTC_CTRL 的 RTC_ENABLE。我在设计闹钟时习惯在配置完成后读一下这两个状态位打印到串口。如果状态不对立刻就能定位问题不需要等闹钟时间到了才发现没触发。这在调试阶段能省下大量时间。4. INTF 寄存器中断标志的读取与清除一个容易卡死的中断“清不掉”问题4.1 INTF 只有 1 个有效位但 8 组 IRQ_SETUP 共用RTC_INTF是中断标志寄存器它里面只有一个有效位RTC_IRQ。这个位是只读的严格来说是“读可知状态写 1 清零”。读它的时候如果位为 1说明至少有一组 IRQ_SETUP 匹配成功过如果为 0说明没有未处理的中断。由于 8 组闹钟共用一个标志所以中断服务函数里处理完当前任务后需要决定是否继续读取其他 IRQ_SETUP 状态。在某些高精度场景下两个闹钟可能只差几毫秒你的中断服务函数还没来得及清标志第二个闹钟又来了。这种情况下RTC_INTF里只会保留一个标志但两个 IRQ_SETUP 的 MATCH_ACTIVE 可能都是 1。你需要把所有置位的 IRQ_SETUP 寄存器都轮询一遍才能保证不漏事件。我之前的做法是在中断服务函数里循环扫描 8 个 IRQ_SETUP 寄存器凡是 ENABLE 且当前时间匹配的都执行对应回调最后统一清一次 INTF。这样即使多个闹钟时间重叠也不会丢。4.2 W1C 语义为什么是写 1 清零而不是写 0W1C 是 Write-1-to-Clear 的缩写意思是“写 1 清零”这是很多 ARM Cortex-M 外设共用的中断清除方式。如果你用习惯写 0 清除的平台到了这里就会踩坑。简单来说RTC_INTF这个位在读的时候反映的是硬件中断状态你写 0 到这一位硬件会忽略因为它的设计是只有写 1 才会触发清除动作。写 1 之前先要确保中断原因已经被处理否则你把标志清了但闹钟条件依然满足硬件会立刻又把它置 1。清标志的代码很简单// 注意写 1 清除不是写 0 rtc_hw-intf RTC_INTF_RTC_IRQ_BITS;很多人问为什么不用 ~来清因为 ~是在写 0对 W1C 寄存器无效。你写了等于没写中断标志一直为 1然后中断服务函数不断被触发形成一个死循环。这是“RTC 中断风暴”最常见的根因。4.3 一个容易踩的死循环中断中断服务函数里没有正确清标志我在给一个同事 review 代码时看到他写的中断服务函数是这样的void isr_rtc(void) { // 处理闹钟逻辑 do_something_now(); // 忘了清 RTC_INTF // 或者写了 rtc_hw-intf ~RTC_INTF_RTC_IRQ_BITS; }如果没有清RTC_INTF或者用 ~清后果就是中断标志永远为 1CPU 会一直进入该中断服务函数主循环完全卡死。从用户视角看就是“程序跑飞了”“一直在执行中断”。排查的时候先看一眼中断服务函数里有没有rtc_hw-intf RTC_INTF_RTC_IRQ_BITS;八成问题就出在这。正确的流程是读中断标志 - 判断是哪一组 IRQ_SETUP 触发 - 执行对应业务 - 写 1 清除 INTF - 退出中断。顺序不能反如果把清除放在处理业务之前处理业务期间一旦又有新的闹钟条件满足硬件会重新置位标志你退出服务函数后又立刻进入逻辑上不算错但会浪费一次不必要的上下文切换。4.4 INTF 与 INTF_XOR 的结合使用除了RTC_INTF调试时还有一个寄存器值得关注RTC_IRQ_SETUP_XOR。它把 8 组 IRQ_SETUP 寄存器里每个使能字段的“匹配值”和“当前时间”做 XOR结果不为 0 的位表示不匹配。如果你配好闹钟后一直不触发可以通过 XOR 结果快速定位是哪个字段没对上。比如你配置了每天 09:30 的闹钟但 XOR 显示 MIN 字段一直不为 0那大概率是分钟字段的 BCD 编码写错了或者写入位置偏移不对。这个寄存器在普通文档里很少有人提但对排查“为什么闹钟不响”非常高效。5. 实测踩坑记录从“时间乱跳”到“中断风暴”的四个真实教训5.1 时间写进去后跳到 1970 年我最早用寄存器直写 RP2040 RTC 时遇到的第一个问题就是时间写进去后读出来是 1970 年。当时第一反应是硬件没起振但查了半天发现 32.768kHz 晶振波形完全正常。后来定位到原因年份字段写入时没有做 BCD 编码。我把十进制 2025 直接写进了 YEAR 字段硬件按照 BCD 方式解析2025 的二进制是 0x7E9这个值大于年份字段能表达的最大 BCD 值硬件状态被重置到初始值。把年份转成 0x2025 再写进去问题立刻消失。这提醒我一个通用经验遇到 RTC 读到错误时间不要急着怀疑硬件先确认协议和编码。尤其是 RP2040 这种字段类型比较特殊的芯片读 datasheet 的字段定义比自己猜要可靠得多。5.2 晚上 0 点闹钟乱触发后来做低功耗设备时我配置了一个每天 00:00:00 执行的日切任务。功能本身很简单但实测中出现了很诡异的现象有时候 23:59:59 就触发有时候 00:00:01 才触发偶尔还会连续触发两次。查了一圈发现问题出在 RTC 午夜切换的瞬间。RP2040 RTC 内部在日期翻转时有一个短暂的窗口如果闹钟比较条件在这期间进行比对可能出现一个“边界误判”。数据手册里专门给了一个FORCE_NOT_MIDNIGHT位就是用来规避这个问题的。我的处理方法是在配置日切闹钟时把RTC_CTRL.FORCE_NOT_MIDNIGHT位置 1确保 RTC 在午夜边界不会产生伪匹配等时间稳定过一秒后再处理业务。如果你也遇到零点附近闹钟异常可以检查一下这个位。5.3 睡眠唤醒后 RTC 时间不走还有一个常见场景设备进入睡眠后唤醒读 RTC 时间发现秒数完全没动。这种情况基本可以断定 RTC 时钟源在睡眠期间丢失了。如果你用的是内部 12MHz 时钟那这个现象是符合预期的因为内部时钟在低功耗模式下会被关掉RTC 自然停走。如果你确信外部 32.768kHz 晶振已经接上那就要检查 XOSC 是否真的工作在低频模式。RP2040 的 XOSC 有两种模式初始化时选错频率外部晶振可能只在唤醒后重新起振睡眠期间并没有持续给 RTC 供时钟。我把这个检查写进了硬件自检设备启动后先连续读 RTC 时间观察秒递增再进入睡眠唤醒后再读一次如果时间没有前进就在日志里告警。这样能快速暴露时钟链路问题。5.4 “RP2040 总是进入烧录模式”跟 RTC 有关吗网上经常有人问“rp2040 总是进入烧录”这通常是 BOOTSEL 引脚被拉低、电源毛刺、或者 SWD 口状态不对导致的和 RTC 本身没有直接关系。但如果你是在写 RTC 闹钟唤醒代码之后才出现这个问题就得考虑一个间接因素闹钟触发后的中断服务函数里如果写了大量耗时操作系统可能被持续中断占满看起来就像卡死或进入烧录模式。排查思路很简单先断开闹钟中断看问题是否消失然后只保留一个极简的中断服务函数连业务都不做只清标志看是否还会进入烧录模式。用二分法缩小范围比闷头猜快了不止一倍。5.5 补充如果产品真的需要掉电保持时间建议的外部电路做法刚才说过 RP2040 内部没有备用电源域如果你想做“断电后时间不丢”的产品光靠 RP2040 是做不到的。常见的方案是外接 RTC 芯片比如 PCF85063、DS3231 这类它们自带电池引脚和温度补偿晶振。这类芯片的电源切换电路通常是在 VCC 和 VBAT 之间加一个二极管外接 CR2032 纽扣电池主电源掉电后自动切到电池供电。但如果你不想增加额外芯片也可以让 RP2040 保持供电只是把其余外设全部断电时钟保持运行的功耗大概在微安级别具体要看晶振和 LDO 的静态电流。这种做法硬件设计上更简单但会持续消耗电池电量适合那些本身就需要长期低压待机的设备。6. 关于 RTC_CLKDIV 与初始化顺序的补充前面讲了 SETUP、IRQ_SETUP、INTF 三个核心寄存器但 RTC 想正常工作还有一步容易被忽略分频链路的初始化。RTC_CLKDIV_M0和RTC_CLKDIV_M1负责把输入时钟分频到 1Hz。如果这一步没配置好RTC 的秒计数会偏快或偏慢。用 Pico SDK 时rtc_init()内部会帮你处理时钟和分频的初始化所以大部分用户感觉不到这个寄存器的存在。但如果是自己写寄存器级初始化或者移植到其他框架就必须确认clk_rtc的频率和RTC_CLKDIV的分频系数匹配。我一般建议能直接用 SDK 就用 SDK。SDK 的rtc_init()做完了包括时钟切换、分频配置、使能 RTC 在内的一整套初始化比自己写寄存器少踩很多坑。只有在需要特殊时序控制、多组闹钟、低功耗唤醒精确控制时才手动操作寄存器。写在最后的排查顺序实际调试 RP2040 RTC 时如果遇到问题我习惯按这个顺序排查确认硬件时钟源32.768kHz 晶振是否焊接正确波形是否正常。确认rtc_init()或等价的分频初始化已执行。确认 SETUP 写入的字段全部是 BCD 编码。确认RTC_CTRL.LOAD被正确置位。确认 IRQ_SETUP 的配置顺序匹配值 - 使能位 - ENABLE。确认RTC_INTF用写 1 方式清除而不是写 0 或 ~。最后再怀疑芯片本身的问题。这套排查链路在我经历过的项目里成功率很高希望对正在被 RP2040 RTC 折腾的你也有帮助。
返回列表