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

cs 复制代码
#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

cs 复制代码
uint32_t RTC_time=1705582640;//此时此刻的时间戳
struct tm tm_RTC;
void RTC_SetTime(void);
void MyRTC_Init(void)
{
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//开启PWR
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);//开启RTC时钟
		
	  PWR_BackupAccessCmd(ENABLE);;//设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问
		
			RCC_LSEConfig(RCC_LSE_ON);//开启LSE

		 while(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:

cs 复制代码
#ifndef __MYRTC_H
#define __MYRTC_H

extern uint16_t MYRTC_Time[];

void MYRTC_Init(void);
void MYRTC_SetTime(void);
void MYRTC_ReadTime(void);

#endif

MYRTC.c:

cs 复制代码
#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;
}

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

相关推荐
蓑衣客VS索尼克8 小时前
单片机中的基础外设GPIO的知识和应用—(6)
笔记·stm32·单片机·嵌入式硬件
云山工作室10 小时前
基于单片机的智慧农业大棚系统(论文+源码)
单片机·嵌入式硬件
柒十三.11 小时前
江科大51单片机笔记【10】蜂鸣器(上)
笔记·嵌入式硬件·51单片机
zephyr_zeng12 小时前
VsCode + EIDE + OpenOCD + STM32(野火DAP) 开发环境配置
c语言·c++·vscode·stm32·单片机·嵌入式硬件·编辑器
鹿屿二向箔12 小时前
72MHz的MCU能支持多大频率的传感器数据采样率?
服务器·网络·单片机
美好的事情总会发生13 小时前
SDIO(Secure Digital Input Output)详解
linux·嵌入式硬件·硬件工程
柒月玖.13 小时前
基于AT89C51单片机的家用全自动洗衣机设计
单片机·嵌入式硬件
Moonnnn.14 小时前
51单片机——程序执行过程(手工汇编)
汇编·笔记·嵌入式硬件·学习·51单片机
派阿喵搞电子15 小时前
STM32的APB1和APB2的区别
stm32·单片机·嵌入式硬件
Archie_IT17 小时前
江协科技/江科大-51单片机入门教程——P[5-1] 模块化编程 & P[5-2] LCD1602调试工具
单片机·嵌入式硬件·mcu·51单片机