【STM32 + CubeMX 教程】RTC 实时时钟 之 闹钟唤醒 -- F407篇

上一篇教程,我们已经实现了RTC双闹钟功能(固定时间闹钟A、相对时间闹钟B),能够通过串口查看闹钟触发提示。

本篇将在此基础上,进一步实现 RTC闹钟唤醒功能------让STM32进入低功耗模式(STOP模式),通过RTC闹钟触发中断,唤醒单片机继续运行,适用于电池供电、低功耗需求的场景(如便携设备、智能监测设备)。

STM32F407的RTC闹钟,支持唤醒低功耗模式,核心原理:单片机进入低功耗模式后,CPU停止工作,仅RTC外设由纽扣电池供电运行;当闹钟触发时,RTC产生中断,唤醒CPU恢复正常工作,既节能又能保证定时任务正常执行。

示范效果

  1. 单片机初始化后,配置闹钟A(如每天6:30:00)或闹钟B(如当前时间+10秒);

  2. 单片机进入STOP低功耗模式,CPU停止工作,功耗降至最低;

  3. 闹钟触发时,RTC中断唤醒单片机,执行闹钟任务(如串口打印、LED翻转);

  4. 任务执行完成后,可再次进入低功耗模式,实现"唤醒-执行-休眠"循环。

目录


一、工程准备

1. 基础前提

已完成前两篇教程(RTC日历功能、RTC双闹钟功能),确保RTC初始化、闹钟A/B配置、中断回调函数可正常运行;

2. 硬件准备

STM32F407开发板、USB-TTL串口、纽扣电池(CR2032,保证RTC掉电后正常运行)、LED灯(可选,用于直观显示唤醒状态);

3. 软件准备

Keil5、CubeMX、串口助手。

提示:若未完成前序教程,请先查阅:

① 【STM32 + CubeMX 教程】RTC 实时时钟 之 日历 -- F407篇

② 【STM32 + CubeMX 教程】RTC 实时时钟 之 双闹钟 -- F407篇


二、CubeMX 配置(低功耗+RTC闹钟唤醒)

本步骤在之前RTC双闹钟配置的基础上,新增"低功耗模式"和"唤醒源"配置,无需重新配置RTC闹钟核心参数,仅补充以下设置。

步骤 2-1:配置低功耗模式(STOP模式)

  1. 打开之前的CubeMX工程(已配置RTC日历+双闹钟);

  2. 点击左侧 Power Management(电源管理),展开配置;

  3. 选择 Stop mode(STOP模式),这是STM32F407最常用的低功耗模式(CPU停止,外设可选择性工作,RTC正常运行);

  4. 唤醒方式:勾选 Wake-up from Stop mode by RTC闹钟(允许RTC闹钟唤醒STOP模式);

  5. 其他默认即可(无需修改RTC相关配置,沿用之前的闹钟A/B配置)。

步骤 2-2:配置唤醒相关中断(关键)

  1. 点击左侧 NVIC(中断控制器);

  2. 找到 RTC Alarm global interrupt(RTC闹钟全局中断),确保已打勾使能(之前配置闹钟时已开启,此处确认即可);

  3. 优先级配置:默认即可(无需修改,若有其他中断可调整,确保RTC闹钟中断优先级高于低功耗唤醒中断)。

步骤 2-3:生成初始化代码

点击右上角 Generate Code 按钮,CubeMX会自动将低功耗模式、RTC唤醒相关配置添加到工程中,覆盖原有初始化代码(保留之前的用户代码,无需担心丢失)。


三、实现 RTC 闹钟唤醒功能(代码编写)

核心思路:初始化RTC闹钟 → 配置低功耗模式 → 单片机进入STOP模式 → 闹钟触发中断唤醒 → 执行任务 → 再次进入低功耗模式(循环)。

所有代码均在 main.c 中编写,沿用之前的闹钟A/B配置函数、中断回调函数,仅新增"低功耗配置函数"和"唤醒逻辑"。

步骤 3-1:编写低功耗配置函数(进入STOP模式)

打开 main.c 文件,在 /* USER CODE BEGIN 0 */ 和 /* USER CODE END 0 */ 之间,添加低功耗模式配置函数:

/******************************************************************************

* 函 数: RTC_EnterStopMode

* 功 能: 配置并进入STOP低功耗模式,由RTC闹钟唤醒

* 说 明: 1. 进入STOP模式后,CPU停止工作,RTC、串口等外设停止运行

* 2. 仅RTC外设由纽扣电池供电,维持闹钟计时

* 3. 闹钟触发后,自动唤醒CPU,恢复正常运行

* 参 数: 无

* 返回值: 无

* 备 注: 最后修改_2026年03月17日

******************************************************************************/

void RTC_EnterStopMode(void)

{

/* 关闭所有不必要的外设(可选,进一步降低功耗)*/

HAL_UART_DeInit(&huart1); // 关闭串口1(唤醒后需重新初始化)

/* 进入STOP模式 */

HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

// 说明:PWR_LOWPOWERREGULATOR_ON:低功耗稳压器开启(保证唤醒稳定)

// PWR_STOPENTRY_WFI:进入停止模式,等待中断唤醒(WFI = Wait For Interrupt)

/* 唤醒后,重新初始化被关闭的外设 */

MX_USART1_UART_Init(); // 重新初始化串口1,用于打印唤醒提示

}

步骤 3-2:修改中断回调函数(唤醒后执行任务)

唤醒后,程序会自动进入闹钟中断回调函数,我们在回调函数中执行任务(如打印提示、LED翻转),无需额外处理唤醒逻辑。

沿用之前的回调函数,补充唤醒任务(以LED翻转为例,若没有LED可仅保留串口打印):

  1. 闹钟A回调函数(固定时间唤醒)

/******************************************************************************

* 函 数: HAL_RTC_AlarmAEventCallback

* 功 能: RTC 闹钟 A 中断回调函数(唤醒后执行)

* 说 明: 1. 闹钟A触发时,唤醒单片机,自动调用此函数

* 2. 执行唤醒任务后,可再次进入低功耗模式

* 参 数: hrtc:RTC句柄

* 返回值: 无

* 备 注: 最后修改_2026年03月17日

******************************************************************************/

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)

{

/* 唤醒任务:串口打印 + LED翻转(LED引脚需自行定义,此处以PB0为例)*/

printf("闹钟A 唤醒成功!当前时间:6:30:00 \r\n");

HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // 翻转LED状态,直观显示唤醒

/* 任务执行完成后,再次进入低功耗模式,等待下次闹钟唤醒 */

RTC_EnterStopMode();

}

  1. 闹钟B回调函数(相对时间唤醒)

/******************************************************************************

* 函 数: HAL_RTCEx_AlarmBEventCallback

* 功 能: RTC 闹钟B 中断回调函数(唤醒后执行)

* 说 明: 1. 闹钟B触发时,唤醒单片机,自动调用此函数

* 2. 重新设置闹钟B(5秒后再次触发),循环唤醒

* 参 数: hrtc:RTC句柄

* 返回值: 无

* 备 注: 最后修改_2026年03月17日

******************************************************************************/

void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)

{

/* 唤醒任务:串口打印 + LED翻转 */

printf("闹钟B 唤醒成功!将在5秒后再次唤醒 \r\n");

HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);

/* 重新设置闹钟B(5秒后触发),并再次进入低功耗模式 */

RTC_SetAlarmB(5);

RTC_EnterStopMode();

}

步骤 3-3:LED引脚配置(可选,直观显示唤醒)

若需要用LED显示唤醒状态,需在CubeMX中新增GPIO配置,步骤如下:

  1. 点击左侧 GPIO,选择一个空闲引脚(如PB0);

  2. 配置为 Output Push-Pull(推挽输出),默认电平设置为Low;

  3. 重新生成代码,CubeMX会自动生成GPIO初始化函数 MX_GPIO_Init(),无需手动编写。

步骤 3-4:main函数调用(初始化+进入低功耗)

在 /* USER CODE BEGIN 2 */ 和 /* USER CODE END 2 */ 之间,添加闹钟配置和低功耗调用代码,完整如下:

/* USER CODE BEGIN 2 */

printf("RTC闹钟唤醒功能初始化完成!\r\n");

// 配置闹钟A(每天6:30:00唤醒)

RTC_SetAlarmA(6, 30, 00);

// 配置闹钟B(首次5秒后唤醒,后续循环5秒唤醒)

RTC_SetAlarmB(5);

// 初始化完成后,进入低功耗模式,等待闹钟唤醒

RTC_EnterStopMode();

/* USER CODE END 2 */

步骤 3-5:烧录 & 验证

  1. 编译工程,将代码烧录到STM32F407开发板;

  2. 打开串口助手(波特率、数据位等参数与串口配置一致);

  3. 观察现象:

① 烧录后,串口打印"RTC闹钟唤醒功能初始化完成!",随后单片机进入低功耗模式;

② 闹钟A触发时(每天6:30:00),串口打印唤醒提示,LED翻转;

③ 闹钟B触发时(每5秒一次),串口打印唤醒提示,LED翻转,随后再次进入低功耗;

④ 若拔掉USB供电,仅靠纽扣电池,单片机仍能维持RTC运行,闹钟正常唤醒(实现低功耗节能)。


四、关键知识点(低功耗+唤醒原理)

  1. STOP低功耗模式说明

STM32F407的STOP模式,是兼顾"低功耗"和"唤醒速度"的最优选择,核心特点:

① CPU停止工作,内核时钟关闭,功耗降至几十微安(具体取决于外设关闭情况);

② RTC外设、后备域由纽扣电池供电,正常运行,维持日历和闹钟计时;

③ 可通过RTC闹钟、外部中断等方式唤醒,唤醒时间快(几微秒);

④ 唤醒后,CPU恢复正常运行,外设需重新初始化(如串口、GPIO)。

  1. RTC闹钟唤醒核心原理

① 单片机进入STOP模式后,仅RTC外设工作,不断检测闹钟触发条件;

② 当闹钟时间与当前RTC时间匹配时,RTC产生中断信号,触发NVIC中断;

③ 中断信号唤醒CPU,退出STOP模式,执行中断回调函数中的任务;

④ 任务执行完成后,可再次调用 RTC_EnterStopMode(),进入低功耗循环。

  1. 关键函数说明

① HAL_PWR_EnterSTOPMode():进入STOP低功耗模式,两个参数含义:

  • PWR_LOWPOWERREGULATOR_ON:开启低功耗稳压器,保证唤醒时电压稳定;

  • PWR_STOPENTRY_WFI:进入停止模式后,等待中断唤醒;

② HAL_UART_DeInit() / MX_USART1_UART_Init():关闭/重新初始化串口,降低功耗;

③ HAL_GPIO_TogglePin():翻转LED引脚电平,直观显示唤醒状态。


五、常见问题排查

  1. 进入低功耗后,闹钟无法唤醒

原因及解决方法:

① CubeMX未开启"RTC闹钟唤醒STOP模式":重新配置Power Management,勾选唤醒选项;

② RTC闹钟中断未使能:检查NVIC中"RTC Alarm global interrupt"是否打勾;

③ 纽扣电池没电:更换新的CR2032纽扣电池,确保RTC掉电后正常运行;

④ 唤醒后未重新初始化外设:确保 RTC_EnterStopMode() 中,唤醒后重新初始化串口、GPIO等。

  1. 唤醒后,串口打印乱码

原因:进入低功耗时关闭了串口,唤醒后未重新初始化串口。

解决:在 RTC_EnterStopMode() 中,唤醒后调用 MX_USART1_UART_Init(),重新初始化串口。

  1. 低功耗效果不明显

原因:未关闭不必要的外设(如LED、其他GPIO、串口)。

解决:在进入低功耗前,关闭所有不使用的外设(如 HAL_GPIO_DeInit() 关闭多余GPIO)。

  1. 闹钟唤醒后,无法再次进入低功耗

原因:回调函数中未调用 RTC_EnterStopMode(),或调用位置错误。

解决:在闹钟回调函数的最后,添加 RTC_EnterStopMode(),确保任务执行完成后进入低功耗。

总结

本篇教程在RTC双闹钟的基础上,实现了RTC闹钟唤醒低功耗功能,核心是"配置STOP模式+RTC闹钟中断唤醒",适用于电池供电、需要节能的场景。

重点注意:

① CubeMX中必须开启"RTC闹钟唤醒STOP模式"和RTC中断;

② 进入低功耗前关闭不必要的外设,唤醒后重新初始化;

③ 闹钟回调函数中,执行任务后需再次进入低功耗,实现循环唤醒。

至此,STM32F407 RTC的核心功能(日历、双闹钟、闹钟唤醒)已全部实现,可直接应用于实际项目开发。

相关推荐
BT-BOX2 小时前
第6章《Stm32CubeMX+Proteus仿真入门》LCD1602显示
stm32·嵌入式硬件·proteus
’长谷深风‘2 小时前
51单片机入门(2)
单片机·嵌入式硬件·51单片机·定时器·中断
chao1898442 小时前
STM32F103C8T6驱动LDC1614测试程序
stm32·单片机·嵌入式硬件
梦..3 小时前
Allegro学习记录(一)
arm开发·单片机·嵌入式硬件·学习·硬件架构·硬件工程·pcb工艺
零一iTEM3 小时前
低功耗开关机电路
嵌入式硬件
三佛科技-187366133973 小时前
FT838NB1-RT原边反馈5级能效电源控制器5V1A芯片电路图及管脚定义
单片机·嵌入式硬件·物联网
2501_918126913 小时前
学习所有6502写游戏控制器的语句
java·linux·网络·汇编·嵌入式硬件
qqssss121dfd4 小时前
STM32H750XBH6的ETH模块的IPv4 ARP offload功能分析
stm32·单片机·嵌入式硬件
修充电器上瘾5 小时前
驱动一个AIP650、数码管、按键、LED、红外、蜂鸣器控制板
单片机·嵌入式硬件