学习STM32第十六天

发布于:2024-04-23 ⋅ 阅读:(19) ⋅ 点赞:(0)

RTC实时时钟

一、简介

RTC是一个独立的BCD格式定时器,提供一个时钟日历,两个可编程报警中断,一个具有中断功能周期性可编程唤醒标志,RTC和时钟配置系统处于后备区域。

通过两个32位寄存器以BCD格式实现秒、分钟、小时(12、24小时制),日(星期)、月和年等信息。只要有电(VBAT提供),RTC就永不停止。RTC时钟源RTCCLK可从LSE、LSI和Divided HSE三者中选择,通常情况下使用LSE。 32768 = 2 15 32768 = 2^{15} 32768=215,经过15位分频器的自然溢出即可得到1Hz的频率,15位的计数器从0开始计数,计到最大值32767自然溢出,这个溢出信号就是1Hz信号。
RTC框图
RTCCLK先进行平滑校准,然后进行非同步预分频,最后进行同步预分频得到1Hz。相关频率计算公式如下: f C K − A P R E = f R T C C L K P R E D I V − A + 1 f_{CK - APRE}=\frac {f_{RTCCLK}}{PREDIV-A + 1} fCKAPRE=PREDIVA+1fRTCCLK f C K − A P R E f_{CK - APRE} fCKAPRE是用于为二进制 R T C − S S R RTC-SSR RTCSSR子秒下计数器计时,减到0, R T C − S S R RTC-SSR RTCSSR会重新加载 P R E D I V − S PREDIV-S PREDIVS的内容。 f C K − S P R E = f C K − A P R E P R E D I V − S + 1 f_{CK - SPRE}=\frac {f_{CK-APRE}}{PREDIV-S + 1} fCKSPRE=PREDIVS+1fCKAPRE f C K − S P R E f_{CK - SPRE} fCKSPRE可用于更新日历或者作为16位唤醒自动重载定时器的时基单元。RTC基本结构如下
RTC基本结构
RTC初始化与配置

  • 使能PWR和BKP时钟
  • 设置PWR_CR的DBP位,使能对BKP和RTC的访问
  • 对RTC寄存器的写操作都必须在前一次写操作结束后进行

RTC外设与BKP(备份寄存器)和PWR(电源)有关,这里一起讲解。

二、Unix时间戳

Unix事件戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不用考虑闰秒。时间戳存储在一个秒计数器中,是32位/64位的整型变量,不同时区通过添加偏移来得到当地时间。由于地球自转一周时间不固定,GMT对时间的定义更标准,为消除计时一天和地球自转一周的误差,通过执行闰秒
来保证计时一天的时间与地球自转一周的时间协调一致。

  • UTC(Universal Time Coordinated)协调世界时是一种以原子钟为基础的时间计量系统。
  • GMT(Greenwich Mean Time)格林尼治标准时间是一种以地球自转为基础的时间计量系统。

时间戳转换,C语言的time.h模块提供了时间获取和时间戳转换的相关函数。可以方便地进行秒计数器、日期时间和字符串之间的转换。
RTC时间戳转换
上面几个函数之间关系如下
RTC时间戳转换关系图
相应的实例代码如下

#include <stdio.h>
#include <time.h>
/*验证时间戳功能*/
time_t time_cnt;            //默认情况下是64位有符号秒计数器类型
struct tm time_date;        //tm结构体包含事件表示的元素,其中年份是从1900开始计算
char *time_str;             //指向一个表示时间的字符串

/*time_t time(time_t *)函数获取系统时钟,不能用于离线裸机系统*/
time_t Get_timestamp()
{
    return time(NULL);
}
/*struct tm* gmtime(const time_t*)函数将秒计数器转换为日期时间GMT格式*/
struct tm* Get_timeGMT(time_t* timestamp)
{
    return gmtime(timestamp);
}
/*struct tm* localtime(const time_t*)函数将秒计数器转换为当地日期时间,自动判断时区*/
struct tm* Get_localtime(time_t* timestamp)
{
    return localtime(timestamp);
}
/*time_t mktime(struct tm*)函数将当地日期时间转换为秒计数器*/
time_t localtime_stamp(struct tm* localtime)
{
    return mktime(localtime);
}
/*char* ctime(const time_t*)函数将秒计数器转换为字符串*/
char* timetostr(time_t* timestamp)
{
    return ctime(timestamp);
}
int main()
{
    time_cnt = Get_timestamp();
    printf("Time_cnt = %d\n", time_cnt);
    time_date = *Get_timeGMT(&time_cnt);
    printf("\n");
    printf("Time: %d-%d-%d  %d:%d:%d\n", time_date.tm_year + 1900, time_date.tm_mon + 1, time_date.tm_mday, time_date.tm_hour, time_date.tm_min, time_date.tm_sec);
    printf("\n");
    time_date = *Get_localtime(&time_cnt);
    printf("localTime: %d-%d-%d  %d:%d:%d\n", time_date.tm_year, time_date.tm_mon, time_date.tm_mday, time_date.tm_hour, time_date.tm_min, time_date.tm_sec);
    printf("\n");
    printf("localTime_stamp: %d\n", localtime_stamp(&time_date));
    printf("\n");
    printf("%s\n", timetostr(&time_cnt));

    return 0;
}

三、BKP

BKP(Backup Register)备份寄存器,可用于存储用户应用程序数据。VDD断开后,由VBAT维持供电,只要有电数据就不会丢失。通过备份域复位执行复位,由篡改/入侵检测(tamper detection)事件触发,一个篡改检测事件复位所有备份寄存器(防止外部窃取数据)。STM32F4xxBKP拥有20个32位寄存器,存储80字节用户应用数据。这里给出BKP基本结构
BKP基本结构


网站公告

今日签到

点亮在社区的每一天
去签到