BKP简介:
- BKP(Backup Registers)备份寄存器
- BKP可用于存储用户应用程序数据。当VDD(系统主电源2.0~3.6V)电源被切断,他们仍然由VBAT(备用电池电源1.8~3.6V)维持供电。
当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位(清除)
- TAMPER(侵入检测)引脚产生的侵入事件将所有备份寄存器内容清除
- RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲
- 存储RTC时钟校准寄存器
- 用户数据存储容量:20字节(就是有10个DR,每个DR有十六位(两个字节))(中容量和小容量)/ 84字节(就是有42个DR)(大容量和互联型)
BKP基本结构:
后备区域:特性是,当VDD主电源掉电时,后备区域仍然可以由VBAT的备用电池供电。当VDD供电时,会切换到主电源供电,就是当主电源有电时,VBAT不会用到,可以节省电池电量。
橙色部分:后备区域,BKP处于后备区域
BKP里主要有:DR数据寄存器(16位)、CR控制寄存器、SR状态寄存器和RTC时钟校准寄存器这些东西。
BKP的库函数:
- 恢复缺省配置
可以手动清除BKP所有的寄存器(因为BKP有备用电池时,掉电不清零,上电复位也不清零。)
2. 用来配置TAMPER侵入检测功能。
可以配置TAMPER的有效电平,
3. 是否开启侵入检测功能
4. 中断配置,是否开启中断。
5. 时钟输出功能的配置。
可以选择在RTC引脚上输出时钟信号,输出RTC校准时钟,RTC闹钟脉冲或者秒脉冲
6. 设置RTC校准值。就是写入RTC校准寄存器
*7. 写备份寄存器。
第一个参数是你要写在哪个DR里,第二个参数是写入的数据。
*8. 读备份寄存器
参数是指定要读哪个DR,返回值是读DR的值
9. 获取标志位状态
10. 清除标志位
11. 获取中断标志位
12. 清除中断挂起位
RTC简介:
- RTC(Real Time Clock)实时时钟
- RTC是一个独立的定时器,可为系统提供时钟和日历的功能
- RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD(2.0~3.6V)断电后可借助VBAT(1.8~3.6V)供电继续走时
- 32位的可编程计数器,可对应Unix时间戳的秒计数器(对用时间戳里的换算)
- 20位的可编程预分频器,可适配不同频率的输入时钟
- 可选择三种RTC时钟源(在RCC时钟树里有说明):
- HSE(高速外部时钟信号)时钟除以128(通常为8MHz/128)
- LSE(低速外部时钟信号)振荡器时钟(通常为32.768KHz)
- LSI(低速内部时钟信号)振荡器时钟(40KHz)
RTC框图
- 黑色部分是核心的、分频和计数计时部分。
- 这一块输入时钟是RTCCLK(上面有三种RTC时钟选择),首先要经过RTC预分频器进行分频,分频器由2个寄存器完成,RTC_PRL(重装载寄存器)和RTC_DIV(余数寄存器,实际还是CNT(计数器)的功能,不过是一个自减寄存器,自减到0产生溢出信号,然后DIV从PRL获取重装值继续自减)
- 分频器其实就是一种计数器,计几个数就溢出一次就是几分频(同时计数器记到几是几+1分频,因为计数是从0开始)
- 右边的计数计时部分:32位可编程计数器RTC_CNT,就是计时最核心的部分,可以把这个CNT看做Unix时间戳的秒计数器,这样借助Time.h的函数,就可以很方便的得到年月日时间。
在下面还有一个闹钟寄存器的RTC_ALR,它也是32位的寄存器,和上面这个CNT是等宽的,作用是设置闹钟,可以在ALR写一个秒数,设定闹钟,当CNT的值和ALR设定的闹钟值时,就是中间的等号,就代表闹钟响了,这是就会产生RTC_Alarm通往右边的中断系统,同时闹钟信号可以退出待机状态。
- 红色的部分是中断输出使能和NVIC部分
一共有3个信号可以触发中断,
- 第一个是RTC_Second, 秒中断,来源是CNT的输入时钟,如果开启这个秒中断,那么程序就会每秒进入一次RTC中断。
- 第二个RTC_Overflow,溢出中断,它的来源是CNT的右边,他是CNT的32位计数器满溢出了,会触发一次中断
- 第三个是RTC_Alarm,闹钟中断,当计数器和闹钟值相等时,触发中断,同时闹钟也可以吧设备从待机模式唤醒,
三个信号右边是中断标志位和中断输出控制,F(Flag)结尾是对应的中断标志位,IE(Interrupt Enable)结尾是中断使能,他们通过一个或门汇聚到NVIC的中断控制器。
- 蓝色的是APB1总线读写部分
APB1总线和APB1的接口,就是程序读写寄存器的地方,读写寄存器就是通过APB1总线来完成,同时RTC是APB1总线上的设备。
- 绿色的是PWR关联部分,意思是RTC的闹钟可以唤醒设备,退出待机模式
WKUP(Weak Up)引脚和闹钟信号,都可以唤醒设备。
同时,在原图中有灰色填充的部分是后备区域,可以在主电源掉电后,使用备用电池维持工作。在待机时也会维持供电。
下面的RTC基本结构图是对上面的RTC框图的一个总结。
RTC的基本结构:
RTC的核心部分如图所示:
- 最左边是RTCCLK时钟来源,这一块需要在RCC里配置,三个时钟,选择一个,当做RTCCLK。
- 之后,RTCCLK先通过预分频器,对时钟进行分频。余数计数器是一个自减计数器,存储当前的计数值。重装寄存器是计数目标,决定分频值(选择分频系数),分频过后,得到1Hz的秒计数信号。
- 然后通向32位计数器(可以进行日期时间的读写),一秒自增一次,下面还有一个32位的闹钟值,可以设置闹钟
- 右边有三个信号可以触发中断,分别是秒信号,计数器溢出信号和闹钟信号,三个信号先通过中断输出控制,进中断使能,使能的中断通向NVIC,然后向CPU申请中断。
硬件电路:
为了配合STM32的RTC,外部还需要一些电路的,外部电路需要加上备用电池部分和外部低速晶振。
备用电池供电部分:
简单连接:就是用电池正极接STM32的VBAT引脚,负极共地。
推荐连接:电池通过二极管D1,向VBAT供电,外主电源的3.3v,也通过二极管D2向VBAT供电,最后VBAT再加一个0.1uF的电源滤波电容。
外部晶振部分:
这里的X1是一个32.768KHz的RTC晶振(部分正负极),两端分别接在OSC32这两个引脚上,然后晶振两端,在分别接一个起振电容,到GND。
RTC操作注意事项:
- 执行以下操作将使能对BKP和RTC的访问:
- 设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和
- BKP时钟
设置PWR_CR的DBP,使能对BKP和RTC的访问
需要都开启才能使用BKP和PWR
- 若在读取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1
- 必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器
- 对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器
RTC操作流程:
- 开启PWR和BKP的时钟,使能BKP和RTC的访问
- 启动RTC时钟,选择HSE(外部高速时钟)和LSE(外部低速时钟)和LSI(内部低速时钟)
这里我使用的LSE,所以要使用RCC模块里的函数,开启LSE的时钟。(同时LSE为了省电是默认关闭的,要手动开启)
- 配置RTCCLK这个数据选择器,指定LSE为RTCCLk
- 调用两个等待函数,一个是等待同步,另一个是等待上一次操作完成。
- 配置预分频器。给PRL(重装寄存器)给一个合适的分频值;以确保传输给计数器的频率是1HZ
- 配置CNT的值,给这个RTC一个初始时间;如果需要闹钟的话,可以配置闹钟值;需要中断的话,可以配置中断这部分。
RTC的库函数
- 配置LSE(外部低速时钟)
- 配置LSI(内部低速时钟)
- RTCCLK配置,用来选择RTCCLK时钟源。实际上配置数据选择器。
- 启动RTCCLK
- 获取标志位。
- 配置中断输出
- 进入配置模式 把CNF位置1
- 退出配置模式 把CNF位清零
- 获取CNT计数器的值,读取时钟需要这个函数
- 写入CNT计数器的值,显然设置时间,就靠这个函数。
- 写入预分频器,这个值会写入到预分频器的PRL重装寄存器中,用来配置预分频器的分频系数
- 写入闹钟值,如果需要闹钟,就可以配置这个函数。
- 读取预分频器中的DIV余数寄存器(自减计数器)
- 等待上次操作完成,循环直到RTOFF状态位为1.
- 等待同步,清除RSF标志位,然后循环,直到RSF为1
16~19 是有关的标志位函数。