RTC:专门产生年月日时分秒日期和时间信息的定时器
部分芯片断掉主电源后VBAT会微弱的给整个电源供电
unix时间戳:秒数

由unix演变的系统(如Linux Windows 安卓)的计时系统都使用unix时间戳。

STM32时间戳:32位无符号数据类型,约2106年溢出。
世界各地unix时间戳(秒数)相同,不同地区的时间差异在转换为年月日时根据时区加上偏移量。
UTC&GMT:

UTC为现行时间标准。 UTC的秒数更精准,秒数所表示的时间间隔变化更小,利于科学研究。但为了满足人类生活需要,加入润秒机制(时间戳在转化为年月日时增大进制,如61秒进位1分钟)用于表示地球自转一周的时间。因此,使用UTC时在秒数 上精准有利于科学研究,转换为年月日时符合地球自转一周的时间,有利于日常生活。UNIX时间戳转换不考虑润秒,国家授时中心为标准时间。
时间戳转换:
time()函数在电脑里可直接读取电脑时间,在stm32离线裸机系统不行。如:
time_t数据类型实际上是int数据类型,struct tm数据类型实际上是封装的结构体类型,因此日期实际上是结构体。为结构体默认赋值法。
BKP模块
BKP简介

STM32引脚中VDD_1-3,VSS_1-3,VDDA(模拟),VSSA(模拟)皆是主电源,VBAT为备用电源。
后备区域:3.2KHZ振荡器,BKP和RTC都位于后备区域,后备区域由VDD供电,当系统断电时由VBAT供电。
BKP不同于flash,BKP虽使用备用电源VBAT,但掉电丢失,本质上是RAM存储器,flash掉电不丢失。
TAMPER侵入监测:先加默认上拉电阻,然后接设备外壳的防拆开关或触电到地,当外壳拆开时开关闭合,引脚产生下降沿,STM32监测到侵入事件,使BKP数据清零并申请中断。由于使用的是VBAT电源,主电源掉电依旧有效。
PC13,TAMPER,RTC共用一个端口。
BKP基本结构
(该数据寄存器为16位寄存器)

RTC的时钟输出位于BKP模块,同时外部可通过该输出引脚读取RTC的校准时钟,配合BKP内部的校准寄存器对RTC的误差进行校准。通常不使用RTC输出,直接通过APB1总线直接访问RTC相关寄存器读取值,再通过其他引脚输出即可。
RTC模块
RTC简介

DS1302:同样为实时时钟RTC外设,内部拥有年月日等寄存器,通过写入或读取对应寄存器操作相应信息。而STM32的RTC外设只有32位的可编程计数器,作为时间戳的秒计数器,通过软件计算得到年月日等时间信息。
RTCCLK来源可选上图三种,其中LSE为其专用时钟源,RTC_DIV为20位分频器,HSE需/128的原因是若其直接作为时钟源(8MHZ)则分频器无法将其分频到1HZ。
32.768KHZ:1.32KHZ频率为晶振工艺适合频率。 2.32768为2的15次方数,经过15位分频器自然溢出(记到最大值)便可得到1HZ。
**使用LSE原因:仅有LSE时钟可以通过VBAT供电,而RTC需要掉电继续计时。**其他两路仅作为特殊情况备选方案。
RTC框图

驱动RTC的时钟必须是1HZ信号,RTCCLK频率较高,因此需要分频器。RTC预分频器实际为计数器和重装载器,RTC_DIV为自减计数器,RTC_DIV从RTC_PRL的值减到0后产生溢出信号提供给RTC_CNT。RTC_CNT即为UNIX时间戳秒计数器。
RTC_ALR可设置闹钟,当RTC_CNT的值与RTC_ALR设置的值相等时,产生RTC_Alarm信号,可作为中断信号进入中断系统,也可唤醒待机状态下的STM32。闹钟值为定值,若想周期性使用则需每次使用完重新设定新值。
RTC中3个信号可作为中断源:1.RTC_Second,开启则每秒进入中断。2.RTC_Overflow,CNT计数器溢出触发,而CNT约2106年溢出,所以该中断无用。3.RTC_Alarm,如前文描述。
中断控制中SECF等F结尾为中断标志位,SECIE等IE则为中断使能。
RTC为APB1总线上设备。
灰色部分为后备区域,即主电源掉电后可用备用电源供电。
RTC基本结构

RTC所需电路 
由图得知,供电和晶振外接,BKP和RTC位于芯片内部。内外组合构成主电源驱动模块外的独立模块。
C1,C2为起振电容,为高质量的5pf---15pf的瓷介电容器。
RTC操作注意事项

事项二与事项四注释:PCLK频率远大于RTCCLK,若当APB1开启时立即读取RTC寄存器,此时RTC寄存器的值由于时钟频率低尚未上传到APB1总线上,使得读取的值有误(通常为0),因此需要等待RTC_CRL寄存器同步。事项四同理。
BKP&RTC模块寄存器:
1.BKP寄存器




2.RTC寄存器






BKP&RTC模块函数:
1.BKP函数


1.恢复缺省配置,即清除BKP所有寄存器。结果等同于将所有寄存器手动写零。
2.侵入检测有效电平,即高电平触发或者低电平触发。
3.侵入检测使能。
4.中断使能。
5.RTC引脚输出时钟信号(RTC校准时钟,RTC闹钟脉冲或者秒脉冲)
6.设置RTC校准值。
7.写BKP备份寄存器
8.读BKP备份寄存器
额外:备份寄存器访问使能
2.RTC函数
1)RCC相关函数


1.低速外部时钟使能。
2.低速内部时钟使能。若LSE不起振则可用LSI实验。
3.选择RTCCLK时钟源。
4.启动RTCCLK。
额外:获取标志位。启动始终后需等待LSERDY标志位置1,时钟才算启动完成。
2)RTC相关函数

1.配置RTC中断输出
2.RTC进入配置模式。在RTC的寄存器写入值需要进入配置模式,即置CRL寄存器的CNF位为1。
3.RTC退出配置模式。
4.获取CNT计数器的值,即读取时钟。
5.设置CNT计数器的值,即设置时钟。
6.设置RTC预分频器的值,实际上将值写入PRL重装寄存器中。
7.写入RTC闹钟值。
8.读取DIV余数寄存器的值,CNT的计数间隔通常为1s,读取余数寄存器可获得更精确细致的时间。
9.等待上次操作完成。对RTC任何寄存器的写操作都必须在前一次写操作结束后进行。该函数实际是循环函数,直至RTOFF状态位为1。
10.等待同步。APB1读取RTC寄存器时,需等待RTCCLK时钟。
模块实验
1.读写BKP
1)接线图

2)代码

3)实验现象
按键按下时写入2个寄存器的值+1.
若复位或者主电源掉电时,写入数据显示栏清空,而读取数据显示栏的值并未改变,为最后一次写入数据,则实验成功。
2.RTC实时时钟
1)接线图

2)初始化配置:


LSE时钟默认关闭,以节省功耗,需手动开启。
RCC_LSE_Bypass:时钟旁路,即不接晶振,直接从引脚输入指定频率信号。
等待写入函数可在每次写入之前或者之后调用均可,也可在之前和之后一并调用。
RTC部分函数封装时已设置进入配置模式和退出配置模式,此时无需手动进入,如配置分配系数函数和RTC闹钟配置函数:
3)设置RTC时间(伦敦&北京):



在C语言中1和01不同,写入01默认为8进制数,若将9改成09则程序报错,因为在8进制中数字9无效。
KEIL中的time.h文件与DevC++中的不同,如在RTC程序里time()函数无法使用,而在DevC++中该函数可获得电脑系统时间。STM32无法区分所在时区,gmtime函数被舍弃,localtime和mktime始终为0时区,即伦敦时间,需手动加偏移值。
4)读取RTC时间(伦敦&北京):


5)主函数:

6)程序现象

7)复位时间重置
此时程序每次复位时,时间都会重置,原因是每次复位时,都调用了初始化函数,而初始化函数里我们手动重置了时间。因此需要写入判断语句,当系统掉电而备用电源没掉电时,不执行初始化,都掉电时再执行初始化。实现方法为在BKP寄存器中随意写入数据,如果上电数据没清零,则备用电池没掉电。此时配置函数如下。


8)获取DIV并生成毫秒



(知识自学习专题,课程资料来源江协科技)