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

目录

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.mfbz.cn/a/414151.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

html5盒子模型

1.边框的常用属性 border-color 属性 说明 示例 border-top-color 上边框颜色 border-top-color:#369; border-right-color 右边框颜色 border-right-color:#369; border-bottom-color 下边框颜色 border-bottom-color:#fae45b; border-left-color 左边框颜色…

phpldapadmin This base cannot be created with PLA

phpldapadmin This base cannot be created with PLA 1、问题描述2、问题分析3、解决方法&#xff1a;创建根节点 1、问题描述 安装phpldapadmin参考链接: https://blog.csdn.net/OceanWaves1993/article/details/136048686?spm1001.2014.3001.5501 刚安装完成phpldapadmin&…

括号生成(力扣题目22)

题目描述&#xff1a; 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()&q…

备战蓝桥杯————k个一组反转单链表

k个反转单链表&#xff0c;顾名思义就是k个节点为一组进行反转&#xff0c;这是一道困难的题目&#xff0c;如何解答&#xff0c;可以在我们前面的反转链表中得到思路。 如何 K 个一组反转单链表 题目描述 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xf…

STC-ISP原厂代码研究之 V3.7d汇编版本

最近在研究STC的ISP程序,用来做一个上位机烧录软件,逆向了上位机软件,有些地方始终没看明白,因此尝试读取它的ISP代码,但是没有读取成功。应该是目前的芯片架构已经将引导代码放入在了单独的存储块中,而这存储块有硬件级的使能线,在面包板社区-宏晶STC单片机的ISP的BIN文…

802.11局域网的 MAC 帧

目录 802.11 局域网的 MAC 帧 802.11 数据帧的三大部分 1.关于 802.11 数据帧的地址 最常用的两种情况 2.序号控制字段、持续期字段和帧控制字段 802.11 局域网的 MAC 帧 802.11 帧共有三种类型&#xff1a;控制帧、数据帧和管理帧。 802.11 数据帧的三大部分 MAC 首部&…

千卡利用率超98%,详解JuiceFS在权威AI测试中的实现策略

2023 年 9 月&#xff0c;AI 领域的权威基准评测 MLPerf 推出了 Storage Benchmark。该基准测试通过模拟机器学习 I/O 负载的方法&#xff0c;在不需要 GPU 的情况下就能进行大规模的性能压测&#xff0c;用以评估存储系统的在 AI 模型训练场景的适用性。 目前支持两种模型训练…

07 Qt自绘组件:图片预览小组件ImageViewer

系列文章目录 01 Qt自定义风格控件的基本原则-CSDN博客 02 从QLabel聊起&#xff1a;自定义控件扩展-图片控件-CSDN博客 03 从QLabel聊起&#xff1a;自定义控件扩展-文本控件-CSDN博客 04 自定义Button组件&#xff1a;令人抓狂的QToolButton文本图标居中问题-CSDN博客 0…

CentOS7 Hive2.3.8安装

CentOS7 Hive2.3.8 安装 建议从头用我的博客&#xff0c;如果用外教的文件到 一、9)步骤了&#xff0c;就用他的弄完&#xff0c;数据库不一样&#xff0c;在9步骤前还能继续看我的 一、 安装MySQL 0.0&#xff09;查询mariadb,有就去0.1&#xff09;&#xff0c;没有就不管…

element el-table表格内容宽度自适应,不换行,不隐藏

2024.2.27今天我学习了如何用el-table实现表格宽度的自适应&#xff0c;当我们动态渲染表格数据的时候&#xff0c;有时候因为内容太多会出现挤压换行的效果&#xff1a; 我们需要根据内容的最大长度设置动态的宽度&#xff0c;这边我在utils里面封装了一个js&#xff1a; //…

排序算法之快速排序(挖坑法)

挖坑法的思想&#xff1a;记第一个数为key&#xff0c;要调整key的位置&#xff0c;使得左边的都要比key的小&#xff0c;右边的数都比key的大。 记录下关键字keybegin&#xff0c;把28那个位置挖坑holebegin 让end找到小于28&#xff08;key&#xff09;的数&#xff0c;把那…

针对KZG承诺和高效laconic OT的extractable witness encryption

1. 引言 2024年以太坊基金会等成员论文 Extractable Witness Encryption for KZG Commitments and Efficient Laconic OT&#xff0c;开源代码实现见&#xff1a; https://github.com/rot256/research-we-kzg&#xff08;Rust&#xff09; 在该论文中&#xff0c;提供了一种…

c# ABB 机械手上位机连接

c# 程式开发和调试步骤如下&#xff1a; ABB 机械手要开启PC Interface功能。ABB 机械手设定ip地址。设定测试笔记本和机械手同一网段&#xff0c;用网线直连机械手&#xff0c;也可以通过交换机连接机械手。确保笔记本能够ping通和telnet 机械手80端口都是OK的。以上都OK的话…

语音合成(TTS) GPT-SoVITS认知

写在前面 小伙伴推荐&#xff0c;简单了解相对之前试过的其他的TTS项目&#xff0c;GPT-SoVITS的优点简单易用&#xff0c;文档完整&#xff0c;默认的模型效果就很好理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候…

【半监督医学图像分割 2021 IEEE】DU-GAN

【半监督医学图像分割 2021 IEEE】DU-GAN 论文题目&#xff1a;DU-GAN: Generative Adversarial Networks with Dual-Domain U-Net Based Discriminators for Low-Dose CT Denoising 中文题目&#xff1a;基于双域U-Net鉴别器的生成对抗网络用于低剂量CT去噪 论文链接&#xff…

LeetCode 热题 100 | 图论(上)

目录 1 200. 岛屿数量 2 994. 腐烂的橘子 2.1 智障遍历法 2.2 仿层序遍历法 菜鸟做题&#xff0c;语言是 C 1 200. 岛屿数量 解题思路&#xff1a; 遍历二维数组&#xff0c;寻找 “1”&#xff08;若找到则岛屿数量 1&#xff09;寻找与当前 “1” 直接或间接连接在…

考研数据结构算法机试训练1

中南大学上机压轴题 测试数据&#xff1a; 3 500 0.6 100 0.8 200 0.7 100 输出 390首先要对输入的折扣进行排序&#xff0c;优先使用比率低的z进行支付。 然后用lowcost记录目前多少钱是打过折的。T-lowcost就是剩余没打折的。 每次循环用上一个人的折扣额度。若所有人折扣额…

Android 跨进程通信aidl及binder机制详解(二)

跨进程通信流程 通过上文可发现&#xff0c;要实现跨进程通信&#xff0c;需要客户端、服务端、客户端与服务端通信规约也就是通过aidl生成的java接口。下面用一个图来表述&#xff1a; 对于上图的调用过程&#xff0c;我们做一下解释&#xff1a;上图中列了几个对象的关联关系…

windows安装部署node.js并搭建Vue项目

一、官网下载安装包 官网地址&#xff1a;https://nodejs.org/zh-cn/download/ 二、安装程序 1、安装过程 如果有C/C编程的需求&#xff0c;勾选一下下图所示的部分&#xff0c;没有的话除了选择一下node.js安装路径&#xff0c;直接一路next 2、测试安装是否成功 【winR】…

Windows系统x86机器安装(麒麟、统信)ARM系统详细教程

本次介绍在window系统x86机器上安装国产系统 arm 系统的详细教程。 注:ubuntu 的arm系统安装是一样的流程。 1.安装环境准备。 首先,你得有台电脑,配置别太差,至少4核8G内存,安装window10或者11都行(为啥不能是Window7,你要用也不是不行,你先解决win7补丁更新问题)。…