STM32F103学习笔记(六) RTC实时时钟(应用篇)

news2024/10/2 6:42:08

目录

1. RTC 实时时钟的应用场景

2. RTC 的配置与初始化

2.1 设置 RTC 时钟源

2.2 初始化 RTC 寄存器

2.3 中断配置

2.4 备份寄存器配置

2.5 校准 RTC

3. 实例演示代码

4. 总结

1. RTC 实时时钟的应用场景

        实时时钟(RTC)在嵌入式系统中具有广泛的应用场景,特别是对于需要准确跟踪时间的应用。下面是一些常见的 RTC 应用场景:

        时钟显示: RTC 可用于驱动液晶显示屏上的时钟模块,以在设备上显示当前时间。

        日历功能: RTC 可用于记录日期,包括年、月、日等信息,从而实现日历功能。

        定时任务: 在需要周期性执行任务的应用中,RTC 可以作为触发定时任务执行的时钟源。

        事件记录: RTC 可用于记录系统中的事件发生时间,例如记录故障发生的时间戳。

        定时器功能: RTC 还可以用作定时器,实现定时触发操作,例如定时启动警报等。

        电源管理: RTC 可以在设备休眠时运行,唤醒时提供时间信息,从而实现高效的电源管理。

        日志记录: RTC 可以用于记录系统运行状态或用户操作记录的时间信息,以便后续分析。

2. RTC 的配置与初始化

        配置和初始化 RTC 模块是使用实时时钟功能的关键步骤。下面是配置和初始化 RTC 的一般步骤:

2.1 设置 RTC 时钟源

        RTC 的时钟源通常有两种选择:外部晶体振荡器(LSE)和内部振荡器(LSI)。外部晶体振荡器(通常是32.768kHz)提供更高的精度和稳定性,而内部振荡器则更为节省成本,可以在LSE失效时使用。

2.2 初始化 RTC 寄存器

        RTC 模块通常包含多个寄存器,用于存储时间、日期和控制信息。在初始化过程中,需要设置这些寄存器的初始值,以确保 RTC 模块能够正确地工作。

2.3 中断配置

        如果需要使用 RTC 中断功能,例如定时器中断或闹钟中断,还需要配置相应的中断使能位和中断优先级。这样,当 RTC 模块产生中断时,系统可以及时响应并处理中断事件。

2.4 备份寄存器配置

        RTC 模块通常还包含一些备份寄存器(BKP),用于存储关键信息,例如设备状态、配置参数等。在初始化过程中,可以根据需要对这些备份寄存器进行配置,以实现数据的备份和恢复功能。

2.5 校准 RTC

        通过下列RTC简图可知,后备区域的时钟与APB1总线的时钟是不相同的,为了确保 RTC 模块提供的时间信息准确可靠,需要对 RTC 进行周期性的校准。校准过程包括校正 RTC 时钟源的偏差,以及对 RTC 寄存器的时间值进行校准,以确保与外部时间标准的一致性。

3. 实例演示代码

        本节我们将利用RTC实现一个时钟显示的功能,通过读取时间戳来获取当前时间(主供电断开依然可以由备用电池供电,故主供电断开依然可以记时),本程序可以通过动态传参的方法来配置当前的初始时间。
        首先是等待RTC同步函数

void rtc_wait(void)
{
	RTC_WaitForSynchro();								//等待同步
	RTC_WaitForLastTask();								//等待上一次操作完成
}

        接着是RTC的初始化

void rtc_Init(uint16_t year,uint16_t mouth,uint16_t day,uint16_t hour,uint16_t min,uint16_t sec)
{
	time_t time_cnt;
	struct tm time_date;	
	BKP_Init();//备份寄存器初始化,同时使能PWR的时钟

	if (R_Save_data(BKP_DR10) != 0x2024)			//判断是否是第一次设置备份寄存器
	{
		RCC_LSEConfig(RCC_LSE_ON);							//LSE时钟,通常是32.768kHz
		while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);	//LSE准备就绪
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);				//配置LSE来源
		RCC_RTCCLKCmd(ENABLE);								//RTC时钟使能
		
		rtc_wait();//等待同步(主时钟和低速时钟的同步)
		
		RTC_SetPrescaler(32768 - 1);						//把32.768kHz分频到1Hz
		RTC_WaitForLastTask();								//等待上一次操作完成
		
		time_date.tm_year = year - 1900;  //time库中,年是从1900年算起的
		time_date.tm_mon = mouth - 1; 		//time库中,月是从1月算起的
		time_date.tm_mday = day;
		time_date.tm_hour = hour;
		time_date.tm_min = min;
		time_date.tm_sec = sec;
		
		time_cnt = mktime(&time_date) - 8 * 60 * 60;	//将日期转换为秒计数器,并减8个时区(东8)
		RTC_SetCounter(time_cnt);						//更新到计数器
		RTC_WaitForLastTask();							//等待上一次操作完成
		
		BKP_WriteBackupRegister(BKP_DR10, 0x2024);			//第一次设置完成,写入标志位
	}
	else	rtc_wait();//第一次已经配置好了,后期主上电只需等待时钟同步
}

        接着是RTC读取时间的函数

void Read_RTC(uint16_t *year,uint16_t *mouth,uint16_t *day,uint16_t *hour,uint16_t *min,uint16_t *sec)
{
	time_t time_cnt;		
	struct tm time_date;	
	
	time_cnt = RTC_GetCounter() + 8 * 60 * 60;		//获取当前的秒计数器
	
	time_date = *localtime(&time_cnt);				//将秒计数器转换为日期
	
	*year = time_date.tm_year + 1900;		//将日期时间结构体赋值给数组的时间
	*mouth = time_date.tm_mon + 1;
	*day = time_date.tm_mday;
	*hour = time_date.tm_hour;
	*min = time_date.tm_min;
	*sec = time_date.tm_sec;
}

        在这里我们要注意,需要在文件的开头包含time.h文件,因为在函数中使用到了该头文件中包含的结构体和其他有关时间戳的函数,通过该头文件我们可以避免自己编写闰年等等的程序逻辑

#include <time.h>

        在获取函数之前,我们还需要定义全局变量,一定要全局变量哈,不要写在main函数或者其他功能函数中了

uint16_t year,mouth,day,hour,min,sec;

接着,我们只需要在初始化时将当前时间作为参数传入初始化函数,就可以在获取函数中通过全局变量实时获取到当前的时间了

rtc_Init(2024,2,19,4,27,55); //RTC初始化,当前时间2024年2月19日4点27分55秒
Read_RTC(&year,&mouth,&day,&hour,&min,&sec);//获取函数,将日期信息分别赋值到全局变量中

        最后程序中如果出现函数未定义的,可能是在BKP篇中封装好的函数,下附BKP篇的.c文件

#include "bkp.h"

//备份寄存器初始化
void BKP_Init(void)
{
	//备份寄存器通常需要在Vbat电压下工作(Vbat是用于保持备份寄存器内容的电源),而PWR模块负责监测Vbat电压
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);		//开启PWR的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);		//开启BKP的时钟
	
	PWR_BackupAccessCmd(ENABLE);							//用PWR使能备份寄存器
}

/*在f103c8t6中,有20个字节的后备数据空间,对应10个16位的备份寄存器
BKP_DR对应BKP_DR1 - BKP_DR10
*/
uint16_t W_Save_data(uint16_t BKP_DR, uint16_t data)
{
	BKP_WriteBackupRegister(BKP_DR, data);	//将需要掉电保存的数据写入备份寄存器
	if(data == BKP_ReadBackupRegister(BKP_DR))		//读取写入的备份寄存器的数据
	{
			return 1; //如果正确读取到备份寄存器的数据,返回1
	}
	else return 0;
}

uint16_t R_Save_data(uint16_t BKP_DR)
{
	return BKP_ReadBackupRegister(BKP_DR);
}

4. 总结

        RTC(实时时钟)模块在嵌入式系统中扮演着重要角色,通过提供精确时间和日期信息,帮助系统实现定时任务、时间戳记录、闹钟等功能。我们学习了RTC的原理、配置和应用场景。在配置和初始化RTC时,需要注意时钟源选择、寄存器初始化和异常处理,以确保模块的稳定可靠运行。通过掌握RTC知识,我们能够提升系统性能和稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1471877.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(二十三)Flask之高频面试点

目录&#xff1a; 每篇前言&#xff1a;Q1&#xff1a;为什么把request和session放在一起&#xff1f;Q2&#xff1a;Local对象的作用&#xff1f;Q3:&#xff1a;LocalStack对象的作用&#xff1f;Q4&#xff1a;一个运行中的Flask应用程序分别包括几个Local/LocalStack&#…

msvcr110.dll找不到怎么修复?多种解决msvcr110.dll缺失方法分析

面对如“程序无法启动&#xff0c;因为电脑中缺失msvcr110.dll”这样的错误提示时&#xff0c;你的日常工作或游戏娱乐很可能会被迫暂停。这种问题在Windows用户中相当普遍&#xff0c;它们来源于某些共享的系统文件缺失。不过&#xff0c;好消息是解决此类错误通常并非困难任务…

springboot集成quartz定时任务并接入后台管理系统(copy即用)

说明:项目启动后会根据设置的时间进行执行,业务代码根据自己的需求更改,数据库文件在最后(记得清空数据库哦~)这里需要注意的一点就是className字段表示的是下面的对应的DynamicTask的路径如:com.example.demo.quartz.task.DynamicTask,如有多个定时任务copy并更改Dynam…

Oracle ADG相关介绍

文章目录 一、ADG原理1、ADG介绍2、ADG搭建流程 二、ADG相关参数三、增量修复 一、ADG原理 1、ADG介绍 Oracle ADG&#xff08;Advanced Data Guard&#xff09;是Oracle数据库的一项高可用和灾难恢复技术&#xff0c;它通过将数据保持在物理备库中来提供数据保护和容灾能力。…

FariyGUI × Cocos Creator 3.x 弹窗制作

在fgui里制作一个弹窗 新建一个按钮&#xff0c;作为返回按钮 新建一个标签 做成这个样子 其中包含两个节点&#xff0c;名称分别为title和closeButton 可以阅读fgui的源码window.js得到&#xff0c;closeButton按钮只需要输入名称即可在contentPane设置时自动绑定。 且会…

Wagtail安装运行并结合内网穿透实现公网访问本地网站界面

文章目录 前言1. 安装并运行Wagtail1.1 创建并激活虚拟环境 2. 安装cpolar内网穿透工具3. 实现Wagtail公网访问4. 固定的Wagtail公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xf…

nginx高级配置详解

目录 一、网页的状态页 1、状态页的基本配置 2、搭配验证模块使用 3、结合白名单使用 二、nginx 第三方模块 1、echo模块 1.1 编译安装echo模块 1.2 配置echo模块 三、nginx变量 1、内置变量 2、自定义变量 四、自定义图标 五、自定义访问日志 1、自定义日志格式…

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用

Java根据excel模版导出Excel&#xff08;easyexcel、poi&#xff09;——含项目测试例子拿来即用 1. 前言1.1 关于Excel的一般导出2.2 关于easyexcel的根据模版导出 2. 先看效果2.1 模版2.2 效果 3. 代码实现&#xff08;核心代码&#xff09;3.1 项目代码结构3.2 静态填充例子…

数学建模【GM(1, 1)灰色预测】

一、GM(1, 1)灰色预测简介 乍一看&#xff0c;这个名字好奇怪&#xff0c;其实是有含义的 G&#xff1a;Grey&#xff08;灰色&#xff09;M&#xff1a;Model&#xff08;模型&#xff09;(1, 1)&#xff1a;只含有一个变量的一阶微分方程模型 提到灰色&#xff0c;就得先说…

【已解决】解决Win11忘记开机密码(不用重装系统)

问题起因 因为在实验室的电脑从过年就没有用过&#xff0c;也不知道为什么记性这么差&#xff0c;就把电脑密码忘了&#xff0c;但是又不想用系统盘重装电脑。于是从网上整理一些文章&#xff0c;最后写了下面一篇解决方法 解决方法 1.首先在登录界面&#xff08;输入密码那…

深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(下)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

合并3D线条模型怎样进行调整长度---模大狮模型网

在3D建模软件中合并3D线条模型后&#xff0c;要调整线条的长度可以通过以下步骤进行&#xff1a; 选择线条模型&#xff1a;首先&#xff0c;在3D建模软件中选择您要调整长度的线条模型。这通常涉及使用选择工具或者鼠标点击线条模型来进行选择。 使用拉伸工具&#xff1a;大多…

采访影视行业艺术指导“Sora入局,或将改变游戏规则?”

自OpenAI发布Sora已经过去了半个月&#xff0c;人们对于这个新兴的“文生视频”&#xff08;text-to-video&#xff09;大模型工具都已经有了初步的认识&#xff0c;经过半个月的沉淀&#xff0c;他们也陆续发布了一些更加令人震惊的demo&#xff0c;话不多说&#xff0c;我们先…

大厂性能测试监控指标及分析调优指南

一、哪些因素会成为系统的瓶颈 CPU&#xff1a;如果存在大量的计算&#xff0c;他们会长时间不间断的占用CPU资源&#xff0c;导致其他资源无法争夺到CPU而响应缓慢&#xff0c;从而带来系统性能问题&#xff0c;例如频繁的FullGC&#xff0c;以及多线程造成的上下文频繁的切换…

Jqgrid入门

最近要用Jqgrid做项目&#xff0c;之前都没怎么接触过&#xff0c;看了看官网有一个小demo&#xff0c;于是下下来后&#xff0c;发现这个demo有点问题&#xff0c;度娘了一下&#xff0c;发现有的博主直接贴官网的代码&#xff0c;截了个图&#xff0c;我真是***&#xff0c;还…

【Java程序设计】【C00313】基于Springboot的物业管理系统(有论文)

基于Springboot的物业管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的物业管理系统&#xff0c;本系统有管理员、物业、业主以及维修员四种角色权限&#xff1b; 管理员进入主页面&#xff0c;主要功能包…

protobuf简单使用(二)

介绍 上一节中&#xff0c;我们介绍了protobuf&#xff0c;简单来说&#xff0c;它是一种消息数据格式&#xff0c;其作用类似于json&#xff0c;但是比json的使用效率要高。 除此以外&#xff0c;我们介绍了protobuf的简单使用&#xff0c;也就是如何可以像使用json一样&…

matplotlib plt.show()却弹出空白框并之后自动退出程序的原因及解决方法

运行下列代码并使用plt.show()进行展示时候&#xff0c;cmd输出如下&#xff1a; 先弹出空白框&#xff1a; 而后直接退出程序&#xff1a; 之前遇到过很多次&#xff0c;由于不输出Traceback&#xff0c;完全不知道什么原因。结果发现是因为没有导入torch导致的。 解决办法就…

电商平台商品详情api数据一键采集

批量采集电商平台商品详情API数据的步骤如下&#xff1a; 1. 了解目标电商平台&#xff1a;首先&#xff0c;你需要了解目标电商平台的API文档和规则。不同的电商平台可能有不同的API接口和限制&#xff0c;需要熟悉这些信息。 2. 获取API访问权限&#xff1a;在采集数据之前…

【C++】类与对象——友元,内部类,匿名对象

类与对象 1 友元1.1 概念&#xff1a;1.2 友元函数1.3 友元类 2 内部类概念&#xff1a;特性&#xff1a;举例&#xff1a; 3 匿名对象Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&#xff01;&#xff01;&am…