STM32 使用 RTC 实现实时时钟功能
演示视频:https://www.bilibili.com/video/BV1ffoXYaE5E/?share_source=copy_web&vd_source=0e4269581b0bc60d57a80c9a27c98905
一、实验目的
本实验演示如何使用 STM32 内部的 RTC(Real Time Clock)模块来实现实时时钟功能,并使用 OLED 显示日期、时间、计数器值及分频器值。
二、实验现象
上电后,OLED 会显示当前的年月日、时分秒,以及 RTC 内部的 CNT
(计数器值)与 DIV
(分频器值),并且随着时间流逝自动刷新,达到实时时钟功能的效果。
三、RTC 初始化逻辑说明
STM32 的 RTC 默认使用外部低速晶振(LSE)32.768kHz,通过配置分频器,使计数器每秒加 1,实现标准 UNIX 时间戳计数。该时间戳可以与 time.h
标准库兼容,轻松转换为年月日时分秒。
RTC 初始化流程:
void MyRTC_Init(void)
开启 PWR 和 BKP 外设时钟。
使能备份寄存器访问。
判断备份寄存器值是否为
0xA5A5
:如果不是,说明是第一次上电:
配置 LSE 晶振作为 RTC 时钟源;
启用 RTC;
设置分频系数 32768;
设置初始时间;
备份寄存器写入标志。
如果是,直接同步和等待任务完成。
四、RTC 相关函数说明
设置初始时间:
void MyRTC_SetTime(void)
使用 time.h
中的 mktime()
函数将年月日时分秒转换为时间戳(以秒为单位),并设置给 RTC。
获取当前时间:
void MyRTC_ReadTime(void)
从 RTC 获取时间戳,再使用 localtime()
转换为年月日时分秒,保存至数组 MyRTC_Time[]
中。
五、主函数展示
int main() {OLED_Init(); // OLED初始化MyRTC_Init(); // RTC初始化// 静态界面文字OLED_ShowString(1, 1, "Data:XXXX-XX-XX");OLED_ShowString(2, 1, "Time:XX:XX:XX");OLED_ShowString(3, 1, "CNT:");OLED_ShowString(4, 1, "DIV:");while(1) {MyRTC_ReadTime(); // 更新时间数据// 显示年月日OLED_ShowNum(1, 6, MyRTC_Time[0], 4); // 年OLED_ShowNum(1, 11, MyRTC_Time[1], 2); // 月OLED_ShowNum(1, 14, MyRTC_Time[2], 2); // 日// 显示时分秒OLED_ShowNum(2, 6, MyRTC_Time[3], 2); // 时OLED_ShowNum(2, 9, MyRTC_Time[4], 2); // 分OLED_ShowNum(2, 12, MyRTC_Time[5], 2); // 秒// 显示RTC内部值OLED_ShowNum(3, 5, RTC_GetCounter(), 10); // 当前时间戳OLED_ShowNum(4, 5, RTC_GetDivider(), 10); // 当前分频器值}
}
六、关键全局变量
uint16_t MyRTC_Time[] = {2025, 3, 27, 10, 50, 50};
用于存储年月日时分秒。初始化时使用该值设置 RTC 初始时间。
七、注意事项
LSE 晶振要接上,如果板子无 LSE,可使用 LSI,但精度会差很多;
若修改初始时间,需要先清除备份寄存器或重新烧写初始化代码;
RTC 配置只需设置一次,断电后由后备电池保持计数。