文章目录
1. Unix时间戳
2. UTC/GMT
3. 时间戳转换
4. BKP简介
5. BKP基本结构
6. RTC简介
7. RTC框架图
8. RTC基本结构
9. 代码示例
1. Unix时间戳
实时时钟,本质上是一个定时器,专门用来产生年月日时分秒。
Unix 时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒。
时间戳是一个计数器数值,从1970年1月1日0时0分0秒开始,到现在总共所经过的秒数。
时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量。
世界上所有时区的秒计数器相同,不同时区通过添加偏移来得到当地时间。
2. UTC/GMT
GMT(Greenwich Mean Time)格林尼治标准时间是一种以地球自转为基础的时间计量系统。它将地球自转一周的时间间隔等分为24小时,以此确定计时标准。
UTC(Universal Time Coordinated)协调世界时是一种以原子钟为基础的时间计量系统。它规定铯133原子基态的两个超精细能级间在零磁场下跃迁辐射9,192,631,770周所持续的时间为1秒。当原子钟计时一天的时间与地球自转一周的时间相差超过0.9秒时,UTC会执行闰秒来保证其计时与地球自转的协调一致。
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*); | 日期时间转换为字符串(自定义格式) |
4. BKP简介
BKP(Backup Registers)备份寄存器,本质上就是RAM储存器。
BKP可用于存储用户应用程序数据。当VDD(2.0~3.6V)电源被切断,他们仍然由VBAT(1.8~3.6V)维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位。
TAMPER引脚产生的侵入事件将所有备份寄存器内容清除。
RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲。
存储RTC时钟校准寄存器。
用户数据存储容量:20字节(中容量和小容量)/ 84字节(大容量和互联型)。
手册建议:
- 如果没有外部电池,建议VBAT引脚接到VDD,就是VBAT和主电源接到一起,并且再连接一个100nf的滤波电容
5. BKP基本结构
STM32后备区域的特性:
- 当VDD主电源掉电时,后备区域仍然可以由VBAT的备用电池供电。
- 当VDD主电源上电时,后备区域供电会自动从VBAT切换到VDD。
数据寄存器:
- 16位(存储2个字节)。
- 中小容量设备有DR1~DR10,总共10个数据寄存器,每个寄存器存储2个字节,总容量为20字节。
- 大容量和互联型设备有42个数据寄存器(DR)。
TAMPER引脚:
- 用于引入检测信号(上升沿/下降沿),清除BKP所有内容以保证数据安全。
时钟输出:
- 可以将RTC相关时钟从PC13位置的RTC引脚输出供外部使用。
- 输出校准时钟时,可以配合校准寄存器对RTC的误差进行校准。
6. RTC简介
RTC (Real Time Clock):实时时钟。
RTC是一个独立的定时器,可为系统提供时钟和日历的功能。
RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD(2.0 - 3.6V)断电后可借助VBAT(1.8 - 3.6V)供电继续走时。
32位的可编程计数器,可对应Unix时间戳的秒计数器。
20位的可编程预分频器,可适配不同频率的输入时钟。
RTCCLK可选择三种RTC时钟源:
- HSE时钟除以128(通常为8MHz/128)
- LSE振荡器时钟(通常为32.768KHz)
- LSI振荡器时钟(40KHz)
时钟信号解释
- HSE = 高速外部时钟信号
- HSI = 高速内部时钟信号
- LSI = 低速内部时钟信号
- LSE = 低速外部时钟信号
- H (High):高速,L (Low):低速,E (External):外部,I (Internal):内部
使用说明
- 高速时钟:一般供内部程序运行和主要外设使用。
- 低速时钟:一般供RTC、看门狗等东东使用。
- 只有选择LSE振荡器时钟,才能实现RTC主电源掉电继续走时的功能。
7. RTC框架图
可编程预分频器:
RTC_CNT
每秒自增,因此驱动计数器的时钟TR_CLK
需要是1Hz的信号。实际提供RTC模块的时钟(RTCCLK)频率较高,因此RTCCLK经过20位RTC预分频器(1~2^20分频),保证输出给计数器的频率为1Hz。- 灰色填充区域均是后备区域。
分频和计数:
- 输入时钟RTCCLK,经过RTC预分频器(由重装载寄存器RTC_PRL和余数寄存器RTC_DIV控制),计数器重装值ARR和CNT进行分频。
RTC_CNT:
- 可以作为Unix时间戳的秒计数器,再借用
time.h
的函数可以方便地得到年月日时分秒。
闹钟寄存器RTC_ALR:
- 32位寄存器,用来设置闹钟。设置闹钟时,将ALR写入一个秒数,当CNT的值等于ALR设定的闹钟值时,就会产生RTC_Alarm闹钟信号。通过中断系统,在闹钟中断里执行相应操作。
- 同时,闹钟信号可以让STM32退出待机模式。
- 此外,这个闹钟值是一个定值,只能响一次。若想实现周期闹钟,在每次闹钟响过后,都需要重新设置下一次闹钟时间。
中断信号
- RTC_Second(秒中断):来自于CNT的输入时钟。开启此中断后,程序会每秒进入一次RTC中断。
- RTC_Overflow(溢出中断):来自CNT右边,表示CNT的32位计数器计满溢出时触发一次中断。
- RTC_Alarm(闹钟中断):当计数器的值和闹钟值相等时触发中断,同时可以唤醒设备退出待机模式。
中断标志位和中断输出控制
- **F(Flag)**结尾的是对应的中断标志位。
- **IE(Interrupt Enable)**结尾的是中断使能。
- 最后三个信号通过一个或汇聚到NVIC中断控制器。
APB1总线和APB1接口
- 程序读写寄存器的地方可以通过APB1总线完成,RTC位于APB1总线上的设备。
退出待机模式:唤醒机制
- 闹钟信号和WKUP引脚都可以唤醒设备,退出待机模式。
8. RTC基本结构
RTCCLK的配置和信号处理流程
时钟来源配置
- 最左边的RTCCLK时钟来源在RCC中配置,可以从三个时钟中选择一个作为RTCCLK。
时钟预分频
- 选择的RTCCLK经过预分频器对时钟进行分频。
- 余数计数器是一个自减计数器,存储当前的计数值。
- 重装寄存器决定计数目标和分频值。
- 分频后得到1Hz的秒计数信号,传递给32位计数器,每秒自增一次。
闹钟设定
- 32位计数器下有一个32位的闹钟值,可以设定闹钟时间。
中断信号触发
- 右侧有三个信号可以触发中断:秒信号、计数器溢出信号和闹钟信号。
- 这三个信号通过中断输出控制,进行中断使能。
- 启用的中断信号才能传递到NVIC,然后向CPU申请中断。
程序配置步骤
配置数据选择器:选择RTCCLK时钟来源。
配置重装寄存器:选择分频系数。
配置32位计数器
- 进行日期时间的读写。
- 如果需要闹钟,配置32位闹钟值。
配置中断
- 启用中断,再配置NVIC。
- 最后,编写对应的中断函数。
9. 代码示例
STM32读写备份寄存器和实时时钟
STM32读写备份寄存器和实时时钟-CSDN博客