【STM32】RTC实时时钟

在学习RTC实时时钟之前,我们先来了解一下Unix时间戳。

Unix时间戳

  • Unix 时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒
  • 时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量
  • 世界上所有时区的秒计数器相同,不同时区通过添加偏移来得到当地时间
 UTC/GMT

        GMT(Greenwich Mean Time)格林尼治标准时间是一种以地球自转为基础的时间计量系统。它将地球自转一周的时间间隔等分为24小时,以此确定计时标准

        UTC(Universal Time Coordinated)协调世界时是一种以原子钟为基础的时间计量系统。它规定铯133原子基态的两个超精细能级间在零磁场下跃迁辐射9,192,631,770周所持续的时间为1秒。当原子钟计时一天的时间与地球自转一周的时间相差超过0.9秒时,UTC会执行闰秒来保证其计时与地球自转的协调一致

时间戳转换 
  • C语言的time.h模块提供了时间获取和时间戳转换的相关函数,可以方便地进行秒计数器、日期时间和字符串之间的转换 
函数作用
time_t time(time_t*);获取系统时钟
struct tm* gmtime(const time_t*);秒计数器转换为日期时间(格林尼治时间)
struct tm* localtime(const time_t*);秒计数器转换为日期时间(当地时间)
time_t mktime(struct tm*);日期时间转换为秒计数器(当地时间)
char* ctime(const time_t*);秒计数器转换为字符串(默认格式)
char* asctime(const struct tm*);日期时间转换为字符串(默认格式)
size_t strftime(char*, size_t, const char*, const struct tm*);日期时间转换为字符串(自定义格式)

 BKP备份寄存器(Backup Registers)

BKP介绍
  • BKP可用于存储用户应用程序数据。当VDD(2.0~3.6V)电源被切断,他们仍然由VBAT(1.8~3.6V)维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位
  • TAMPER引脚产生的侵入事件将所有备份寄存器内容清除
  • RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲
  • 存储RTC时钟校准寄存器
  • 用户数据存储容量:     20字节(中容量和小容量)/ 84字节(大容量和互联型)
BKP基本结构 

RTC实时时钟 (Real Time Clock)

  • RTC是一个独立的定时器,可为系统提供时钟和日历的功能
  • RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD(2.0~3.6V)断电后可借助VBAT(1.8~3.6V)供电继续走时
  • 32位的可编程计数器,可对应Unix时间戳的秒计数器
  • 20位的可编程预分频器,可适配不同频率的输入时钟 可选择三种RTC时钟源:

 HSE时钟除以128(通常为8MHz/128)     

LSE振荡器时钟(通常为32.768KHz)     

LSI振荡器时钟(40KHz)

VBAT、晶振硬件电路 

 RTC框图

RTC基本结构

 RTC编程注意事项
  • 执行以下操作将使能对BKP和RTC的访问:     

设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和BKP时钟     

设置PWR_CR的DBP,使能对BKP和RTC的访问

  • 若在读取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1
  • 必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器
  • 对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器
RTC 初始化代码 
void MyRTC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);		
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);		
	
	/*备份寄存器访问使能*/
	PWR_BackupAccessCmd(ENABLE);							
		
	RCC_LSEConfig(RCC_LSE_ON);							//开启LSE时钟
	while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);	//等待LSE准备就绪
	
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);				//选择RTCCLK来源为LSE
	RCC_RTCCLKCmd(ENABLE);								//RTCCLK使能
	
	RTC_WaitForSynchro();								//等待同步
	RTC_WaitForLastTask();								//等待上一次操作完成
	
	RTC_SetPrescaler(32768 - 1);						//设置RTC预分频器,预分频后的计数频率为1Hz
	RTC_WaitForLastTask();								//等待上一次操作完成
	
	RTC_SetCounter(1672588795);						//将秒计数器写入到RTC的CNT中(可自定义)
	RTC_WaitForLastTask();							//等待上一次操作完成

}

 rcc.h常用函数

		RCC_LSEConfig(RCC_LSE_ON);							//开启LSE时钟
		RCC_GetFlagStatus(RCC_FLAG_LSERDY);	                //查看LSE状态标志位
		
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);				//选择RTCCLK来源为LSE
		RCC_RTCCLKCmd(ENABLE);								//RTCCLK使能

bkp.h常用函数

//向STM32芯片的备份寄存器中写入数据
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);


//读取STM32芯片的备份寄存器中的数据

uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);

pwr.h常用函数

//用来开启或关闭STM32芯片的备份区域的访问权限
void PWR_BackupAccessCmd(FunctionalState NewState);

rtc.h常用函数

uint32_t  RTC_GetCounter(void);    //获取STM32芯片上实时时钟(RTC)的计数器值
void RTC_SetCounter(uint32_t CounterValue);    //用于设置STM32芯片上实时时钟(RTC)的计数器值
void RTC_SetPrescaler(uint32_t PrescalerValue);    //用于设置RTC(实时时钟)的预分频器值

void RTC_WaitForLastTask(void);    //用于等待RTC的最后一个操作完成
void RTC_WaitForSynchro(void);    //用于等待RTC的时钟同步

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值