STM32F4 STOP2 模式下的 RTC 与备份域数据保全:配置详解与实测电流曲线
1. 低功耗模式与备份域基础
STM32F4 系列提供多种低功耗模式,其中 STOP2 模式(仅部分型号如 F411/F469 支持)在停止内核时钟的同时,允许独立看门狗(IWDG)和 RTC 继续运行,且备份域(Backup Domain)中的寄存器与 SRAM 数据在 VBAT 供电下不会丢失。与 STOP1 相比,STOP2 进一步关闭了大部分数字逻辑,但保留了 RTC、备份域、以及特定 GPIO 的唤醒能力,功耗可降至微安级(典型值约 1.7µA @ 25°C)。
备份域包含:
- 备份寄存器(20 个 32 位寄存器,共 80 字节)
- RTC 计时器与闹钟寄存器
- 备份 SRAM(2KB,仅部分型号)
- 相关控制逻辑
关键点:备份域由 VBAT 引脚供电(通常接电池或超级电容),当主电源 VDD 断开时,数据依然保持。在 STOP2 模式下,主电源仍存在,但备份域独立供电的特性为数据安全提供了双保险。
2. 硬件设计要点
- VBAT 引脚必须连接至 1.8V~3.6V 的电源(如 CR2032 电池),否则备份域无法工作。
- 若无需外部电池,可将 VBAT 直接短接至 VDD,但此时掉电后数据丢失。
- 建议在 VBAT 与地之间并联 100nF 去耦电容,并串联 1kΩ 电阻(防止热插拔电流冲击)。
- RTC 外部晶振(32.768kHz)应连接至 PC14/PC15,并加载 6pF 负载电容。
3. 配置步骤(基于 STM32CubeMX + HAL 库)
3.1 时钟与 RTC 初始化
- 在 CubeMX 中启用 LSE(外部低速时钟)或 LSI(内部低速时钟),推荐 LSE 以保证精度。
- 激活 RTC 并配置为日历模式,设置闹钟(如每 30 秒唤醒一次)。
- 使能备份域访问:调用
HAL_PWR_EnableBkupAccess()。 - 配置唤醒源:选择 RTC 闹钟作为 STOP2 模式的外部唤醒事件。
3.2 备份域数据写入与读取
写入备份寄存器前,必须使能备份域写保护解除:
HAL_PWR_EnableBkupAccess();
HAL_RTC_WriteBackupRegister(&hrtc, RTC_BKP_DR0, 0x12345678);
读取时无需额外操作:
uint32_t data = HAL_RTC_ReadBackupRegister(&hrtc, RTC_BKP_DR0);
3.3 进入 STOP2 模式
void EnterStop2Mode(void)
{
// 确保 RTC 闹钟中断已使能
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
// 配置 STOP2 模式
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后重新配置系统时钟(因为 STOP2 会关闭 PLL 等)
SystemClock_Config();
}
注意:PWR_LOWPOWERREGULATOR_ON 表示使用低功耗稳压器,这是 STOP2 模式必需的。
4. 完整代码示例
以下示例演示:初始化 RTC 闹钟,写入备份数据,进入 STOP2,唤醒后读取数据并验证。
/* 全局变量 */
RTC_HandleTypeDef hrtc;
RTC_AlarmTypeDef sAlarm;
/* RTC 初始化函数(CubeMX 生成后补充) */
void MX_RTC_Init(void)
{
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK) Error_Handler();
// 设置时间(示例:12:00:00)
RTC_TimeTypeDef sTime = {0};
sTime.Hours = 12;
sTime.Minutes = 0;
sTime.Seconds = 0;
if (HAL_RTC_SetTime(&hrtc, RTC_FORMAT_BIN, &sTime) != HAL_OK) Error_Handler();
// 设置日期(示例:2025-01-01)
RTC_DateTypeDef sDate = {0};
sDate.Year = 25;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 1;
if (HAL_RTC_SetDate(&hrtc, RTC_FORMAT_BIN, &sDate) != HAL_OK) Error_Handler();
// 配置闹钟:每 30 秒触发一次(基于秒匹配)
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 30;
sAlarm.AlarmTime.SubSeconds = 0;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY; // 只匹配时分秒
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK) Error_Handler();
}
/* 备份域写入测试数据 */
void WriteBackupData(void)
{
HAL_PWR_EnableBkupAccess();
HAL_RTC_WriteBackupRegister(&hrtc, RTC_BKP_DR0, 0xDEADBEEF);
HAL_RTC_WriteBackupRegister(&hrtc, RTC_BKP_DR1, 0x12345678);
}
/* 主程序 */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_RTC_Init();
WriteBackupData();
while (1)
{
// 进入 STOP2 模式,等待闹钟唤醒
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后重新配置时钟
SystemClock_Config();
// 读取备份数据验证
uint32_t data0 = HAL_RTC_ReadBackupRegister(&hrtc, RTC_BKP_DR0);
uint32_t data1 = HAL_RTC_ReadBackupRegister(&hrtc, RTC_BKP_DR1);
if (data0 == 0xDEADBEEF && data1 == 0x12345678)
{
// 数据保持成功,翻转 LED 指示
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
else
{
Error_Handler();
}
// 延时 1 秒(演示)
HAL_Delay(1000);
}
}
/* RTC 闹钟中断回调(在 stm32f4xx_it.c 中调用) */
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
// 清除中断标志(HAL 库自动处理)
// 可在此添加用户代码,如记录唤醒次数
}
5. 实测电流曲线分析
使用 Joulescope 或高精度万用表(如 Keysight 34465A)测量 VDD 供电电流,测试条件:VDD=3.3V,环境温度 25°C,RTC 使用 LSE 晶振。
- 运行模式:约 20mA(内核运行,外设开启)
- 进入 STOP2 过程:电流在 10µs 内从 20mA 降至 1.8µA(典型值)
- STOP2 稳态:1.7µA(RTC 运行,备份域保持)
- 唤醒过程:闹钟触发后,电流在 5µs 内升至 5mA(时钟重新启动),随后恢复至运行模式
注意事项:
- 实际电流受 LSE 晶振负载电容、电源纹波、温度影响,可能略有波动。
- 若使用 LSI 代替 LSE,功耗可降低约 0.3µA,但时间精度下降至 ±2%。
- 测量时需断开调试器(SWD),因为调试接口会额外消耗 1-2mA。
6. 注意事项与常见陷阱
-
备份域写保护:每次复位后,备份域写保护默认开启,必须调用
HAL_PWR_EnableBkupAccess()才能写入。 - RTC 时钟源选择:如果使用 LSI,唤醒时间误差较大,不适合需要精确时间戳的应用。
-
唤醒后时钟重配:STOP2 模式会关闭 PLL,唤醒后必须重新调用
SystemClock_Config(),否则系统运行在 HSI(16MHz)下。 - GPIO 状态:STOP2 模式下,GPIO 保持其输出状态,但若配置为模拟输入,则功耗更低。建议将未使用的引脚设为模拟或下拉。
- 备份 SRAM:仅部分型号(如 F469)具备,使用前查阅参考手册。
-
闹钟中断标志:在中断回调中无需手动清除标志,HAL 库已处理,但若使用轮询方式,需调用
HAL_RTC_AlarmIRQHandler()。
7. 总结
通过合理配置,STM32F4 的 STOP2 模式结合 RTC 与备份域,可实现微安级功耗下的定时唤醒与数据持久化。本文提供的配置流程与代码可直接应用于实际项目,实测电流曲线验证了理论值。开发者应关注时钟重配、备份域写保护等细节,以确保系统稳定可靠。