Skip to content

BKP & RTC

RTC (实时时钟),就绝对绕不开它的“连体婴”兄弟 —— BKP (Backup Registers,备份寄存器)

这两兄弟通常是穿一条裤子的。在嵌入式开发(特别是 STM32)中,它们共同组成了芯片中一个最神秘、最坚挺的区域 —— 备份域 (Backup Domain)

把它们的关系比作:“挂钟”与“保险箱”

一、 什么是 BKP?(单片机里的保险箱)

你已经知道 RTC 是**“挂钟”(负责走字)。

那 BKP 就是挂钟下面的一个“小保险箱”**。

1. 物理特性

  • 空间很小:通常只有几十个字节(比如 STM32F103 有 42 个 16位的寄存器)。它不是用来存大数据的,是用来存**关键“秘密”**的。
  • 供电特殊:它和 RTC 一样,也是吃 VBAT (纽扣电池) 的饭。
  • 记忆力超强
    • 按下复位键 (NRST)?数据还在。
    • 软件重启 (System Reset)?数据还在。
    • 主电源 VDD 断电(只要电池还在)?数据还在。
    • 只有一种情况会丢失:纽扣电池被拔掉,或者发生了“入侵事件”(Tamper,后面讲)。

2. 它的作用

它是 RAM,读写速度极快,不需要像 Flash 那样擦除。它主要用来保存系统断电后不能丢、但复位后又需要立刻读取的“状态标记”


二、 为什么 RTC 离不开 BKP?(经典应用场景)

这是嵌入式面试必问的题目:“系统重新上电后,如何防止 RTC 时间被重置?”

场景模拟:

  1. 你写了一个代码:RTC_Init(); RTC_SetTime(12:00);
  2. 第一次烧录运行:时间设定为 12:00,开始走字。
  3. 问题来了:当你断电重启,或者按复位键,代码又从头跑了一遍,又执行了一次 RTC_SetTime(12:00)
  4. 结果:你的表永远停留在 12:00,或者每次重启都归零。

解决方案:用 BKP 存个“暗号”

因为 BKP 在重启后数据不丢失,我们可以利用它来判断**“这是不是第一次上电”**。

标准代码逻辑(老鸟都在用):

C

// 定义一个暗号,比如 0xA5A5 (随便定义的,只要是个特殊值就行)
#define RTC_CHECK_FLAG  0xA5A5

void RTC_Configuration(void)
{
    // 1. 先去打开保险箱看看,里面有没有我们的暗号?
    if (BKP_ReadBackupRegister(BKP_DR1) != RTC_CHECK_FLAG)
    {
        // === 情况 A:没找到暗号 ===
        // 说明这是这块板子【第一次】上电,或者电池被扣掉过。
      
        printf("第一次上电,正在初始化 RTC...\n");
      
        RTC_Init();          // 初始化 RTC
        RTC_SetTime(12, 0, 0); // 设个默认时间
      
        // 【关键一步】把暗号写进保险箱!
        BKP_WriteBackupRegister(BKP_DR1, RTC_CHECK_FLAG);
    }
    else
    {
        // === 情况 B:找到了暗号 ===
        // 说明板子只是复位了,电池还在,RTC 正在后台默默走字呢。
      
        printf("发现暗号!跳过时间设置,直接显示当前时间。\n");
      
        // 啥也不用干,直接去读 RTC 值就行了
        // 这一步如果不跳过,你的时间就被重置了!
    }
}

结论:

RTC 负责走时,BKP 负责记录“表已经调好了”这个状态。 没有 BKP,RTC 每次重启都会“失忆”。


三、 BKP 的另一个绝技:防拆机(Tamper Pin)

BKP 还有一个非常酷炫的功能,常用于POS 机、加密狗等安全性要求高的产品。

侵入检测 (Tamper Detection)

  • 原理:BKP 模块有一个专门的引脚叫 TAMPER。你可以把它接在一个微动开关上,这个开关顶住产品的外壳。
  • 动作:如果有人试图撬开外壳,开关弹起,TAMPER 引脚电平发生跳变。
  • 后果:BKP 模块会瞬间检测到“入侵”,然后立刻自动清空所有 BKP 寄存器里的数据
  • 目的毁尸灭迹。黑客撬开机器想读你的密钥(假设你把密钥存在 BKP 里),结果打开一看,全变成了 0,啥也没捞着。

四、 资深工程师的总结

RTC 和 BKP 是备份域里的“难兄难弟”。

特性RTC (实时时钟)BKP (备份寄存器)
功能计数 (时间/日期)存储 (数据)
容量32位计数器几十个字节 (16位 x N)
电源VDD 或 VBATVDD 或 VBAT
复位影响不受系统复位影响不受系统复位影响
核心用途提供时间辅助 RTC 判断初始化状态/ 存储掉电数据 / 防拆自毁
访问前提需 PWR 解锁需 PWR 解锁

避坑提醒:

  1. 必须要使能 PWR 和 BKP 时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  2. 必须要解锁PWR_BackupAccessCmd(ENABLE);
  3. BKP 不是 Flash:虽然它掉电不丢(有电池时),但如果你把电池扣了,BKP 里的数据就真没了。所以它不适合存永久性的配置参数(那个该存 Flash 或 EEPROM),它只适合存“临时但跨复位”的数据。