RTC时钟实现实时日历



1、RTC时钟简介

1.2、初识RTC

    1、简介:
RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个32bit的时间寄存器,可直接输出时分秒,星期、月、日、年。比起F103系列的RTC只能输出秒中断,剩下的其他时间需要软件来实现,429的RTC可谓是脱胎换骨,让我们在软件编程时大大降低了难度。RTC功能框图分析

    2、功能框图
在这里插入图片描述
    3、组成:
    APB1接口:用来和APB1总线相连。通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。
    RTC核心:由一组可编程计数器组成,它又分两个主要模块:
        RTC预分频模块,它可以编程产生最长1秒的RTC时间基TR_CLK。如果设置了秒中断允许位,可以产生秒中断;
        32位的可编程计数器,可被初始化为当前时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比,当匹配时候如果设置了闹钟中断允许位,可以产生闹钟中断;如果溢出,可以产生溢出中断。

    4、主要特征:
(1)可编程的预分频系数:分频系数最高为220;
(2)32位的可编程计数器,可用于较长时间段的测量;
(3)2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟频率的四分之一以上);

1.2、相关寄存器

    1、读RTC寄存器:
RTC内核完全独立于APB1接口,软件通过APB1接口对RTC相关寄存器访问。但是相关寄存器只在RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。所以软件必须先等待寄存器同步标志位(RTC_CRL的RSF位)被硬件置1才读。
这意味着,如果APB1接口曾经被关闭,而读操作又是在刚刚重新开启APB1之后,则在第一次的内部寄存器更新之前,从APB1上读出的RTC寄存器数值可能被破坏了(通常读到0)。简单地讲,在APB1接口被禁止(复位、无时钟或断电)的情况下,RTC核仍保持运行状态。接着,重新打开APB1接口,此时必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1,同步之后,读RTC寄存器的值才不会有误。
因此,若在读取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器的RSF位被硬件置1。

    2、写RTC寄存器:
必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器。
另外,对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器。

    3、RTC预分频装载寄存器(RTC_PRLH、RTC_PRLL):
在这里插入图片描述
作用:配置RTC预分频装载值,这个值是20bit长度。
    4、RTC预分频器余数寄存器(RTC_DIVH、RTC_DIVL):
在这里插入图片描述
作用:获得预分频计数器的当前值,也就是从RTC预分频装载寄存器倒数到0之间的一个值(以RTCCLK为时钟)。

    5、RTC计数器寄存器(RTC_CNTH、RTC_CNTL):
在这里插入图片描述
作用:存放计数器内的计数值(以TR_CLK为时钟)。

    6、RTC闹钟寄存器(RTC_ALRH、RTC_ALRL)
在这里插入图片描述

作用:当RTC计数器寄存器的值与RTC闹钟寄存器的值相等的时候,触发一个闹钟事件,产生一个闹钟中断。

2、创建项目2

    1选择STM32F103
C8开发板,创建项目进行配置。
    2、配置RCC:设置高速外部时钟HSE 并使能外部晶振LSE
在这里插入图片描述

    2、配置RTC时钟:Activate Clock Source 激活时钟源、Activate calendar激活日历
在这里插入图片描述

这两个都要选择,作用也很明显,先是使能时钟源,再使能RTC日历
RTC_OUT: Not RTC_OUT
Tamper: ×
第一个是是否使能 tamper(PC13)引脚上输出校正的秒脉冲时钟,
第二个: RTC入侵检测校验功能

    3、配置两个RTC的中断:
RTC全局中断RTC_IRQHandler()
闹钟中断函数RTCAlarm_IRQHandler()
在这里插入图片描述
    设置初始时间为2021-12-03,13:00:00

    4、时钟设置为最大72Hz
在这里插入图片描述

    4、使能串口一
在这里插入图片描述

    5、生成项目文件
在这里插入图片描述

3、完善代码

在main.c文件中重写fputc函数,完成printf函数的重定向

//添加头文件#include "stdio.h"
int fputc(int ch,FILE *f){
 uint8_t temp[1]={ch};
 HAL_UART_Transmit(&huart1,temp,1,2);
 return ch;
}

    1、在main.c的while循环中添加如下代码

/* Get the RTC current Time */
	  HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
      /* Get the RTC current Date */
      HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);

      /* Display date Format : yy/mm/dd */
      printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
      /* Display time Format : hh:mm:ss */
      printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);

      printf("\r\n");

      HAL_Delay(1000);

    2、运行结果
在这里插入图片描述

    3、添加星期几的输出在输出年月日的代码printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);后面添加代码

/* Display date Format : weekday */
		if(GetData.WeekDay==1){
			printf("星期一\r\n");
		}else if(GetData.WeekDay==2){
			printf("星期二\r\n");
		}else if(GetData.WeekDay==3){
			printf("星期三\r\n");
		}else if(GetData.WeekDay==4){
			printf("星期四\r\n");
		}else if(GetData.WeekDay==5){
			printf("星期五\r\n");
		}else if(GetData.WeekDay==6){
			printf("星期六\r\n");
		}else if(GetData.WeekDay==7){
			printf("星期日\r\n");
		}

    4、添加之后的运行结果
在这里插入图片描述

4、总结

    初次了解RTC,使用它能够实现实时试件的实现,能够帮助我们获得正确的环境时间,这对于我们后面的应用帮助是非常大的,我们的数据采集、定时等等操作都需要用到实时时钟。

参考:
https://blog.csdn.net/qq_38410730/article/details/80050619
https://blog.csdn.net/as480133937/article/details/105741893

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值