你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

RTC实时时钟,步骤超细详解,一文看懂RTC

[复制链接]
STMCU 发布时间:2020-9-29 10:09
什么是RTC

RTC (Real Time Clock):实时时钟

RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。


1_meitu_1.jpg


在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。


RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。


两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时( 12 或 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。

上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写访问。

无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。



RCT特征:

● 可编程的预分频系数:分频系数高为220。
● 32位的可编程计数器,可用于较长时间段的测量。
● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟 频率的四分之一以上)。
● 可以选择以下三种RTC的时钟源:
     ● HSE时钟除以128;
     ● LSE振荡器时钟;
     ● LSI振荡器时钟

● 2个独立的复位类型:
     ● APB1接口由系统复位;
     ● RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位

● 3个专门的可屏蔽中断:
     ● 1.闹钟中断,用来产生一个软件可编程的闹钟中断。

     ● 2.秒中断,用来产生一个可编程的周期性中断信号(长可达1秒)。

     ● 3.溢出中断,指示内部可编程计数器溢出并回转为0的状态。


RTC时钟源:
三种不同的时钟源可被用来驱动系统时钟(SYSCLK):

● HSI振荡器时钟
● HSE振荡器时钟
● PLL时钟

这些设备有以下2种二级时钟源:

● 40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。 RTC用于从停机/待机模式下自动唤醒系统。
● 32.768kHz低速外部晶体也可用来通过程序选择驱动RTC(RTCCLK)。



RTC原理框图
2_meitu_2.jpg



RTC时钟的框图还是比较简单的,这里我们把他分成 两个部分:

APB1 接口:用来和 APB1 总线相连。 此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总 线时钟驱动,用来与 APB1 总线连接。

通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。

RTC 核心接口:由一组可编程计数器组成,分成 两个主要模块 。



3_meitu_3.jpg g)





第一个模块是 RTC 的 预分频模块,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个 TR_CLK 周期中 RTC 产生一个中断(秒中断)。



4_meitu_4.jpg





第二个模块是一个 32 位的可编程计数器 (RTC_CNT),可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记 录 4294967296 秒,约合 136 年左右,作为一般应用,这已经是足够了的。



RTC具体流程:

RTCCLK经过RTC_DIV预分频,RTC_PRL设置预分频系数,然后得到TR_CLK时钟信号,我们一般设置其周期为1s,RTC_CNT计数器计数,假如1970设置为时间起点为0s,通过当前时间的秒数计算得到当前的时间。RTC_ALR是设置闹钟时间,RTC_CNT计数到RTC_ALR就会产生计数中断,

  • RTC_Second为秒中断,用于刷新时间,
  • RTC_Overflow是溢出中断。
  • RTC Alarm 控制开关机





RTC时钟选择

使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作.所以RTC一般都时钟低速外部时钟LSE,频率为实时时钟模块中常用的32.768KHz,因为32768 = 2^15,分频容易实现,所以被广泛应用到RTC模块.(在主电源VDD有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式).



RTC复位过程

除了RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。
RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器仅能通过备份域复位信号复位。

系统复位后,禁止访问后备寄存器和RCT,防止对后卫区域(BKP)的意外写操作



读RTC寄存器

RTC内核完全独立于APB1接口,软件通过APB1接口对RTC相关寄存器访问。但是相关寄存器只在RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。所以软件必须先等待寄存器同步标志位(RTC_CRL的RSF位)被硬件置1才读。



配置RTC寄存器

必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、
RTC_CNT、RTC_ALR寄存器。

另外,对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询
RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是’1’
时,才可以写入RTC寄存器。



RTC时钟源

RTC是一个独立的时钟源

5_meitu_5.jpg




RTC寄存器
  • RTC控制寄存器 (RTC_CRH, RTC_CRL)
  • RTC预分频装载寄存器 (RTC_PRLH, RTC_PRLL)
  • RTC预分频余数寄存器 (RTC_DIVH, RTC_DIVL)
  • RTC计数器寄存器 (RTC_CNTH, RTC_CNTL)
  • RTC闹钟寄存器 (RTC_ALRH ,RTC_ALRL)



RTC控制寄存器高位——RTC_CRH 寄存器
6_meitu_6.jpg


作用:配置3个专门的可屏蔽中断(溢出中断、闹钟中断、秒中断)使能。

注意:系统复位后所有的中断被屏蔽,因此可通过写RTC寄存器来
确保在初始化后没有挂起的中断请求。当外设正在完成前一次写操作时(标志位RTOFF=0),不
能对RTC_CRH寄存器进行写操作。



RTC控制寄存器低位——RTC_CRL 寄存器

7_meitu_7.jpg



一般用到该寄存器的 3,4,5位
  • 第 3 位为寄存器同步标志位,我们在修改控制寄存器 RTC_CRH/CRL 之前,必须先判断该位,是否已经同步了,如果没有则等待同步
  • 第 4 位为配置标位,在软件修改 RTC_CNT/RTC_ALR/RTC_PRL 的值的时候,必须先软件置位该位,以允许进入配置模式
  • 第 5 位为 RTC 操作位,该位由硬件操作,软件只读。通过该位可以判断上次对 RTC 寄存器的操作是否完成,如果没有,我们必须等待上一次操作结束才能开始下一次,也就是判断RTOFF位是否置位。



三个位总结如下:

① 修改CRH/CRL寄存器,必须先判断RSF位,确定已经同步。
② 修改CNT,ALR,PRL的时候,必须先配置CNF位进入配置模式,修改完之后,设置CNF位为0退出配置模式

③ **同时在对RTC相关寄存器写操作之前,必须判断上一 8_meitu_8.jpg






RTC 预分频装载寄存器——(RTC_PRLH/RTC_PRLL) 寄存器

作用:配置 RTC 时钟的分频数,

比如我们使用外部 32.768K 的晶振作为时钟的输入频率,那么我们要设置这两个寄存器的值为 7FFFh(32767),就可获得周期为1秒钟的信号。

9_meitu_9.jpg




RTC预分频器余数寄存器(RTC_DIVH、RTC_DIVL)

作用: 和他的名字一样,获得余数,也就是获取更精确的计时,比如:0.1s ,0.01 s等

寄存器是只读寄存器,其值在RTC_PRL或RTC_CNT寄存器中的值发生改变后,由硬件重新装载。


10_meitu_10.jpg






RTC 计数器寄存器——RTC_CNTX 寄存器

作用:存放计数器内的计数值。也就是用来记录时钟时间

该寄存器由 2 个 16 位的寄存器组成 RTC_CNTH 和 RTC_CNTL,总共 32 位,当进行读操作时,直接返回计数器内的计数值(系统时间)

11_meitu_11.jpg






RTC 计数器寄存器——RTC 闹钟寄存器(RTC_ALRH、RTC_ALRL)

作用: RTC时钟中断控制寄存器

该寄存器也是由 2 个 16 位的寄存器组成 RTC_ALRH 和 RTC_ALRL,也就是32位,当可编程计数器的值与RTC_ALR中的32位值相等时,即触发一个闹钟事件,并且产生RTC闹钟中断。


12_meitu_12.jpg






BKP备份寄存器

备份寄存器是42个16位的寄存器。可用来存储84个字节数据。
它们处在备份区域,当VDD电源切断,仍然由VBAT维持供电。

当系统在待机模式下被唤醒,或者系统复位或者电源复位,它们也不会复位。
执行以下操作将使能对后备寄存器和RTC访问:

  • 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备时钟。
  • 设置寄存器PWR_CR的DBP位,使能对RTC和后备寄存器的访问

一般用 BKP 来存储 RTC 的校验值或者记录一些重要的数据,


13_meitu_13.jpg



配置RTC寄存器:

1.查询RTOFF位,知道RTOFF的值为1.

2.置CNF值为1,进入配置模式。

3.对一个或者多个RTC寄存器进行写操作。

4.清除CNF标志位,退出配置模式。

5.查询RTOFF,直到RTOFF位变1,已确认写操作已经完成。

仅当CNF标志位被清除时,写操作才能进行,这个操作至少需要3个RTCCLK周期。



RTC相关库函数
  • RTC时钟源和时钟操作函数:

  1. void RCC_RTCCLKConfig(uint32_t  CLKSource);//时钟源选择
  2. void RCC_RTCCLKCmd(FunctionalState NewState)//时钟使能
复制代码


  • RTC配置函数(预分频,计数值):
  1. void RTC_SetPrescaler(uint32_t PrescalerValue);//预分频配置:PRLH/PRLL
  2. void RTC_SetCounter(uint32_t CounterValue);//设置计数器值:CNTH/CNTL
  3. void RTC_SetAlarm(uint32_t AlarmValue);//闹钟设置:ALRH/ALRL
复制代码


  • RTC中断设置函数:


  1. void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//CRH
复制代码

  • RTC配置函数:

  1. void RTC_EnterConfigMode(void);//允许RTC配置 :CRL位 CNF
  2. void RTC_ExitConfigMode(void);//退出配置模式:CRL位 CNF
复制代码

  • RTC同步函数:
  1. void RTC_WaitForLastTask(void);//等待上次操作完成:CRL位RTOFF
  2. void RTC_WaitForSynchro(void);//等待时钟同步:CRL位RSF
复制代码


  • RTC相关状态位获取清除函数:
  1. FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG);
  2. void RTC_ClearFlag(uint16_t RTC_FLAG);
  3. ITStatus RTC_GetITStatus(uint16_t RTC_IT);
  4. void RTC_ClearITPendingBit(uint16_t RTC_IT);
复制代码


  • 其他相关函数(BKP等)
  1. PWR_BackupAccessCmd();//BKP后备区域访问使能
  2. RCC_APB1PeriphClockCmd();//使能PWR和BKP时钟
  3. RCC_LSEConfig();//开启LSE,RTC选择LSE作为时钟源       
  4. PWR_BackupAccessCmd();//BKP后备区域访问使能
  5. uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);//读BKP寄存器
  6. void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);//写BKP
复制代码


配置RTC步骤
  • ①使能PWR和BKP时钟:
  1. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
复制代码


  • ② 使能后备寄存器访问:

  1. PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后备寄存器访问
复制代码

  • ③复位备份区域,开启外部低速振荡器。

  1. BKP_DeInit();//复位备份区域
复制代码



  • ④ 配置RTC时钟源,使能RTC时钟:

  1. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //选择 LSE 作为 RTC 时钟(RCC_RTCCLKSource_LSI 和 RCC_RTCCLKSource_HSE_Div128)
  2. RCC_RTCCLKCmd(ENABLE); //使能 RTC 时钟
复制代码

  • ⑤ 设置RTC预分频系数:RTC_SetPrescaler();
  1. RTC_EnterConfigMode();/// 允许配置       
  2. RTC_SetPrescaler(32767); //设置RTC预分频的值
  3. RTC_WaitForLastTask();        //等待最近一次对RTC寄存器的写操作完成
复制代码


  • ⑥ 设置时间:RTC_SetCounter();

  1. RTC_EnterConfigMode();/// 允许配置
  2. void RTC_SetCounter(uint32_t CounterValue);
  3. RTC_WaitForLastTask();        //等待最近一次对RTC寄存器的写操作完成
复制代码



  • ⑦开启相关中断(可选):

  1. void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能 RTC 秒中断
复制代码

  • ⑧编写中断服务函数:


  1. RTC_IRQHandler();
复制代码

  • ⑨部分操作要等待写操作完成和同步。

  1. RTC_WaitForLastTask();//等待最近一次对RTC寄存器的写操作完成
  2.    RTC_WaitForSynchro();        //等待RTC寄存器同步
复制代码



收藏 评论1 发布时间:2020-9-29 10:09

举报

1个回答
likang1202 回答时间:2020-9-29 17:31:42
还是标准库呢

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版