什么是BKP?

BKP(Backup Register)是STM32系列中一组特殊的寄存器,用于在系统掉电或重启时保存关键数据。其特点包括:

  • 掉电保持:通过VBAT引脚供电(需外接电池),数据在系统断电后仍能保留。
  • 独立时钟域:与RTC共用低速时钟(LSE/LSI),支持低功耗模式。
  • 侵入检测:可配置硬件触发事件清除BKP数据(防篡改)。

STM32F103C8T6的BKP资源:

  • 10个16位备份寄存器(BKP_DR1 ~ BKP_DR10)
  • 1个侵入检测引脚(PC13)

BKP框图
在这里插入图片描述


手动配置步骤

1. 工程配置

  1. 创建HAL库工程(如使用Keil或STM32CubeIDE)
  2. 手动添加以下HAL库文件:
    • stm32f1xx_hal_pwr.c
    • stm32f1xx_hal_pwr_ex.c
    • stm32f1xx_hal_rtc_ex.c(若使用RTC)

2. 时钟初始化

void stm32_clock_init(uint32_t plln)
{
    HAL_StatusTypeDef ret = HAL_ERROR;
    RCC_OscInitTypeDef rcc_osc_init = {0};
    RCC_ClkInitTypeDef rcc_clk_init = {0};

    rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE;       /* 选择要配置HSE */
    rcc_osc_init.HSEState = RCC_HSE_ON;                         /* 打开HSE */
    rcc_osc_init.HSEPredivValue = RCC_HSE_PREDIV_DIV1;          /* HSE预分频系数 */
    rcc_osc_init.PLL.PLLState = RCC_PLL_ON;                     /* 打开PLL */
    rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;             /* PLL时钟源选择HSE */
    rcc_osc_init.PLL.PLLMUL = plln;                             /* PLL倍频系数 */
    ret = HAL_RCC_OscConfig(&rcc_osc_init);                     /* 初始化 */

    if (ret != HAL_OK)
    {
        while (1);                                              /* 时钟初始化失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
    }

    /* 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2*/
    rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
    rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;        /* 设置系统时钟来自PLL */
    rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;               /* AHB分频系数为1 */
    rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2;                /* APB1分频系数为2 */
    rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV1;                /* APB2分频系数为1 */
    ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_2);  /* 同时设置FLASH延时周期为2WS,也就是3个CPU周期。 */

    if (ret != HAL_OK)
    {
        while (1);                                              /* 时钟初始化失败,之后的程序将可能无法正常执行,可以在这里加入自己的处理 */
    }
}

3. BKP初始化代码

void rtc_init(void)
{
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_RCC_BKP_CLK_ENABLE();
    HAL_PWR_EnableBkUpAccess();
    
    rtc_handle.Instance = RTC;
    rtc_handle.Init.AsynchPrediv = 32767;
    rtc_handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
    HAL_RTC_Init(&rtc_handle);
}

4. 数据读写操作

uint16_t rtc_read_bkr(uint8_t bkrx)
{
    uint32_t data = 0;
    data = HAL_RTCEx_BKUPRead(&rtc_handle, bkrx);
    return (uint16_t)data;
}

void rtc_write_bkr(uint8_t bkrx, uint16_t data)
{
    HAL_RTCEx_BKUPWrite(&rtc_handle, bkrx, data);
}

5. 中断处理(侵入检测)

// 在stm32f1xx_it.c中添加:
void TAMPER_IRQHandler(void) {
  HAL_RTCEx_TamperIRQHandler(&hrtc);
}

// 回调函数
void HAL_RTCEx_TamperEventCallback(RTC_HandleTypeDef *hrtc) {
  // 检测到侵入事件,清除所有BKP数据
  for(int i=BKP_DR1; i<=BKP_DR10; i++) {
    HAL_RTCEx_BKUPWrite(hrtc, i, 0x0000);
  }
}

关键注意事项

  1. 电源配置:确保VBAT引脚连接备用电池(典型3V纽扣电池)
  2. 写保护:操作BKP前必须调用HAL_PWR_EnableBkUpAccess()
  3. 侵入检测:PC13需配置为浮空输入模式
  4. 时钟依赖:BKP操作需要使能PWR和BKP时钟

测试验证

  1. 写入数据后断开主电源,等待10秒后重新上电
  2. 读取BKP寄存器验证数据是否保留
  3. 触发PC13引脚高电平,检查是否触发数据清除

扩展阅读

  1. STM32F103xx参考手册 - BKP寄存器章节
  2. HAL库文档:stm32f1xx_hal_pwr_ex.h
  3. 侵入检测电路设计指南
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐