1.BKP简介
- VBAT备用电池供电引脚,如使用STM32内部的BKP和RTC,引脚必须接备用电池,用来维持BKP和RTC,在VDD主电源掉电后的供电,这里备用电池只有一跟正极的引脚,接电池时,电池正极接VBAT,电池负极和主电源负极接在一起,供地。
- TAMPER引脚产生的侵入事件将所有备份寄存器内容清除,TAMPER是一个接到stm32外部的引脚,这个TAMPER是一个安全保障设计,如果你做一个安全系数非常高的设备,设备需要有防拆功能,然后BKP里也存储了一些敏感数据,这些数据不能被别人窃取或者篡改,那你就可以使用这个TAMPER引脚的侵入检测功能。
- 设计电路时,TAMPER引脚可以先加一个默认的上拉或者下拉电阻,然后引一根线到你的设备外壳的防拆开关或触点,别人一拆开你的设备触发开关,就会在TAMPER引脚产生上升沿或者下降沿,这样STM32就检测到侵入事件了,这时BKP的数据会自动清零,并且申请中断,你在中断里还可以继续保护设备,比如清除其他存储器数据,然后设备锁死,这样来保障设备的安全,另外主电源断电后,侵入检测仍然有效,这样即使设备关机也能防拆。
- RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲,其中外部用设备测量RTC校准时钟,可以对内部RTC微小的误差进行校准。
- 闹钟脉冲或者秒脉冲可以输出出来,为别的设备提供这些信号,这是RTC时钟输出的功能。因为PC13、TAMPER和RTC这三个引脚共用一个端口,所以这三个功能同一时间只能使用一个。
- 存储RTC时钟校准寄存器,这个可以配合上面这个校准时钟输出的功能,结合一些测量方法,可以对RTC进行校准,那这两个功能实际上就是RTC的配置,设计者目前就是把这两个RTC的功能放在BKP里了。
- 我们使用的C8T6是中容量设备,所以可以看出BKP的容量其实非常小,一般只能用来存储少量的参数。
具体看手册第五章
2.BKP基本结构
- 这个图中橙色部分我们可以叫做后备区域,BKP处于后备区域,但后备区域不只有BKP,还有RTC的相关电路也位于后备区域。
- STM32后备区域的特性就是当VDD主电源掉电时,后备区域仍然可以由VBAT的备用电池供电,当VDD主电源上电时,后备区域供电会切换到VDD,主电源有电时VBAT不会用的,这样可以节省电池电量。
- 然后BKP是位于后备区域的,BKP里主要有数据寄存器、控制寄存器、状态寄存器和RTC时钟校准寄存器,其中数据寄存器是主要部分,用来存储数据的,每个数据寄存器都是16位的,也就是一个数据寄存器可以存两个字节,那对于中容量和小容量的设备,里面有DR1、DR2一直到DR10总共十个数据寄存器,那一个寄存器存两个字节,所以容量是20个字节。总共是42个数据寄存器,容量是84个字节。
- BKP功能,这里的侵入检测,可以从PC13位置的TAMPER引脚引入一个检测信号,当TAMPER产生上升沿或者下降沿时,清除BKP所有的内容以保证安全。
- 时钟输出,可以把RTC的相关时钟,从PC13位置的RTC引脚输出数据供外部使用,其中输出较准时钟时,再配合这个校准寄存器,可以对RTC的误差进行校准。
- 核心寄存器模块 数据寄存器:包含多个 16 位寄存器(如 DR1 [15:0]、DR2 [15:0]…DR42 [15:0]),用于存储用户数据或配置参数。一个寄存器存两个字节,所以DR1~DR10就是20各字节,中小容量。其中,“大容量和互联型” 设备支持更多数据寄存器(如 DR42)。
- 控制与状态相关寄存器:
- 控制寄存器:用于配置模块工作模式、参数等。
- 状态寄存器:反馈模块当前工作状态(如中断、错误等)。
- RTC 时钟校准寄存器:对 RTC 时钟进行精度校准,确保计时准确性。
3.RTC简介
- RTC与51中的DS1302的使用相似
- 32位的可编程计数器,原理便是使用的UNIX的时间戳,
- 20位的可编程预分频器,可适配不同频率的输入时钟,保证分频器输出给计数器的频率为1Hz,计时才正确。
RTCCLK频率比较高,需要加一个分频器,来降频。加了一个20位的可编程预分频器,可以对选择的输入时钟进行1~2^20的范围分频,这可适配不同频率的输入时钟。
H开头是高速,L开头是低速。E结尾是外部,I结尾是内部。高速时钟一般供内部程序运行和主要外设使用,低速时钟一般供RTC,看门狗使用。
- RTCCLK有三个来源,
-
第一个是OSC引脚接的HSE外部高速晶振,这个晶振是主晶振,我们一般都用的8MHZ,通过128分频可以产生RTCCLK信号,因为这个8MHz的晶振太快了,如果不提前分频,直接给RTCCLK,后续即使再通过RTC的20位分频器,也分不到1Hz这么低的频率。 -
中间是,
时钟来源是LSE,外部低速晶振(一般使用),我们在oc32这两个引脚,接上外部低速晶振,这个晶振产生的时钟,可以直接提供给RTCCLK,这个osc32的晶振,是内部RTC的专用时钟,通常跟RTC有关的晶振都是统一的数值,就是32.768KHz,一方面是32.768KHz这个值附近的频率,是晶振工艺比较合适的频率,另一方面是2的15次方等于32768,所以32.768KHz,经过一个15位分频器的自然溢出,就能很方便地得到1Hz的频率。 -
第三路,
时钟源,来自于LSI,内部低速rc振荡器,LSI固定是40KHz,如果选择LSI当做RTCCLK,后续再经过40k的分频,就能得到1Hz的计数时钟了,当然内部的RC振荡器,一般精度没有外部晶振高,所以LSI给RTCCLK,l可以当做一个备选方案,另外LSI还可以提供给看门狗。
-
总结: 最常用的就是中间这一路,外部32.768KHz的晶振,提供RTCCLK的时钟。
- 第一个原因就是中间这一路,32.768KHz的晶振本身就是专供RTC使用的,上下这两路其实是有各自的任务,上面这一路主要作为系统主时钟,下面这一路主要作为看门狗时钟,他们只是顺带可以备选当做RTC的时钟。
- 另外一个原因,只有中间这一路的时钟可以通过VBAT备用电池供电,上下两路时钟在主电源断电后是停止运行的,所以要想实现RTC主电源掉电继续走时的功能,必须得选择中间这一路的RTC专用时钟,如果选择的是上下两路时钟,主电源断电后时钟就暂停了,这显然会导致走时出错。
4.RTC框图
左边这一块是核心的分频和计数计时部分,右边这一块是中断输出使能和NVIC部分,上面这一块是APB1总线读写部分,下面这块是PWR关联的部分.灰色填充的部分,都处于后备区域
-
首先看分频和计数器计数部分,这一块的输入时钟是RTCCLK,RTCCLK的来源需要在所以RTCCLK进来,首先需要经过RTC预分频器进行分频,这个分频器由两个计算器组成,上面这个是重装载寄存器RTC_PRL,下面这个RTC_DIV手册里叫做余数寄存器,实际上是计数器的作用。最终通过TR_CLK给予计数器1HZ的时钟
- 那在这里上面这个PRL就是计数目标,我们写入六那就是七分频,写九那就是十分频,因为计数指包含了零。
- 然后下面这个DIV就是每来一个时钟计一个数的用途了,当然这个DIV计数器啊是一个自减计数器,每来一个输入时钟,DIV的值自减一次,自减到0时再来一个输入时钟,DIV输出一个脉冲产生溢出信号,同时DIV从PRL获取重装值,回到重装值继续自减。
-
计数计时部分,32位可编程计数器,RTC_CNT就是计时最核心的部分,把这个计数器看作是Unix时间戳的秒计数器,这样借助time.h的函数,就可以很方便地得到年月日时分秒了。
- 这个RTC还设计的有一个闹钟寄存器RTC_ALR,这个ALR也是一个32位的寄存器,作用是设置闹钟,我们可以在ALR写一个秒数,设定闹钟,当CNT的值跟ALR设定的闹钟值一样时,也是这里的等号啊,如果两个值相等就代表闹钟响了,这时就会产生RTC_Alarm闹钟信号,通往右边的中断系统,在中断函数里你可以执行相应的操作。(相当于定时器的CNT)
-
中断部分的,在左边这里有三个信号可以触发中断:
-
RTC_Second秒中断,它的来源就是cnt的输入时钟,如果开启这个中断,那么程序就会每秒进一次RTC中断。
-
RTC_Overflow溢出中断,它的来源是CNT的右边,意思就是CNT的32位计数器计满溢出了,会触发一次中断,所以这个中断一般不会触发。这个CNT定义的是无符号数,到2106年才会溢出,所以这个中断在2106年会触发一次,你可以让芯片罢工,然后提示当前设备过老,请及时更换,但在2106年之后这个stm32的RTC就不太好用了。
-
**RTC\_Alarm闹钟中断**,当计数器和闹钟值相等时触发中断,同时闹钟信号可以把设备从待机模式唤醒。
-
-
中断信号到右边这里,这一块是中断标志位和中段输出控制,这些F结尾的是对应的中断标志位,IE结尾(Interrupt ENABLE)的是中断使能,最后三个信号通过一个或门,汇聚到NVIC中断控制器。
-
APB1总线和APB1接口,就是程序读写寄存器的地方,读写寄存器可以通过APB1总线来完成。另外,RTC是APB1总线上的设备。
5.RTC基本结构
- 基本结构
-
最左边是RTCCLK时钟来源,这块需要在RCC里配置,三个时钟选择一个当做RTCCLK,之后RTCCLK先通过预分频器对时钟进行分频,
-
余数寄存器(DIV)是一个自减计数器,存储当前的计数值,
-
重装寄存器(PRL)是计数目标,决定分频值(PSC),分频之后,得到1Hz的秒计数信号通向32位计数器(CNT),一秒自增一次,下面还有个32位的闹钟值,可以设定闹钟,如果不需要闹钟的话,下面这一块可以不用管。
-
然后右边有三个信号可以触发中断,分别是秒信号、计数器溢出信号和闹钟信号,三个信号先通过中断输出控制进行中断使能,使能的中断才能通向NVIC,然后向CPU申请中断。
-
**在程序中,配置数据选择器,可以选择时钟来源,配置重装寄存器(PRL),可以选择分频系数(PSC),配置32位计数器(CNT),可以进行日期时间的读写,需要闹钟的话,配置32位闹钟值即可,需要中断的话,先允许中断,再配置NVIC,最后写对应的中断函数即可,这是RTC外设的主要内容。**
6.RTC使用注意事项
-
如果你要使用BKP或者RTC,都要先执行这两步,
- 第一步开启PWR和BKP的时钟
- 第二步使用PWR使能BKP和RTC的访问。
-
第二条:这一步对应代码里的一个库函数就是RTC等待同步,一般在刚上电的时候调用一下这个函数就可以。要求我们在APB1总线刚开机时,要等一下RTCCLK,只要RTCCLK来一个上升沿,RTC把它的寄存器的值同步到APB1总线上,这样之后读取的值就都是没问题的了,这是设计细节的一个问题,只需要在初始化时调用一个等待同步的函数就行了。
-
这一条其实比较简单,就是RTC会有一个进入配置模式的标志位(CNF位),把这一位置1才能设置时间,其实这个操作在库函数中,每个写寄存器的函数,它都自动帮我们加上了这个操作,所以我们就不用再单独调用函数进入配置模式了。
-
这个操作也是调用一个等待的函数就行了,就写入之前要等待一下,如果上一次的写入还没完成,你就别急着写下一次了,或者说每次写入之后,你要等待RTOFF为1,只有RTOFF为1才表示写完成。
- 为什么要有这个操作呢,其实还是因为这里的PCLK1和RTCCLK时钟频率不一样,你用PCLK1的频率写入之后,这个值还不能立刻更新到RTC的寄存器里,因为RTC寄存器是由RTCCLK驱动的,所以PCLK1写完之后,得等一下RTCCLK的时钟,RTCCLK来个上升沿,值更新到RTC寄存器里,整个写作过程才算结束了。在代码里也就是调用一个等待函数的事。