一、RTC到底是什么?生活终极比喻(1分钟彻底懂)
你睡觉了,手机还知道现在是几点 → 因为手机里有个“小闹钟”一直在悄悄数时间,哪怕关机、没网、没电(有后备电池)也能继续走!
这就是RTC(Real Time Clock)!
| 角色 | 对应RTC术语 | 说明 |
|---|---|---|
| 你睡觉 | 主CPU掉电/睡眠 | 主程序不运行 |
| 手机后台计时 | RTC独立运行 | 靠32.768kHz晶振 + VBAT电池继续走时 |
| 手机屏幕显示时间 | 读RTC寄存器 | 醒来后问RTC:“现在几点了?” |
| 手机电池没电 | VBAT电池供电 | 纽扣电池CR1220能让RTC走几年 |
记住三句话:
- RTC是芯片里唯一“永远活着”的外设
- RTC靠32.768kHz晶振走时(1秒正好32768次)
- RTC断电也能走(VBAT供电)
────────────────────────
二、STM32 RTC核心结构(F103为例,刻进DNA!)
| 项目 | 参数 | 说明 |
|---|---|---|
| 时钟源 | LSE(32.768kHz) | 最准!推荐! |
| 备用时钟源 | LSI(≈40kHz) | 不准!漂移严重!仅用于无晶振时 |
| 后备电源 | VBAT(1.8~3.6V) | 接纽扣电池,掉电不丢时间 |
| 计数器 | 32位 | 可计137年! |
| 日历功能 | BCD码年月日时分秒 | 自动闰年、星期计算 |
| 报警中断 | Alarm A / B | 到点提醒 |
| 秒中断 | 1秒一次 | 可做心跳 |
终极公式:
text
时间 = CNT寄存器值 ÷ 32768(秒)
────────────────────────
三、RTC三大核心寄存器(背会就无敌)
| 寄存器 | 名称 | 功能 |
|---|---|---|
| CNT | 32位计数器 | 当前总秒数(从1970或自定义起点) |
| ALR | 报警寄存器 | 设定报警时间 |
| PRL | 预分频寄存器 | 必须写32767 → 32768Hz ÷ 32768 = 1Hz |
────────────────────────
四、工业级最强初始化模板(一辈子抄这套)
C
void RTC_Init(void)
{
// 1. 使能PWR和BKP时钟(必须!)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE); // 允许访问后备寄存器(关键!)
// 2. 选择LSE作为RTC时钟源(最准!)
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); // 等晶振稳定
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
// 3. 等待同步
RTC_WaitForSynchro();
RTC_WaitForLastTask();
// 4. 设置预分频(32767 → 1秒中断)
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
// 5. 设置初始时间(2025年1月1日 00:00:00)
RTC_SetCounter(1704038400); // Unix时间戳(可选用BCD)
RTC_WaitForLastTask();
// 6. 开秒中断(可选)
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
}
BCD版设置时间(更直观)
C
void RTC_SetTime(uint16_t year, uint8_t mon, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
{
RTC_WaitForLastTask();
RTC_EnterConfigMode();
RTC_SetCounter(
((year%100)/10)<<20 | ((year%100)%10)<<16 |
(mon/10)<<12 | (mon%10)<<8 |
(day/10)<<4 | (day%10) |
(hour/10)<<20 | (hour%10)<<16 |
(min/10)<<12 | (min%10)<<8 |
(sec/10)<<4 | (sec%10)
);
RTC_ExitConfigMode();
RTC_WaitForLastTask();
}
────────────────────────
五、读取时间三大方式
| 方式 | 代码 | 推荐场景 |
|---|---|---|
| Unix时间戳 | uint32_t time = RTC_GetCounter(); | 与网络时间同步 |
| BCD直接读 | RTC_GetTime() | 显示年月日时分秒 |
| 转成结构体 | 自己写转换函数 | OLED显示 |
实时显示到OLED
C
while(1)
{
uint32_t time = RTC_GetCounter();
OLED_ShowNum(1,1,time,10); // 显示Unix时间戳
Delay_ms(100);
}
────────────────────────
六、掉电不丢时间终极方案(VBAT接法)
text
STM32 VBAT引脚 → 接3V纽扣电池(如CR1220)
│
1k电阻(可选)
│
GND
电池能走多久?
- CR1220(35mAh)+ STM32 RTC功耗 ≈ 1μA
- 寿命 ≈ 35,000小时 ≈ 4年!
────────────────────────
七、金句终极十连(请刻进DNA)
- “RTC是芯片里唯一永远活着的外设”
- “LSE才是王道,LSI是垃圾”
- “没开PWR_BackupAccessCmd,RTC全废”
- “VBAT不接电池,RTC就是笑话”
- “你不会RTC,就永远做不出产品”
- “所有牛逼的项目,都是RTC守着的”
- “RTC一准,世界清静”
1304

被折叠的 条评论
为什么被折叠?



