RTC讲解

RTC(Real Time Clock)实时时钟

RTC实时时钟本质上是一个独立的定时器。RTC模块拥有一组连续计数的32位无符号计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。

RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒 后,RTC的设置和时间维持不变,需要注意前提得有备用电源VBAT供电保持走时,即VDD(2.0~3.6V)断电后可借助VBAT(1.8~3.6V)供电继续走时。

参考手册给出的结构框图如下:

简单介绍流程,就是一个定时器根据时钟确定每秒钟增加多少秒,往往我们是用于看时间,也就是说对于实际分频过后的时钟要有为:1HZ,才能使得定时器每秒钟加1。我们可以通过time.h对时间戳/计数值处理来得到当前的日期时间。

1.时钟来源:我们实际选择时钟源,可选择三种RTC时钟源HSE时钟除以128(通常为8MHz/128)    , LSE振荡器时钟(通常为32.768KHz)    , LSI振荡器时钟(40KHz)三种

对照手册:

我们也可以通过时钟树看出:

2.RTC实际配置步骤:

1.开启RTC访问权

对于stm32来说,实际正常运行不会启动RTC,因为RTC主要由备份电源VBAT供电使用,所以我们使用时候需要开启访问,而BKP和RTC在stm32当中是统一的,开启RTC就相当于开启BKP同样开启BKP也相当于开启RTC。

2.设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问,需要我们手动开启PWR的DBP位,这样才能对RTC写入操作。

3.选择时钟源:对于RTC来说,我们实际上LSE是专门用于RTC的时钟信号,对应外部晶振32.768KHZ。其他主要是作为当第一种无法使用的备份选择。本质上它主要是由备份电源VBAT供电。

4.等待时钟同步,以及写入完成

注意:每一次写入操作都需要我们对等待写入完成,调用库等待函数,或者等待相应标志位RTOFF置0。

5.配置计数器CNT(如果需要余数寄存器也可以在此配置,不过写入后需要等待写入完成)

主要是写入当前时间戳,不知道可以参考之前时间戳讲解。

6.等待写入完成。

实际也可以使用寄存器,不过我使用的是库函数,寄存器可以参考手册如下:

实例代码:

我使用了两种,一种数组,一种时间戳,具体可以根据需要采用

方案一:时间戳:

MYRTC.h

#ifndef __MYRTC_H__
#define __MYRTC_H__
extern struct tm tm_RTC;void MyRTC_Init(void);void RTC_SetTime(void);void RTC_readtime(void);
#endif

MYRTC.c


uint32_t RTC_time=1705582640;//此时此刻的时间戳
struct tm tm_RTC;
void RTC_SetTime(void);
void MyRTC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//开启PWRRCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);//开启RTC时钟PWR_BackupAccessCmd(ENABLE);;//设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问RCC_LSEConfig(RCC_LSE_ON);//开启LSEwhile(RCC_GetFlagStatus(RCC_FLAG_LSERDY)!= SET);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择RTC时钟源:外部时钟源RCC_RTCCLKCmd(ENABLE);//使能时钟RTC_WaitForSynchro();//等待RTC_CNT, RTC_ALR and RTC_PRL同步RTC_WaitForLastTask();//等待RTOFF置1,写操作完成RTC_SetPrescaler(32768-1);//配置预分频器系数RTC_WaitForLastTask();RTC_SetTime();RTC_WaitForLastTask();BKP_WriteBackupRegister(BKP_DR1, 0xFFFF);}
void RTC_SetTime(void)
{RTC_SetCounter(RTC_time+8*60*60);}
void RTC_readtime(void)
{uint32_t Read_time=0;Read_time=RTC_GetCounter();RTC_WaitForLastTask();tm_RTC=*localtime(&Read_time);
}

方案二:数组

MYRTC.h:

#ifndef __MYRTC_H
#define __MYRTC_Hextern uint16_t MYRTC_Time[];void MYRTC_Init(void);
void MYRTC_SetTime(void);
void MYRTC_ReadTime(void);#endif

MYRTC.c:

#include "stm32f10x.h"                  // Device header
#include <time.h>uint16_t MYRTC_Time[] = {2024, 1, 18, 22, 53, 55};void MYRTC_SetTime(void);void MYRTC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);PWR_BackupAccessCmd(ENABLE);RCC_LSEConfig(RCC_LSE_ON);while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);RCC_RTCCLKCmd(ENABLE);RTC_WaitForSynchro();RTC_WaitForLastTask();RTC_SetPrescaler(32768 - 1);RTC_WaitForLastTask();MYRTC_SetTime();}
void MYRTC_SetTime(void)
{time_t time_cnt;struct tm time_date;time_date.tm_year = MYRTC_Time[0] - 1900;time_date.tm_mon = MYRTC_Time[1] - 1;time_date.tm_mday = MYRTC_Time[2];time_date.tm_hour = MYRTC_Time[3];time_date.tm_min = MYRTC_Time[4];time_date.tm_sec = MYRTC_Time[5];time_cnt = mktime(&time_date) - 8 * 60 * 60;RTC_SetCounter(time_cnt);RTC_WaitForLastTask();
}void MyRTC_ReadTime(void)
{time_t time_cnt;struct tm time_date;time_cnt = RTC_GetCounter() + 8 * 60 * 60;time_date = *localtime(&time_cnt);MYRTC_Time[0] = time_date.tm_year + 1900;MYRTC_Time[1] = time_date.tm_mon + 1;MYRTC_Time[2] = time_date.tm_mday;MYRTC_Time[3] = time_date.tm_hour;MYRTC_Time[4] = time_date.tm_min;MYRTC_Time[5] = time_date.tm_sec;
}

时间的转化当中涉及一定偏移,不知道可以参考之前时间戳讲解。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查看Docker安装的RabbitMQ的版本

1、进入容器 docker exec -it <container_id> bash 2、查看版本 rabbitmqctl version

掌上单片机实验室 – 低分辨率编码器测速方式完善(24)

一、背景 本以为“掌上单片机实验室”这一主题已告一段落&#xff0c;可最近在测试一批新做的“轮式驱动单元”时&#xff0c;发现原来的测速算法存在问题。 起因是&#xff1a;由于轮式驱动单元的连线较长&#xff0c;PCB体积也小&#xff0c;导致脉冲信号有干扰&#xff0c;加…

基于springboot猪场管理系统-计算机毕业设计源码11779

摘要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对猪场管理系统等问题&#xff0c;对猪场管理系…

Linux的启动与进程管理[上]

一、启动管理 1、启动过程 //不需要自己操作&#xff0c;仅需等待登录&#xff0c;不多赘述 2、Linux运行级别 查询&#xff1a; 使用runlevel指令 会提醒上次所处的运行级别和当前系统正在运行的运行级别 系统开机时就进入级别x&#xff08;x可为数字0~6&#xff09; 因此…

MySQL篇—性能压测工具mysqlslap介绍

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…

给程序加个进度条吧!1行Python代码,快速搞定~

你在写代码的过程中&#xff0c;有没有遇到过以下问题&#xff1f; 已经写好的程序&#xff0c;想看看程序执行的进度&#xff1f; 在写代码批量处理文件的时候&#xff0c;如何显示现在处理到第几个文件了&#xff1f; &#x1f446;如上图所示的进度条是一个最好的解决方法…

Docker中创建并配置MySQL、nginx、redis等容器

Docker中安装并配置MySQL、nginx、redis等 文章目录 Docker中安装并配置MySQL、nginx、redis等一、创建nginx容器①&#xff1a;拉取镜像②&#xff1a;运行nginx镜像③&#xff1a;从nginx容器中映射nginx配置文件到本地④&#xff1a;重启nginx并重新配置nginx的挂载 二、创建…

大语言模型系列-BERT

文章目录 前言一、BERT的网络结构和流程1.网络结构2.输入3.输出4.预训练Masked Language ModelNext Sentence Predictionloss 二、BERT创新点总结 前言 前文提到的GPT-1开创性的将Transformer Decoder架构引入NLP任务&#xff0c;并明确了预训练&#xff08;学习 text 表征&am…

vim 编辑器如何同时注释多行以及将多行进行空格

一、场景 YAML文件对空格的要求非常严格&#xff0c;因此在修改YAML时&#xff0c;我们可能需要批量添加空格。 二、操作步骤 请注意&#xff1a;您的所有操作都将以第一行为基准。也就是说&#xff0c;第一行有多少个空格&#xff0c;下面的行就会模仿添加相同数量的空格。…

Spring WebSocket实现实时通信的详细教程

简介 WebSocket 是基于TCP/IP协议&#xff0c;独立于HTTP协议的通信协议。WebSocket 连接允许客户端和服务器之间的全双工通信&#xff0c;以便任何一方都可以通过已建立的连接将数据推送到另一方。 我们常用的HTTP是客户端通过「请求-响应」的方式与服务器建立通信的&#x…

Ubuntu 22.04.1 LTS VirtualBox7.0 解决虚拟机窗口失去焦点一段时间后,虚拟机显示不刷新问题

故障描述&#xff1a; virtualbox安装在ubuntu系统上&#xff0c;虚拟机内安装了windows操作系统。使用中发现&#xff0c;当linux系统窗口被激活&#xff0c;如firefox浏览器&#xff0c;虚拟机的显示一段时间后会暂停刷新&#xff0c;鼠标划入虚拟机窗口后&#xff0c;才会立…

mysql数据迁移报错Specified key was too long; max key length is 767 bytes

目录 场景&#xff1a; 说明&#xff1a; 疑问&#xff1a; 解决&#xff1a; 验证&#xff1a; 场景&#xff1a; 线上项目支持的过程中遇到mysql库表结构和数据由A库迁移到B库上提示Specified key was too long; max key length is 767 bytes报错&#xff0c;第一次遇到特此…