深入解析STM32实时时钟(RTC)的工作原理和功能

RTC

RTC的本质很简单,就是一个时钟经过精确分频最后得到的一个1Hz的时钟,也可以说是计数器,其他大部分功能都是基于这个计数器设计的数字逻辑。

本文讲的RTC是基于STM32F030来讲的,相比与F1系列的RTC来说,M0的将很多原本需要软件实现的功能硬件化了,使用起来更加便利。

先说说STM32F030的RTC有些什么功能:

  1. 集成日历功能,不用像STM32F103一样需要软件算法来做;
  2. 夏令时补偿;
  3. 闹钟功能;
  4. 集成了周期性自动唤醒单元;
  5. 外部参考时钟;
  6. 时钟平移校准(亚秒级);
  7. 数字校准
  8. 时间戳;
  9. 入侵检测;
  10. 备份寄存器

先看看RTC的框图:

从框图中圈出来的部分可以看到,上面提到的RTC功能,大部分在框图上面都有体现,接下来我们按照RTC的功能点讲一讲各个功能的详细内容

RTC的时钟分频

在详述每个功能点之前,我们先了解下RTC的核心,即1Hz的时钟的来历。
从框图中可以看到RTC的时钟来源有3个,时钟源先经过一个精密校准后,再经过一个异步预分频器和一个同步预分频器后,得到的即是我们想要的1Hz的时钟,这个时钟将被送到日历模块,供日历计数用。
我们常用的一个时钟源是一个32.768kHz的低速外部时钟(LSE),为什么是这个特殊的频率呢?因为这个时钟经过分频后可以得到一个完美的1Hz的时钟供给日历模块使用,最大程度上保证时钟的精确性,当然,实际上来说,32.768kHz的时钟并不是完全精确的,所以就会导致实际上的时间会在一段时间后跑偏,且随时间的推移,偏差逐渐扩大,所以我们小时候用电子手表时,会发现时间在我们调整准确后,慢慢的又会出现一点偏差,偏差可以被RTC内部逻辑调整缩小,后面会详细讲述。

32.768kHz为什么比较容易分频得到1Hz时钟呢?
由于我们单片机采用的是二进制数,所以分频器也是以二进制为基础进行分频,32.768kHz在不断的二分频(15次)后,能得到一个精确的1Hz时钟,也就是1秒钟的时间。

而其他两个时钟源(HSE/32)和LSI经过两个分频器后得到的时钟往往都是约等于1Hz,长久计数会产生较大的误差,因为它们的频率在经过无数次2分频后,一般来说,最后都不是一个整数,都是游离在1Hz左右。

理论上来说,如果想要一个1Hz的时钟,一个分频器就可以做到,为什么会有两个分频器呢?因为STM32F030可以精确到亚秒级,在经过第一个时钟分频器后,此时得到的时钟ck_apre(一般为256Hz)会作为亚秒计数器,提供亚秒级别的计数。

日历模块

日历模块是我觉得STM32F030相比与103最大的便捷之处,不需要软件算法的干预,就可以在预设初始年月日,时分秒的基础上开始计时,且还能自动计算星期,闰年也会被自动计算。
日历模块有三个寄存器:时间寄存器, 寄存器,亚秒寄存器

日历寄存器是有两套的,一套是RTC域的本体,一套是由系统时钟控制的影子寄存器。每隔两个RTC_CLK,就会将本体寄存器中的值复制到影子寄存器中。

由于RTC的特性,所以很多情况下在芯片断电后,希望内部的时间系统不受到影响,所以RTC域通常被要求单独供电,即在芯片断电后,RTC还能够正常工作,当下次芯片上电后,影子寄存器在和RTC域本体的日历寄存器同步后,仍然能得到正确时间。

夏令时

支持夏令时功能,可以将日历寄存器中的时间增加或减少一个小时。
利用 SUB1H 或 ADD1H,软件只需单次操作便可在日历中减去或增加一个小时,无需执行
整个初始化步骤,还可以使用 BKP 位来记录是否曾经执行过此操作
因为有的国家实行夏令时制度,需要在夏天时,将全国时间集体向前拨一个小时,在夏令时结束后,又将时间往回拨一个小时,所以030集成了这个功能(有兴趣的可以百度一下夏令时)。

闹钟功能

闹钟功能就是通过在闹钟寄存器设置一个预定时间,当日历寄存器中的时间和闹钟寄存器时间匹配后,会产生一个闹钟信号,在配置闹钟中断以后,也会生成中断。

要注意的是闹钟寄存器是没有年份和月份的,只有日期,时分秒及亚秒。闹钟寄存器还有一个掩码功能(MSK),开启后日期,时、分、秒及亚秒都可以被单独屏蔽,不和日历寄存器中对应值作比较。

周期性自动唤醒单元

配置此功能后,可以在器件进入低功耗模式后,根据配置时间在到达预定时间后使器件退出低功耗模式。可配置的时间范围为1s到36小时。

外部参考时钟,时钟平移校准,数字校准

把这三个功能放在一起的原因是,三个功能都是RTC的时钟精度进行调整的功能,但是三个功能调整时间的方法和调整精度上又是不同的。

外部参考时钟(一般为50Hz或者60Hz):
通过特定GPIO口输入一个参考时钟源,外部参考时钟的精度我们认为是高于现在RTC使用的32.768kHz时钟精度的(32.768kHz由于偏差,并非一定为该数值),具体的做法是用1Hz时钟每次在边沿时检测是否有高精度外部时钟的边沿,如果两个时钟的时钟沿正好对齐。则认为1Hz时钟无偏差,若时钟不对齐,会对异步预分频寄存器进行重载,微调后续1Hz时钟边沿,使其对齐外部参考时钟边沿。

时钟平移校准:
参考一个更高精度的远程时钟,可以对当前的RTC时钟进行秒级或者亚秒级的增加或减少时间。我的理解是,获取到一个我们认为的更高精度的时钟当前值后,手动对自身RTC的值进行调整,以提高RTC的精度。

数字校准:
数字校准是三种校准方式中最为细微的校准方式,分为正校准和负校准。
正校准可以在8秒或者16秒的时钟周期内,对RTC的源时钟。RTC_CLK,在每2的11次方的脉冲内,多插入一个脉冲。
负校准可以在32秒的时钟周期内,在每2的20次方的脉冲内,减少1~255个脉冲,由寄存器决定具体减少数值。
由于RTC的32.768KHz的时钟源多少都会存在一点偏差,数字校准可以做到从源头上对RTC的精度进行调整,但是首先我们得获取到时钟源的具体偏差值才能更好的对偏差进行校准。

时间戳和入侵检测

时间戳
时间戳寄存器和日历寄存器一样,只是不会计数,当有时间戳事件发生的时候,日历寄存器的当前值就会被保存到时间戳寄存器中。
当RTC的RTC_TS引脚检测到时间戳事件时,当前的日历寄存器值就会被保存到时间戳寄存器。
入侵检测
除此之外,入侵检测的发生也可以被当成时间戳时间,当特定的GPIO引脚检测到入侵事件时,时间戳就会记下当前入侵事件发生的时间。
入侵检测事件是当特定的入侵检测引脚被触发时(可以设置触发的电平状态及保持时间),擦除RTC的备份域寄存器,也可以生成入侵检测中断,从停止模式和待机模式唤醒。
备份寄存器
备份寄存器是一小段空间,大小为16字节,可以由用户自定义写入数据,当主电源域掉电后,只要RTC域有电,备份寄存器内的数据就不会丢失。但是当入侵事件发生时,备份寄存器会被复位,数据丢失。

总的来说,RTC本身其实并不复杂,尤其是F030的RTC,简单易用,但是它在整个芯片系统中都是一个很特殊的模块,因为它可以被单独供电,且RTC域的寄存器值是不受系统复位影响的,当系统电源域有电时,它由VDD供电,当系统电源域掉电时,它立刻会切换至后备电源域供电。大致示意图如下:

物联沃分享整理
物联沃-IOTWORD物联网 » 深入解析STM32实时时钟(RTC)的工作原理和功能

发表评论