目录

关于RTCSTM32CubeMAX界面keil界面

关于RTC

1、RTC介绍 RTC(Real Time Clock):实时时钟,是指可以像时钟一样输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。

RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器(BKP)。因为它掉电后仍然可以通过纽扣电池供电,继续工作,所以能时刻保存这些数据。

stm32F103使用外部晶体的32.768kHz的振荡器,产生一个1秒长的时间基准。

RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护。

2、工作过程

RTC只是一个时钟,但与RTC相连的有两个系统时钟:一个是APB1接口的PCLK1,另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核心,其整个核心部分位于后备区域,所以只要有VBAT引脚供电,就能一直工作,由一系列可编程计数器组成,这部分又再细分为两个组件:20位的预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。

RTC_PRL:预分频装载寄存器 RTC_DIV:预分频器余数寄存器 RTC_CNT:计数器寄存器 RTC_ALR:闹钟寄存器

首先,在初始化时候,DIV和PRL都会装载同样的数。RTCCLK频率为32.768kHz,来驱动DIV工作,DIV为自减寄存器。当DIV减少到0时,会产生一个TR_CLK信号,该信号会触发三件事情:①将PRL的数重装在到DIV中;②触发CNT计数器+1;③触发SECF,进而产生秒中断。我们会设置一个合理的预分频数,使得TR_CLK触发时间刚好是1s。ALR中存储的是我们设置的闹钟秒数,当CNT和ALR中的数据相同时,就会触发闹钟中断或者闹钟唤醒。(关于CNT和ALR中存放的数据,为时间戳。)

1s的时间如何计算?

我们的RTC_CLK为32.768kHz,所以只要PRL中写入32767即可,即为2的15次方。 我们只需要在PRL的低16位寄存器中写入0x7FFF即可。

DIV寄存器存在的意义? 从上述能知道TR_CLK输出必须为1s。那么我们想要的到0.15s,应该怎么实现呢? 道理很简单,因为DIV是自减的,并且从32768一直减少到0,所需要的时间为1s。所以减少一个数,所用的时间为1/32768s,那么减少多少个数,就计时了0.15s呢? 1/32768s * n = 0.15 n = 0.15 * 32768 又因为DIV寄存器是可读的,所以我们就能实现0.15s的计时。

从框图中,还可以看到,只有秒中断和闹钟中断能触发中断,溢出是没有中断的。

STM32CubeMAX界面

读取STM32F103C8T6 内部的时钟(年月日时分秒),日历(星期x),1秒周期,通过串口输出到PC上位机

设置RCC

设置RTC 设置RTC参数 设置时钟树 创建工程

keil界面

在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;

}

在main.c中定义时间和日期的结构体用来获取时间和日期

RTC_DateTypeDef GetData; //获取日期结构体

RTC_TimeTypeDef GetTime; //获取时间结构体

在main函数的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);

编译运行结果如下:

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。