RTC的定义:

一个掉电后还继续运行的定时器。

所说的掉电,是指主电源VDD 断开的情况,为了RTC 外设掉电继续运行,必须接上锂电池给STM32 RTC、备份发卡通过VBAT  引脚供电。当主电源VDD 有效时,由VDDRTC 外设供电;而当VDD 掉电后,由VBAT RTC 外设供电。但无论由什么电源供电,RTC  中的数据都保存在属于RTC  的备份域中,若主电源VDD VBAT 都掉电,那么备份域中保存的所有数据将丢失。备份域除了RTC 模块的寄存器,还有42 16 位的寄存器可以在VDD  掉电的情况下保存用户程序的数据,系统复位或电源复位时,这些数据也不会被复位。

RTC  的定时器特性来说,它是一个32 位的计数器,只能向上计数。它使用的时钟源有三种,分别为高速外部时钟的128 分频(HSE/128 )、低速内部时钟LSI 以及低速外部 时钟LSE;使HSE 分频时钟或LSI 的话,在主电源VDD 掉电的情况下,这两个时钟来源都

会受到影响,因此没法保证RTC 正常工作。因此RTC 一般使用低速外部时钟LSE,在设计中,频率通常为实时时钟模块中常用的32.768KHz,这是因为32768 = 215次方,分频容易实现,所以它被广泛应用到RTC 模块。在主电源VDD 有效的情况下(待机)RTC还可以配置闹钟事件使STM32 退出待机模式。

 

RTC框图:

 

 

 

 

    框图中浅灰色的部分都是属于备份域的,在VDD 掉电时可在VBAT 的驱动下继续运行。这部分仅包括RTC  的分频器,计数器,和闹钟控制器。若VDD电源有效,RTC  可以触发RTC_Second(秒中断)RTC_Overflow(溢出事件)RTC_Alarm( 闹钟中断)。从结构图可以分析到,其中的定时器溢出事件无法被配置为中断。若STM32 原本处于待机状态,可由闹钟事件或WKUP 事件(外部唤醒事件,属于EXTI 模块,不属于RTC)使它退出待机模式。闹钟事件是在计数器RTC_CNT 的值等于闹钟寄存器RTC_ALR 的值时触发的。

    在备份域中所有寄存器都是16 位的,RTC 控制相关的寄存器也不例外。它的计数器 RTC_CNT 32 位由RTC_CNTL RTC_CNTH 两个寄存器组成,分别保存定时计数值的低16 位和高16 位。在配置RTC 模块的时钟时,通常把输入的32768Hz RTCCLK 进行32768分频得到实际驱动计数器的时钟TR_CLK = RTCCLK/32768= 1 Hz,计时周期为1秒,计时器在TR_CLK 的驱动下计数,即每秒计数器RTC_CNT 的值加1。 由于备份域的存在,使得RTC 核具有了完全独立于APB1 接口的特性,也因此对RTC寄存器的访问要遵守一定的规则。

    系统复位后,默认禁止访问后备寄存器和RTC,防止对后备区域(BKP)的意外写操作。执行以下操作使能对后备寄存器和RTC 的访问:

  (1) 设置RCC_APB1ENR 寄存器的PWREN BKPEN 位来使能电源和后备接口时钟。

  (2) 设置PWR_CR 寄存器的DBP 位使能对后备寄存器和RTC 的访问。

设置后备寄存器为可访问后,在第一次通过APB1 接口访问RTC 时,因为时钟频率的差异,所以必须等待APB1 RTC 外设同步,确保被读取出来的RTC 寄存器值是正确的。 若在同步之后,一直没有关闭APB1 RTC 外设接口,就不需要再次同步了。

   如果内核要对RTC 寄存器进行任何的写操作,在内核发出写指令后,RTC 模块在3

RTCCLK 时钟之后,才开始正式的写RTC 寄存器操作。由于RTCCLK  的频率比内核主频低得多,所以每次操作后必须要检查RTC 关闭操作标志位RTOFF,当这个标志被置1 时, 写操作才正式完成。

 

UNIX计时元年:

被设置为格林威治时间1970 1 1 0 0 0 秒。

UNIX时间戳:

即为当前时间相对于UNIX 计时元年经过的秒数。

 

RTC使用步骤:

  1. RTC  区域的时钟比APB时钟慢,访问前需要进行时钟同步,只要调用库函数 RTC_WaitForSynchro  即可,而如果修改了RTC的寄存器,又需要调用RTC_WaitForLastTask 函数确保数据已写入。
  2. 默认情况下,RTC 所属的备份域禁止访问,可使用库函数PWR_BackupAccessCmd 使能访问,使能后才能访问RTC相关的寄存器;若希望修改RTC 的寄存器,还需要进一步使能RTC 控制寄存器的CNF 位使能寄存器配置。
  3. 使用RCC 相关的库函数选择RTC 使用的时钟后,可以使用库RTC_SetPrescaler 进行分频,一般会把RTC 时钟分频得到1Hz 的时钟。
  4. RTC 外设中最重要的就是计数器以及闹钟寄存器了,它们可以使用RTC_SetCounterRTC_GetCounter 以及RTC_SetAlarm 库函数操作。利用RTC_SetCounter 可以向RTC 的计数器写入新数值,通常这些数值被设置为时间戳以更新时间。RTC_GetCounter 函数则用于在RTC 正常运行时获取当前计数器的值以获取当前时间。RTC_SetAlarm 函数用于配置闹钟时间,当计数器的值与闹钟寄存器的值相等时,可产生闹钟事件或中断,该事件可以把睡眠、停止和待机模式的STM32 芯片唤醒。

 

posted on 2018-07-03 19:26  lzd626  阅读(579)  评论(0编辑  收藏  举报