解锁STM32F103C8T6新技能:BKP备份寄存器背后的惊人用途!
BKP(Backup Register)是STM32系列中一组特殊的寄存器,用于在系统掉电或重启时保存关键数据。掉电保持:通过VBAT引脚供电(需外接电池),数据在系统断电后仍能保留。独立时钟域:与RTC共用低速时钟(LSE/LSI),支持低功耗模式。侵入检测:可配置硬件触发事件清除BKP数据(防篡改)。10个16位备份寄存器(BKP_DR1 ~ BKP_DR10)1个侵入检测引脚(PC13)BK
·
什么是BKP?
BKP(Backup Register)是STM32系列中一组特殊的寄存器,用于在系统掉电或重启时保存关键数据。其特点包括:
- 掉电保持:通过VBAT引脚供电(需外接电池),数据在系统断电后仍能保留。
- 独立时钟域:与RTC共用低速时钟(LSE/LSI),支持低功耗模式。
- 侵入检测:可配置硬件触发事件清除BKP数据(防篡改)。
STM32F103C8T6的BKP资源:
- 10个16位备份寄存器(BKP_DR1 ~ BKP_DR10)
- 1个侵入检测引脚(PC13)
BKP框图
手动配置步骤
1. 工程配置
- 创建HAL库工程(如使用Keil或STM32CubeIDE)
- 手动添加以下HAL库文件:
stm32f1xx_hal_pwr.cstm32f1xx_hal_pwr_ex.cstm32f1xx_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);
}
}
关键注意事项
- 电源配置:确保VBAT引脚连接备用电池(典型3V纽扣电池)
- 写保护:操作BKP前必须调用
HAL_PWR_EnableBkUpAccess() - 侵入检测:PC13需配置为浮空输入模式
- 时钟依赖:BKP操作需要使能PWR和BKP时钟
测试验证
- 写入数据后断开主电源,等待10秒后重新上电
- 读取BKP寄存器验证数据是否保留
- 触发PC13引脚高电平,检查是否触发数据清除
扩展阅读
- STM32F103xx参考手册 - BKP寄存器章节
- HAL库文档:
stm32f1xx_hal_pwr_ex.h - 侵入检测电路设计指南
更多推荐



所有评论(0)