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

【经验分享】STM32F2 RTC

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:28

实时时钟介绍:

       STM32F207的实时时钟是一个独立的BCD定时/计数器。它提供一个日历时钟,两个可编程的定时器中断,1个具有中断能力的周期性可编程唤醒标志,同时RTC还包含自动唤醒单元,用于管理低功耗模式。

      两个32位的寄存器,包含了实时时钟的秒,分,时(12或24小时制),星期,日,月,年这些内容。这些内容都以BCD码存放在这两个寄存器中。

      同时,RTC模块会自动判断闰年与非闰年,并对2月分的天数进行自动处理,当然也会对其他月分的天数进行自动处理,它还支持Daylight saving time compensation(这个不知道怎么译了)功能。

     另外的32位寄存器包含了(可编程)闹钟的秒,分,时,星期,日期。

     RTC模块还具有数字校准功能,能够补偿由于晶体振荡器精度所致的任何偏差。

     上电复位后,所有与RTC相关的寄存器都自动进入保护模式,以防止意外的写操作发生。

注意:只要RTC的供电电压在正常工作范围内,则RTC永远不会停止工作,此时对于RTC来说,芯片的工作模式、低功耗模式以及芯片的复位等都不会对RTC造成影响。


9 B3 B' C  p* }

RTC的主要功能介绍:

       RTC单元的主要功能如下:

       (1)具有秒,分,时,星期,日,月,年的日历功能;

       (2)可通过软件编程的Daylight saving compensation;

       (3)两个具有中断功能的可编程闹钟,每个闹钟中断都可以被日历项(指的是秒,分,时,星期等)中的任何几项的组合触发;

       (4)自动唤醒单元可以产生一个周期性的标志,用于触发自动唤醒中断;

       (5)参考时钟检查:一个更高精度的第二时钟源(50或60Hz)可以用于提高日历时钟的精度;

       (6)可屏蔽的中断/事件:

              a. 闹钟A

              b. 闹钟B

              c. 唤醒中断

              d. 时间戳

              e. 修改检测(对IO引脚状态发生变化的检测)

       (7)数字校准电路(周期计数器校正),精度为50ppm;

       (8)时间戳功能用于事件保存(一个事件);

       (9)修改检测:1个事件修改的边沿检测(对于IO引脚,后面详述);

       (10)20个备分寄存器(80字节)在修改检测事件发生时时,备分寄存器将被复位;(有待确定)

       (11)RTC复用引脚输出功能(RTC_AFO)

               a. AFO_CALIB:512Hz时钟输出(使用LSE频率32.768KHz)该功能与引脚RTC_AF1相连;

               b. AFO_ALARM:闹钟A或闹钟B或唤醒中断(三个之中只能选定一个作为输出源),该功能与引脚RTC_AF1相连;

       (12)RTC复用引脚输入功能(RTC_AFI)

               a. AFI_TAMPER:修改事件检测,该功能与引脚RTC_AF1及RTC_AF2相连;

               b. AFI_TIMSTAMP:时间戳事件检测,该功能与引脚RTC_AF1及RTC_AF2相连接;

+ W4 A6 p4 n- H" u% N2 t7 u( _

RTC的时钟和预分频器:

       STM32F207可以使用三种时钟作为时钟源:LSE(外总低速振荡器,一般为32768Hz的晶体)、LSI(内部低频振荡器时钟)或者HSE(外部高速振荡器,最高1MHz)。在后面的介绍中还会对其配置方法进行详细说明。

       一个可编程的预分频器用于产生1Hz的时钟,用于更新日历时钟,为了降低功耗,这个预分频器又被分割成了两个预分频器:

      a. 7位的异步分频器,可以通过改变RTC_PRER寄存器中的PREDIV_A位对其进行配置;

      b. 13位的同步分频器,可以通过改变RTC_PRER寄存器中的PREDIV_B位对其进行配置。

注意:如果两个分频器同时使用,为了降低功耗,请尽量让异步分频器的分频因子更大一些。

      将同步分频器的分频因子设为128,将异步分频器的分频因子设为256,这时候就可以使用外部的32.768Hz的振荡器时钟信息来获取一个1Hz的内部时钟信号(ck_spre),对于分频器来说,其最低的分频因子为2,最大的分频因子为2的20次方,由此,对应的输入频率最大为大约1MHz。ck_spre的计算公式如下:

                                  F(ck_spre) = RTC_CLK/((PREDIV_S+1)*(PREDIV_A+1))

         ck_spre时钟可以被用于更新日历时钟,也可以被用作16位唤醒自动重装定时器的时基信号。为了获取较短的定时周期,16位的唤醒自动重装定时器了可以使用RTC_CLK经过可编程4位异步分频器后得到的时钟作为时基信号(后面还会说述)。

! _2 M2 Z9 g1 j' `( `  L4 Z

实时时钟和日历

         RTC的日期和时间寄存器通过与PCLK1(APB1 clock)同步的影子寄存器进行访问:

         a. RTC_TR寄存器用于存储RTC的时间数据

         b. RTC_DR寄存器用于存储RTC的日期数据

         每两个RTCCLK周期,当前日历的数据都会被COPY到影子寄存器中,然后RTC_ISR寄存器中的RSF位会被置位。但在停止和待机模式下,以上数据COPY的过程将不会发生。在退出这些模式后,影子寄存器会在2个RTCCLK周期后被更新。

         当应用程序读取日历寄存器时,实质就是访问影子寄存器中的内容。当读取RTC_TR和RTC_DR的时候,APB总线的时钟(fAPB)必须至少是RTC时钟(fRTCCLK)的7倍,以避免读取过程中出错。影子寄存器会随系统复位而被复位。


% T4 V* ?& U5 v2 Q

可编程闹钟

        RTC模块提供的两个可编程闹钟,闹钟A和闹钟B.可编程的闹钟功能可以通过设置RTC_CR寄存器中的ALRAIE与ALRBIE位来使能。如果日历时钟的秒,分,时,星期,及日期分别与闹钟寄存器RTC_ALRMAR及RTC_ALRMBR中的对应设置相匹配,则对应的标志位ALRAF和ALRBF将置位。每个日历项可以通过RTC_ALRMAR和RTC_ALRMBR寄存器中的MAKx位独立进行选中或屏蔽。而闹钟中断功能则可以通过设置RTC_CR寄存器中的ALRAIE与ALRBE位进行使能。

        闹钟A和闹钟B(如果通过RTC_CR寄存器中的OSE[0:1]位进行使能)可以通过芯片引脚进行AFO_ALARM输出。而输出的极性可以通过RTC_CR中的POL位进行配置。

注意:如果'秒'选项被选中(在RTC_ALRMAR或RTC_ALRMBR寄存器中的MSK0位置1),则RTC_PRER寄存器中的异步预分频器分频因子至少应该设置为3,以保证正确的执行。


9 [. n) Y' Q* J* ]$ Z- l* Z% X* W

周期和自动唤醒

          周期唤醒标志由1个16位的可编程自动重装向下计数器控制。唤醒定时器可以被扩展到17位。自动重装功能可以通过RTC_CR寄存器中的WUTE位进行使能。

          唤醒定时器的时钟输入可以是以下之一:

          a. RTC时钟(RTCCLK)被2/4/8/16分频之后的频率。当RTCCLK选择为LSE(32.768KHz)时,允许将唤醒中断的周期配置为从122us到32s,精度为61us。

          b. ck_spre(通常是1Hz的内部时钟),当ck_spre是1Hz的内部时钟时,允许以1秒的精度将唤醒中断时间配置为从1秒到36个小时,当然如此大的可编程时间范围会被分成两个部分,具体如下:

                     1 - 当WUCKSEL[2:1] = 1:0时,范围从1秒到18小时;

                     2 - 当WUCKSEL[2:1] = 1:1时,范围从18小时到36小时。在这种情况下,2的16次方被自动地加到16位计数器的当前值。初始化序列完成后,定时器开始向下计数。如果唤醒功能为使能状态,向下计数器则保持低功耗状态。当其计数到0时,RTC_ISR中的WUTF会自动置位,并且唤醒计数器会根据RTC_WUTR中的自动重装值进行自动重装。

注意:WUTF位必须由软件清除。

          当通过RTC_CR2中的WUTIE位使能周期唤醒中断时,当计数器中断发生时,就可以使器件退出低功耗模式。

          如果对RTC_CR寄存器中的OSEL[0:1]进行相应的配置,周期唤醒标志的变化可以影响AFO_ALARM输出。至于AFO_ALARM的输出极性则可以通过RTC_CR中的POL位进行设置。

         系统复位,以及各种低功耗模式(睡眠,停止,待机)对唤醒定时器都没有任何的影响。


( n& v5 z  B- i+ h

RTC的初始化,配置及使用请参考固件库(此处略去)

: \  B0 [8 Z( a. V& E

STM32F207的RTC与备分寄存器

         STM32F207具有20个32位的备分寄存器,能够存储共计80字节的内容,当入侵检测(前文中提到的“改变检查”)中断发生时将会被复位,而系统复位,以及系统从其他低功耗模式被唤醒都不会对RTC和BKP造成影响。备分寄存器(BKP)与RTC有什么关系呢,我们从实际来分析一下。我们的RTC和备分寄存器都是可以在系统掉电的情况下由电池进行供电的,假如没有BKP,当系统电源断开后,或者系统复位后,或者系统从低功耗模式被唤醒后,它定要对某些模块进行初始化,而这个时候RTC由电池供电,其数据具有连续性,如果系统不能判断RTC是否该重新初始化,那系统只能对其进行初始化导致系统时间回到默认,用户或上位机软件又得对其进行修改,增加了应用的复杂性。这个时候如果加上BKP,因为它也是可以由电池供电的,掉电丢失信息,意味着如果在电池供电正常的情况下,如果系统VDD掉电,BKP的内容就会保留下来,这样的话,我们在第一次配置好RTC后就可以通过在BKP中某个寄存器内写入一个特片标志值,便可以在系统复位后用于判断,避免对RTC的重配置。

       为了避免意外的写入操作,在系统复位后,对BKP和RTC的访问都被禁止,并且备分区BKP被保护起来。需要特殊的指令序列后才可以对其进行访问。

       举个例子说明,假如第一次配置完RTC后我们往备分寄存器0中写入一个值:0x32F2,则每次复位后我们配置RTC就用下面一段代码即可:

  1. 7 v  c' G2 k! _+ e6 B9 U5 T
  2. <p style="line-height: 26px;"><font color="rgb(77, 77, 77)"><font face="-apple-system, " "=""><font style="font-size: 16px">  if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)
    $ @0 z7 L7 f* _5 P: @2 L
  3.   {  
    - H4 T; I2 R. J  `- |% W
  4.     /* RTC configuration  */3 o% E3 {7 h' _
  5.     RTC_Config();</font></font></font></p><p style="line-height: 26px;"><font color="rgb(77, 77, 77)"><font face="-apple-system, " "=""><font style="font-size: 16px">    /* Configure the RTC data register and RTC prescaler */
    / b% t9 M, [4 \6 F
  6.     RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;% n2 ~# u- T& g4 i( }) k, }
  7.     RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
    3 k8 Y) ?9 h5 V! H9 a9 t
  8.     RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;( o! H- {2 C' B" z2 C' t! n  v
  9.    ; f: @9 k% a4 C- }( {: J$ {0 {: A
  10.     /* Check on RTC init */0 D4 @! [' K8 a# I+ |- ]6 |
  11.     if (RTC_Init(&RTC_InitStructure) == ERROR)/ r3 D8 ^) f, g8 B4 l: U
  12.     {
    " y% z! `) s% X* m
  13.       printf("\n\r        /!\\***** RTC Prescaler Config failed ********/!\\ \n\r");
    : V' }& O8 {* l8 f* l
  14.     }</font></font></font></p><p style="line-height: 26px;"><font color="rgb(77, 77, 77)"><font face="-apple-system, " "=""><font style="font-size: 16px">    /* Configure the time register */
    ; p2 W0 q( l* Q9 E% i/ ?- ~6 Y
  15.     RTC_TimeRegulate();
    / B( z) b3 ~- y" q
  16.   }</font></font></font></p>
复制代码

! @( `8 M+ [  j' W

当然里面有几个函数,需要你根据自已的需要进行选择性的配置和修改。

" V, @/ D3 Q: O0 k! k6 G# `" c, R$ J
收藏 评论0 发布时间:2021-12-1 22:28

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版