news 2026/4/24 19:47:32

RTC代码部分

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RTC代码部分

RTC

一. 常用库函数

void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

void RCC_LSEConfig(uint32_t RCC_LSE);

void RCC_LSICmd(FunctionalState NewState);

FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);

void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);

void RCC_RTCCLKCmd(FunctionalState NewState);

void PWR_BackupAccessCmd(FunctionalState NewState);

uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);

void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);

void RTC_WaitForSynchro(void);

void RTC_WaitForLastTask(void);

void RTC_SetPrescaler(uint32_t PrescalerValue);

void RTC_SetCounter(uint32_t CounterValue);

uint32_t RTC_GetCounter(void);

time_t mktime(struct tm *timeptr);

struct tm *localtime(const time_t *timer);

补充说明:time.h库中的mktimelocaltime用于时间格式转换(日期时间 ? 秒计数器),需包含头文件#include <time.h>

二. 初始化(支持LSE/LSI两种时钟源,默认LSE)

2.1 默认初始化(LSE时钟源,推荐)

voidMyRTC_Init(void){/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//开启PWR时钟(控制备份域访问)RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);//开启BKP时钟(备份寄存器、RTC相关)/*备份寄存器访问使能*/PWR_BackupAccessCmd(ENABLE);//开启对备份域(BKP、RTC)的访问权限// 判断RTC是否为第一次配置(通过备份寄存器标志位判断)if(BKP_ReadBackupRegister(BKP_DR1)!=0xA5A5){RCC_LSEConfig(RCC_LSE_ON);//开启LSE(外部低速晶振,32.768KHz)while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)!=SET);//等待LSE晶振稳定就绪RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择RTC时钟源为LSERCC_RTCCLKCmd(ENABLE);//使能RTC时钟RTC_WaitForSynchro();//等待RTC与APB1总线同步RTC_WaitForLastTask();//等待上一次RTC操作完成(保障操作可靠性)RTC_SetPrescaler(32768-1);//设置RTC预分频器,32768分频后计数频率为1HzRTC_WaitForLastTask();//等待预分频器配置完成MyRTC_SetTime();//初始化时间(将全局数组时间写入RTC硬件)BKP_WriteBackupRegister(BKP_DR1,0xA5A5);//写入标志位,标记已完成第一次配置}else//非第一次配置(已初始化过,直接同步){RTC_WaitForSynchro();//等待RTC与APB1总线同步RTC_WaitForLastTask();//等待上一次RTC操作完成}}

2.2 备用初始化(LSI时钟源,LSE无法起振时使用)

voidMyRTC_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);PWR_BackupAccessCmd(ENABLE);if(BKP_ReadBackupRegister(BKP_DR1)!=0xA5A5){RCC_LSICmd(ENABLE);//开启LSI(内部低速晶振,约40KHz)while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)!=SET);//等待LSI晶振稳定就绪RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);//选择RTC时钟源为LSIRCC_RTCCLKCmd(ENABLE);//使能RTC时钟RTC_WaitForSynchro();RTC_WaitForLastTask();RTC_SetPrescaler(40000-1);//设置预分频器,40000分频后计数频率为1HzRTC_WaitForLastTask();MyRTC_SetTime();BKP_WriteBackupRegister(BKP_DR1,0xA5A5);}else{RCC_LSICmd(ENABLE);//非第一次配置,也需重新开启LSI时钟while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)!=SET);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);RCC_RTCCLKCmd(ENABLE);RTC_WaitForSynchro();RTC_WaitForLastTask();}}

初始化关键说明

  • 时钟配置核心:RTC依赖低速时钟(LSE/LSI),LSE为外部32.768KHz晶振,可由备用电源供电(主电源掉电后仍能走时);LSI为内部40KHz晶振,无需外部硬件,但主电源掉电后停止走时。

  • 备份域访问:RTC和BKP(备份寄存器)属于备份域,需先开启PWR和BKP时钟,再通过PWR_BackupAccessCmd(ENABLE)开启访问权限,否则无法操作RTC和备份寄存器。

  • 第一次配置判断:通过备份寄存器BKP_DR1写入标志位0xA5A5,下次上电时读取该标志位,避免重复初始化(重复初始化会覆盖已设置的时间)。

  • 同步与等待:RTC_WaitForSynchro()用于等待RTC与APB1总线同步(避免读写时序错乱);RTC_WaitForLastTask()用于等待RTC操作完成(RTC操作是异步的,需等待确认)。

  • 预分频器配置:预分频器值 = 时钟频率 - 1,LSE(32768KHz)对应32768-1,LSI(40KHz)对应40000-1,分频后RTC计数频率为1Hz(每秒计数1次),对应时间的秒单位。

三. 核心函数用法

  1. MyRTC_Initvoid MyRTC_Init(void);
    函 数:RTC初始化(含时钟源配置、备份域使能、第一次配置判断)
    作用:初始化RTC相关时钟和GPIO,判断是否为第一次配置,第一次配置则开启时钟源、设置预分频器、初始化时间并写入标志位;非第一次配置则直接完成同步,确保RTC正常工作。
    补充:默认使用LSE时钟源,LSE无法起振时,替换为LSI版本的初始化函数。

  2. MyRTC_SetTimevoid MyRTC_SetTime(void);函 数:RTC设置时间
    作用:将全局数组MyRTC_Time(格式:年、月、日、时、分、秒)的时间值,刷新到RTC硬件电路。
    核心逻辑:通过mktime函数将日期时间结构体转换为秒计数器(从1970年1月1日00:00:00开始的总秒数),减去86060(东八区时区调整),再通过RTC_SetCounter写入RTC计数器,完成时间设置。

  3. MyRTC_ReadTimevoid MyRTC_ReadTime(void);
    函 数:RTC读取时间
    作用:读取RTC硬件电路中的当前时间,刷新到全局数组MyRTC_Time,供主函数调用。
    核心逻辑:通过RTC_GetCounter读取RTC当前的秒计数器,加上86060(东八区时区调整),再通过localtime函数将秒计数器转换为日期时间结构体,最后赋值给全局数组。

四. 全局变量说明

uint16_tMyRTC_Time[]={2023,1,1,23,59,55};//RTC时间全局数组// 数组索引对应:[0]=年,[1]=月,[2]=日,[3]=时,[4]=分,[5]=秒// 用法:修改该数组后调用MyRTC_SetTime(),即可更新RTC硬件时间;调用MyRTC_ReadTime(),可将硬件时间读入该数组

五. 注意事项

  • LSE晶振注意:LSE依赖外部32.768KHz晶振,若未焊接晶振或晶振无法起振,程序会卡死在while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET),此时需替换为LSI版本的初始化函数。

  • LSI局限性:LSI为内部晶振,精度低于LSE,且无法由备用电源供电,主电源掉电后RTC停止走时,再次上电后时间需重新校准。

  • 标志位作用:备份寄存器BKP_DR1中的0xA5A5是自定义标志位,用于判断RTC是否第一次配置,若手动清除该标志位(或备份域掉电),RTC会重新执行第一次配置,覆盖原有时间。

  • 时区调整:mktimelocaltime函数默认使用UTC时间(世界标准时间),需通过±86060(8小时)调整为东八区时间,否则读取的时间会比实际时间晚8小时。

  • 同步与等待函数:RTC_WaitForSynchro()RTC_WaitForLastTask()不可省略,否则会导致RTC读写时序错乱,出现时间设置失败、读取数据异常等问题。

  • 备用电源:使用LSE时钟源时,若接入备用电源(如纽扣电池),主电源掉电后RTC仍能正常走时;使用LSI时钟源时,备用电源无效。

  • 时间格式:全局数组MyRTC_Time的年份需传入4位(如2023),月份、日期、时、分、秒需传入实际值(月份1-12,日期1-31,时0-23,分0-59,秒0-59),MyRTC_SetTime会自动适配tm结构体的格式(年份-1900,月份-1)。

  • 头文件依赖:需包含time.h头文件,否则mktimelocaltime函数会报错,需确保编译器支持该头文件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 19:41:04

如何快速掌握QQ截图独立版:免登录的专业截图工具完整指南

如何快速掌握QQ截图独立版&#xff1a;免登录的专业截图工具完整指南 【免费下载链接】QQScreenShot 电脑QQ截图工具提取版,支持文字提取、图片识别、截长图、qq录屏。默认截图文件名为ScreenShot日期 项目地址: https://gitcode.com/gh_mirrors/qq/QQScreenShot QQ截图…

作者头像 李华