STM32-Unix时间戳和BKP备份寄存器以及RTC实时时钟

本内容基于江协科技STM32视频学习之后整理而得。

1. Unix时间戳

1.1 Unix时间戳简介

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

image.png

1.2 UTC/GMT

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

1.3 时间戳转换

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*); 日期时间转换为字符串(自定义格式)

image.png

2. BKP备份寄存器

2.1 BKP简介

  • BKP(Backup Registers)备份寄存器

  • BKP可用于存储用户应用程序数据。当VDD(2.03.6V)电源被切断,他们仍然由VBAT(1.83.6V)维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位

  • TAMPER引脚产生的侵入事件将所有备份寄存器内容清除

  • RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲

  • 存储RTC时钟校准寄存器

  • 用户数据存储容量:

    20字节(中容量和小容量)/ 84字节(大容量和互联型)
    在STM32引脚定义图中,标红色的都是供电引脚,VDD和VSS_1、2、3是内部数字部分电路的供电。VDDA和VSSA是内部模拟部分电路的供电。该四组以VDD开头的供电,都是系统的主电源。在正常使用STM32时,这四组供电
    全部都需要接到3.3V的电源上。VBAT是备用电池供电引脚,如果要使用STM32内部的BKP和RTC,该引脚必须接备用电池。用来维持BKP和RTC在VDD主电源掉电后的供电。备用电池只有一根正极的供电引脚,接电池时,电池正极接到VBAT,电池负极和主电源的负极接在一起供地。

2.2 BKP基本结构

image.png

  • 橙色区域可以称为后备区域,功能是当VDD主电源掉电时,后备区域仍然可以由VBAT的备用电池供电。当VDD主电源上电时,后备区域供电会由VBAT切换到VDD。也就是,主电源有电时,VBAT不会用到,这样可以节省电池电量。
  • BKP位于后备区域。BKP主要有数据寄存器、控制寄存器、状态寄存器和RTC时钟校准寄存器。数据寄存器是主要部分,用来存储数据的。每个数据寄存器都是16位的,一个数据寄存器可以存2个字节。中小容量的有DR1~DR10,所以容量是20字节。
  • TAMPER侵入检测,当产生上升沿和下降沿时,清除BKP所有的内容,以保证安全。
  • 时钟输出,可以从PC13位置的RTC引脚输出出去,供外部使用。当输出校准时钟时,再配合校准寄存器,可以对RTC的误差进行校准。

2.3 BKP库函数

// 缺省配置,手动清空BKP所有的数据寄存器
void BKP_DeInit</
### STM32 RTC 时间戳实现方法 在STM32微控制器中,RTC(Real-Time Clock)模块可以通过配置生成或处理时间戳。以下是具体的方法: #### 1. 配置RTC硬件 首先需要初始化RTC外设并启用其功能。这通常涉及以下几个步骤: - 启用LSE(Low Speed External Oscillator)作为RTC时钟源。 - 初始化RTC结构体`RTC_HandleTypeDef hrtc`。 - 使用HAL库中的函数完成RTC的初始化。 ```c // 定义RTC句柄 RTC_HandleTypeDef hrtc; void MX_RTC_Init(void) { // LSE使能代码省略... /** Initialize RTC and set the Time and Date */ hrtc.Instance = RTC; hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND; // 自动预分频为1秒 hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } } ``` 上述代码展示了如何通过HAL库初始化RTC模块[^3]。 --- #### 2. 获取当前时间并转换为时间戳 为了将RTC的时间转换为Unix时间戳,需先读取RTC的实际时间日期,再将其转化为秒计数器形式。以下是一个完整的流程: ##### (1)读取RTC时间与日期 使用`HAL_RTC_GetTime()``HAL_RTC_GetDate()`分别获取当前的时间日期信息。 ```c RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; if (HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); // 处理错误 } if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); // 处理错误 } ``` 此处调用了两个HAL库函数来提取RTC的时间日期数据。 ##### (2)构建`struct tm`对象 C语言的标准头文件`<time.h>`提供了一个名为`struct tm`的数据结构用于表示分解后的本地时间。可以利用该结构存储从RTC获得的信息。 ```c #include <time.h> struct tm current_tm = { .tm_sec = sTime.Seconds, .tm_min = sTime.Minutes, .tm_hour = sTime.Hours, .tm_mday = sDate.Date, .tm_mon = sDate.Month - 1, // 注意月份是从0开始 .tm_year = sDate.Year + 100 // 年份相对于1900年的差值 }; ``` 此部分代码说明了如何将RTC返回的具体字段映射至`struct tm`成员变量上[^1]。 ##### (3)计算时间戳 借助于`mktime()`函数可将`struct tm`类型的局部时间转成以秒为单位的时间戳。 ```c time_t timestamp = mktime(&current_tm); if (timestamp == -1) { Error_Handler(); // 如果发生错误则进入异常处理逻辑 } else { printf("Current Unix Timestamp: %ld\n", (long)timestamp); } ``` 这里实现了最终的时间戳计算过程,并打印结果以便验证正确性。 --- #### 3. 将时间戳写入RTC BKP寄存器保存 如果希望持久化存储某个特定时刻对应的时间戳,则可通过备份寄存器(BKP Registers)来进行操作。 ```c #define TIME_STAMP_BKP_REGISTER RTC_BKP_DR1 uint32_t save_timestamp(uint32_t ts_value) { __HAL_RCC_BACKUPRESET_FORCE(); // 强制复位备份区域 __HAL_RCC_BACKUPRESET_RELEASE(); // 解除复位状态 HAL_PWR_EnableBkUpAccess(); // 允许访问备份域 HAL_RTCEx_BKUPWrite(&hrtc, TIME_STAMP_BKP_REGISTER, ts_value); return ts_value; } ``` 以上片段描述了一种安全的方式把时间戳数值储存在指定位置供后续恢复用途。 反之亦然,在必要时候可以从这些专用地址重新加载之前记录下来的内容出来加以应用。 --- ### 总结 综上所述,基于STM32平台上的RTC组件配合相应软件接口能够轻松达成对于UNIX风格下标准化表达方式即所谓“时间戳”的创建、解析及其长期保留等功能需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值