欢迎光临
我们一直在努力

STM32入门教程:BKP备份寄存器 & RTC实时时钟详解

🚀 我的STM32学习专栏:[点击直达 | 持续更新中]

适用平台:STM32F103C8T6 开发环境:Keil5 + 标准库函数


前言

做项目的时候,你有没有遇到过这种需求:单片机断电重启后,想要记住上一次设置的某个参数?比如密码、校准值、或者一个计数器的值?用Flash存当然可以,但Flash有擦写次数限制,而且操作麻烦。这时候,BKP备份寄存器就派上用场了。

再说另一个场景:你想做一个电子时钟,要求断电后时间还能继续走,下次上电显示的是当前真实时间,而不是从0开始。这时候就需要RTC实时时钟。

BKP和RTC这两个模块在STM32里是"绑"在一起的,它们都工作在后备区域,都有独立的电池供电。这篇文章我就结合江科大的课程笔记,把这两个东西从原理到应用彻底讲清楚。


一、BKP备份寄存器

1.1 BKP是什么?

BKP(Backup Registers) 就是备份寄存器,说白了,它就是单片机里一小块特殊的RAM,用来存用户数据。但它和普通RAM最大的区别是:掉电不丢失。

特性说明
供电方式 VDD(2.0~3.6V)正常供电;VDD掉电后自动切换为VBAT(1.8~3.6V)电池供电
抗复位能力 系统复位、电源复位、待机唤醒后,数据不清零
数据清除条件 只有TAMPER引脚检测到侵入事件,或软件手动清除,才会清空
存储容量 中/小容量:20字节(10个16位寄存器 DR1~DR10);大容量/互联型:84字节(DR1~DR42)
附加功能 RTC时钟校准、闹钟脉冲/秒脉冲输出

我的理解:你可以把BKP想象成单片机的"记事本小纸条"。主电源断了,它靠纽扣电池续命;你按复位键重启了,它上面的字还在。只有你把TAMPER引脚(PC13)接到一个检测电路上,有人拆机打开外壳触发了侵入检测,它才会"销毁证据"把数据清空。这个设计在安防领域很有用。

1.2 BKP的基本结构

BKP基本结构框图

从框图里可以清楚地看到BKP的三大外部接口:

  • VBAT:电池供电入口,接3V纽扣电池(CR2032)

  • TAMPER:侵入检测引脚,对应PC13。当这个引脚检测到有效边沿时,所有备份寄存器内容被硬件自动清除

  • RTC:可以输出RTC校准时钟、闹钟脉冲或秒脉冲

  • 内部核心是数据寄存器(DR),每个DR都是16位的。中容量芯片有DR1~DR10共10个,能存20个字节。对于STM32F103C8T6这种中容量芯片来说,20个字节存个密码、存个设备ID、存几个标志位,完全够用了。


    二、RTC实时时钟

    2.1 RTC是什么?

    RTC(Real Time Clock) 实时时钟,就是一个独立的定时器,专门用来给系统提供时间和日历功能。

    RTC的几个关键特性:

    • 独立工作:RTC和它的时钟配置寄存器都在后备区域,有自己独立的时钟源

    • 掉电保持:VDD(2.0~3.6V)断电后,VBAT(1.8~3.6V)继续给RTC供电,时钟继续走

    • 32位计数器:RTC_CNT是一个32位可编程计数器,可以把它当成Unix时间戳的秒计数器来用

    • 20位预分频器:RTC_PRL是预分频重装寄存器,可以把不同频率的输入时钟分频成1Hz

    • 闹钟功能:RTC_ALR是32位闹钟值,当CNT == ALR时产生闹钟中断

    我的理解:RTC本质上就是一个"超级定时器"。普通定时器(TIM)主电源断了就停了,RTC有"备用电池"这个外挂,所以能一直跑。32位计数器最大能计到 0xFFFFFFFF,换算成秒大约是136年,所以你根本不用担心它溢出。预分频器的作用就是把32.768KHz这种"高频"时钟,分频成1Hz(每秒一个脉冲),这样CNT每加1就代表过了1秒。

    2.2 RTC的三种时钟源

    RTC的时钟源可以选择三种:

    时钟源频率特点适用场景
    HSE/128 8MHz/128 = 62.5KHz 精度高,但主电源断了HSE就停了 不推荐用于RTC
    LSE 32.768KHz(外部晶振) 精度高,有独立供电,频率正好是2^15 强烈推荐
    LSI 约40KHz(内部RC) 不用外接晶振,但温漂大,精度差 对时间精度要求不高的场景

    重点说一下LSE:32.768KHz这个频率选得特别巧妙,因为 32768 = 2^15。RTC的20位预分频器设置重装值为 32768-1 = 32767 时,正好分频得到1Hz。而且外部低速晶振(如下图的圆柱形银色晶振)频率稳定,温漂小,是做时钟的最佳选择。

    2.3 RTC框图与基本结构

    简化的RTC框图

    RTC基本结构

    把这两张图结合起来看,RTC的工作流程就很清晰了:

    第一步:时钟源选择 HSE/128、LSE、LSI 三选一,经过多路选择器输出 RTCCLK。

    第二步:预分频 RTCCLK 进入预分频器,RTC_PRL 存放分频重装值,RTC_DIV 是余数寄存器(当前分频计数)。当DIV减到0时,输出一个 TR_CLK(通常是1Hz)。

    第三步:32位计数器计数 TR_CLK 的每个上升沿让 RTC_CNT 加1。CNT就是当前的秒计数器。

    第四步:中断与闹钟

    • 秒中断:每个TR_CLK周期产生一次(每秒一次)

    • 溢出中断:CNT从0xFFFFFFFF回到0时产生

    • 闹钟中断:当 CNT == ALR 时产生,同时可以唤醒待机模式

    第五步:NVIC中断管理 三种中断信号经过RTC_CR控制寄存器中的中断使能位(SECIE、OWIE、ALRIE),最终汇总到NVIC。

    注意框图中的两个小字:"待机时不供电" 和 "待机时维持供电"。APB1接口和NVIC在主电源断电后是不工作的,但预分频器、计数器、闹钟值这些核心模块由VBAT维持供电,所以时间不会停。

    我的理解:RTC的设计非常像"沙漏"。预分频器就是那个控制沙流速率的阀门(把32.768KHz变成1Hz),CNT就是下面接沙子的容器(每秒钟多一粒沙)。ALR闹钟就是你设定的目标重量,到了就响铃。而APB1总线只是你"看"沙漏的窗口,你断电了窗口黑了,但沙子还在流。


    三、硬件电路

    3.1 备用电池供电

     硬件电路连接

    看左边的"备用电池供电"部分:

    • 简单连接:VBAT直接接3V电池正极,电池负极接地。这种接法有个问题:主电源3.3V和电池同时存在时,可能会有电流倒灌。

    • 推荐连接:通过二极管D1、D2做"或门"供电。VDD(3.3V)经过D2降压后到VBAT,电池B2经过D1到VBAT。谁电压高谁供电。C3是滤波电容。这样主电源有电时电池不耗电,主电源断了电池无缝接管。

    3.2 外部低速晶振电路

    晶振X1(32.768KHz)跨接在PC14(OSC32_IN)和PC15(OSC32_OUT)之间,两个引脚各接一个10pF的负载电容到地。这是标准的皮尔斯振荡电路。

    我的理解:VBAT这个设计真的很妙。你想想看,如果没有VBAT,每次断电重启时间都要重新设置,那电子时钟就没法用了。纽扣电池一般能用好几年,因为RTC功耗极低(微安级)。我建议大家做项目时一定用推荐连接的二极管方案,不要直接把电池焊在VBAT上,否则电池寿命会大打折扣。


    四、RTC操作注意事项(重点!)

    4.1 使能访问权限(第一步必须做)

    要对BKP和RTC进行任何操作,必须先完成以下两步:

  • 开启PWR和BKP的时钟:这两个外设都挂在APB1总线上,使用前必须先开时钟,否则寄存器写不进去。

  • 设置PWR_CR的DBP位:DBP(Disable Backup Domain Write Protection)默认是0,后备区域被锁死;置1后才能访问RTC和BKP寄存器。

  • 为什么需要这两步? 因为后备区域是"敏感地带",为了防止程序跑飞时误改写RTC和BKP,STM32默认把它们锁起来了。你必须先开时钟,再设置DBP位,才能解锁。

    4.2 等待寄存器同步

    如果APB1接口之前被禁用过,在读取RTC寄存器前,必须等待RSF位(Register Synchronized Flag)被硬件置1。

    由于RTC时钟(32.768KHz)和APB1时钟(36MHz)是异步的,APB1读RTC寄存器时需要等待同步,否则读到的可能是旧数据。

    4.3 进入配置模式

    必须设置RTC_CRL寄存器中的CNF位(Configuration Flag),使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR这三个核心寄存器。

    这是硬件层面的保护机制。CNF=1时,RTC核心暂停计数,允许修改配置;CNF=0时,RTC正常运行。

    4.4 等待写操作完成

    对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CRL寄存器中的RTOFF位(RTC Operation OFF)来判断RTC寄存器是否处于更新中。

    仅当RTOFF状态位是1时,才可以写入RTC寄存器。

    因为RTC时钟很慢(32.768KHz),而APB1时钟很快(36MHz),写RTC寄存器需要好几个RTC时钟周期才能真正生效。如果连续快速写入,后面的数据会覆盖前面的,导致配置错误。

    风险说明:这四步如果漏了任何一步,RTC要么初始化失败,要么时间不准,要么写不进去。特别是解除写保护(DBP)和等待RTOFF,是很多新手最容易踩的坑。


    五、总结表格

    项目BKP备份寄存器RTC实时时钟
    全称 Backup Registers Real Time Clock
    本质 16位数据寄存器组(DR1~DRn) 32位秒计数器 + 20位预分频器
    供电区域 后备区域(VBAT维持) 后备区域(VBAT维持)
    掉电保持 ✅ 数据不丢失 ✅ 时钟继续走
    系统复位保持 ✅ 不清零 ✅ 不清零
    容量/范围 20字节(中容量)/ 84字节(大容量) CNT可计136年
    时钟源 无(纯寄存器) HSE/128、LSE(32.768KHz)、LSI(40KHz)
    推荐时钟源 LSE外部低速晶振
    清除条件 TAMPER侵入事件、软件复位 仅VBAT断电才停
    中断类型 秒中断、溢出中断、闹钟中断
    关键寄存器 DRx、CSR、CR PRL、DIV、CNT、ALR、CRL、CRH
    访问前提 开PWR/BKP时钟 + DBP=1 开PWR/BKP时钟 + DBP=1 + CNF=1 + RTOFF=1

    写这篇文章的时候,我把江科大的视频又回顾了一遍,对照着《STM32F10xxx参考手册》把RTC的框图重新梳理了一次。说实话,RTC这个章节知识点比较杂,BKP和RTC的关系、三种时钟源的选择、预分频器的计算、那四个操作注意事项,刚开始学的时候很容易搞混。

    但只要你抓住一条主线——"RTC是一个用32.768KHz晶振驱动、经过32768分频得到1Hz、用32位计数器记录秒数的独立定时器"——其他的细节就都能串起来了。BKP则是RTC的"好邻居",共享后备区域和VBAT供电,用来存一些掉电不能丢的小数据。

    📌 开发环境:Keil5 + STM32F103C8T6最小系统板 + ST-Link 📌 参考资料:江科大STM32入门教程、《STM32F10xxx参考手册》 📌 前置文章:江科大STM32入门:Unix时间戳详解

    如果本文对你有帮助,欢迎点赞 👍 收藏 ⭐ !有任何问题欢迎在评论区交流,一起学习进步!

    赞(0)
    未经允许不得转载:171主机测评 » STM32入门教程:BKP备份寄存器 & RTC实时时钟详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址