STM32
直播中

打马过草原

9年用户 890经验值
擅长:可编程逻辑 电源/新能源
私信 关注
[问答]

要经过哪几个步骤的配置才能使实时时钟RTC正常工作呢

实时时钟RTC是什么?由哪些部分组成呢?
要经过哪几个步骤的配置才能使实时时钟RTC正常工作呢?

回帖(1)

谭子薇

2021-11-22 10:07:54
  STM32 RTC 时钟简介
  实时时钟( RTC)是一个独立的定时器。 RTC 模块拥有一组连续计数的计数器,在相应软
  件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
  RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒
  后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以
  防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域( BKP)写
  保护。
  RTC 由两个主要部分组成(见下图)。第一部分(APB1 接口)用来和 APB1 总线相连。此单元
  还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。 APB1 接口由 APB1 总线时钟
  驱动,用来与 APB1 总线接口。
  另一部分(RTC 核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是 RTC 的
  预分频模块,它可编程产生最长为 1 秒的 RTC 时间基准 TR_CLK。 RTC 的预分频模块包含了
  一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,
  则在每个 TR_CLK 周期中 RTC 产生一个中断(秒中断)。第二个模块是一个 32 位的可编程计数
  器,可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记录 4294967296
  秒,约合 136 年左右,作为一般应用,这已经是足够了的。
  RTC 还有一个闹钟寄存器 RTC_ALR,用于产生闹钟。系统时间按 TR_CLK 周期累加并与
  存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许
  实时时钟( RTC)是一个独立的定时器。 RTC 模块拥有一组连续计数的计数器,在相应软
  件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
  RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒
  后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以
  防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域( BKP)写
  保护。
  RTC 由两个主要部分组成(见下图)。第一部分(APB1 接口)用来和 APB1 总线相连。此单元
  还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。 APB1 接口由 APB1 总线时钟
  驱动,用来与 APB1 总线接口。
  另一部分(RTC 核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是 RTC 的
  预分频模块,它可编程产生最长为 1 秒的 RTC 时间基准 TR_CLK。 RTC 的预分频模块包含了
  一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,
  则在每个 TR_CLK 周期中 RTC 产生一个中断(秒中断)。第二个模块是一个 32 位的可编程计数
  器,可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记录 4294967296
  秒,约合 136 年左右,作为一般应用,这已经是足够了的。
  RTC 还有一个闹钟寄存器 RTC_ALR,用于产生闹钟。系统时间按 TR_CLK 周期累加并与
  存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许
  位,比较匹配时将产生一个闹钟中断。
  
  RTC 内核完全独立于 RTC APB1 接口,而软件是通过 APB1 接口访问 RTC 的预分频值、计
  数器值和闹钟值的。但是相关可读寄存器只在 RTC APB1 时钟进行重新同步的 RTC 时钟的上升
  沿被更新, RTC 标志也是如此。这就意味着,如果 APB1 接口刚刚被开启之后,在第一次的内
  部寄存器更新之前,从 APB1 上都处的 RTC 寄存器值可能被破坏了(通常读到 0)。因此,若
  在读取 RTC 寄存器曾经被禁止的 RTC APB1 接口,软件首先必须等待 RTC_CRL 寄存器的 RSF
  位(寄存器同步标志位, bit3)被硬件置 1。
  接下来,我们介绍一下 RTC 相关的几个寄存器。首先要介绍的是 RTC 的控制寄存器, RTC
  总共有 2 个控制寄存器 RTC_CRH 和 RTC_CRL,两个都是 16 位的。 RTC_CRH 的各位描如下
  图所示:
  
  该寄存器用来控制中断的,我们这一节将要用到秒钟中断,所以在该寄存器必须设置最低
  位为 1,以允许秒钟中断。我们再看看 RTC_CRL 寄存器。该寄存器各位描述如下图所示:
  
  这一节我们用到的是该寄存器的 0、 3~5 这几个位,第 0 位是秒钟标志位,我们在进入闹
  钟中断的时候,通过判断这位来决定是不是发生了秒钟中断。然后必须通过软件将该位清零(写
  0)。第 3 位为寄存器同步标志位,我们在修改控制寄存器 RTC_CRH/CRL 之前,必须先判断该
  位,是否已经同步了,如果没有则等待同步,在没同步的情况下修改 RTC_CRH/CRL 的值是不
  行的。第 4 位为配置标位,在软件修改 RTC_CNT/RTC_ALR/RTC_PRL 的值的时候,必须先软
  件置位该位,以允许进入配置模式。第 5 位为 RTC 操作位,该位由硬件操作,软件只读。通过
  该位可以判断上次对 RTC 寄存器的操作是否完成,如果没有,我们必须等待上一次操作结束才
  能开始下一次操作。
  第二个要介绍的寄存器是 RTC 预分频装载寄存器,也有 2 个寄存器组成, RTC_PRLH 和
  RTC_PRLL。这两个寄存器用来配置 RTC 时钟的分频数的,比如我们使用外部 32.768K 的晶振
  作为时钟的输入频率,那么我们要设置这两个寄存器的值为 32767,以得到一秒钟的计数频率。
  RTC_PRLH 的各位描述如下:
  
  在介绍完这两个寄存器之后,我们介绍 RTC 预分频器余数寄存器,该寄存器也有 2 个寄存
  器组成 RTC_DIVH 和 RTC_DIVL,这两个寄存器的作用就是用来获得比秒钟更为准确的时钟,
  比如可以得到 0.1 秒,或者 0.01 秒等。该寄存器的值自减的,用于保存还需要多少时钟周期获
  得一个秒信号。在一次秒钟更新后,由硬件重新装载。这两个寄存器和 RTC 预分频装载寄存器
  的各位是一样的,这里我们就不列出来了。
  接着要介绍的是 RTC 最重要的寄存器, RTC 计数器寄存器。该寄存器由 2 个 16 位的寄存
  器组成 RTC_CNTH 和 RTC_CNTL,总共 32 位,用来记录秒钟值(一般情况下)。此两个计数
  器也比较简单,我们也不多说了。注意一点,在修改这个寄存器的时候要先进入配置模式。
  最后我们介绍 RTC 部分的最后一个寄存器, RTC 闹钟寄存器,该寄存器也是由 2 个 16 为的寄
  存器组成 RTC_ALRH 和 RTC_ALRL。总共也是 32 位,用来标记闹钟产生的时间(以秒为单位),
  如果 RTC_CNT 的值与 RTC_ALR 的值相等,并使能了中断的话,会产生一个闹钟中断。该寄
  存器的修改也要进入配置模式才能进行。
  因为我们使用到备份寄存器来存储 RTC 的相关信息(我们这里主要用来标记时钟是否已经
  经过了配置),我们这里顺便介绍一下 STM32 的备份寄存器。
  备份寄存器是 42 个 16 位的寄存器(大容量产品才有,我们的 MiniSTM32 开发板使用的是
  STM32F103RBT6,属于小容量产品,只有 10 个 16 为的寄存器),可用来存储 84 个字节的用
  户应用程序数据。他们处在备份域里,当 VDD 电源被切断,他们仍然由 VBAT 维持供电。当
  系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位。
  此外, BKP 控制寄存器用来管理侵入检测和 RTC 校准功能。
  复位后,对备份寄存器和 RTC 的访问被禁止,并且备份域被保护以防止可能存在的意外的
  写操作。执行以下操作可以使能对备份寄存器和 RTC 的访问:
  1)通过设置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位来打开电源和后备接口的时
  钟
  2)电源控制寄存器(PWR_CR)的 DBP 位来使能对后备寄存器和 RTC 的访问。
  我们一般用 BKP 来存储 RTC 的校验值或者记录一些重要的数据,相当于一个 EEPROM,
  不过这个 EEPROM 并不是真正的 EEPROM,而是需要电池来维持它的数据。关于 BKP 的详细
  介绍请看《 STM32 参考手册》的第 47 页, 5.1 一节。
  最后,我们还要介绍一下备份区域控制寄存器 RCC_BDCR。该寄存器的个位描述如下:
  
  
  RTC 的时钟源选择及使能设置都是通过这个寄存器来实现的,所以我们在 RTC 操作之前
  先要通过这个寄存器选择 RTC 的时钟源,然后才能开始其他的操作。
  寄存器介绍就给大家介绍到这里了,我们下面来看看要经过哪几个步骤的配置才能使 RTC 正常
  工作。 RTC 正常工作的一般配置步骤如下:
  1)使能电源时钟和备份区域时钟。
  前面已经介绍了,我们要访问 RTC 和备份区域就必须先使能电源时钟和备份区域时钟。这
  个通过 RCC_APB1ENR 寄存器来设置。
  2)取消备份区写保护。
  要向备份区域写入数据,就要先取消备份区域写保护(写保护在每次硬复位之后被使能),
  否则是无法向备份区域写入数据的。我们需要用到向备份区域写入一个字节,来标记时钟已经
  配置过了,这样避免每次复位之后重新配置时钟。
  3)复位备份区域,开启外部低速振荡器。
  在取消备份区域写保护之后,我们可以先对这个区域复位,以清除前面的设置,当然这个
  操作不要每次都执行,因为备份区域的复位将导致之前存在的数据丢失,所以要不要复位,要
  看情况而定。然后我们使能外部低速振荡器,注意这里一般要先判断 RCC_BDCR 的 LSERDY
  位来确定低速振荡器已经就绪了才开始下面的操作。
  4)选择 RTC 时钟,并使能。
  这里我们将通过 RCC_BDCR 的 RTCSEL 来选择选择外部 LSI 作为 RTC 的时钟。然后通过
  RTCEN 位使能 RTC 时钟。
  5)设置 RTC 的分频,以及配置 RTC 时钟。
  在开启了 RTC 时钟之后,我们要做的就是设置 RTC 时钟的分频数,通过 RTC_PRLH 和
  RTC_PRLL 来设置,然后等待 RTC 寄存器操作完成,并同步之后,设置秒钟中断。然后设置
  RTC 的允许配置位( RTC_CRH 的 CNF 位),设置时间(其实就是设置 RTC_CNTH 和 RTC_CNTL
  两个寄存器)。
  6)更新配置,设置 RTC 中断。
  在设置完时钟之后,我们将配置更新,这里还是通过 RTC_CRH 的 CNF 来实现。在这之后
  我们在备份区域 BKP_DR1 中写入 0X5050 代表我们已经初始化过时钟了,下次开机(或复位)
  的时候,先读取 BKP_DR1 的值,然后判断是否是 0X5050 来决定是不是要配置。接着我们配
  置 RTC 的秒钟中断,并进行分组。
  7)编写中断服务函数。
  最后,我们要编写中断服务函数,在秒钟中断产生的时候,读取当前的时间值,并显示到
  TFTLCD 模块上。
  通过以上几个步骤, 我们就完成了对 RTC 的配置,并通过秒钟中断来更新时间。接下来我
  们将进行下一步过程。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分