1. 基于STM32L0的定时唤醒GPIO控制LED
任务定义
本案例基于STM32L0系列MCU(以STM32L053R8为例),实现以下完整闭环:
- MCU进入停止模式(Stop Mode),RTC周期唤醒(每2秒);
- 唤醒后翻转GPIO控制LED状态(亮/灭各1秒,通过两次唤醒实现完整周期);
- 提供功耗测量方法及判定标准。
硬件连接
- LED阳极通过1kΩ限流电阻接PB3,阴极接GND;
- 调试串口PA2(USART2_TX)用于输出唤醒计数(可选,不影响核心功能);
- 供电:VDD接3.3V,测量时串入万用表电流档或使用评估板IDD测量跳线。
代码实现
使用STM32CubeMX生成初始化代码后,在main.c中补充以下核心逻辑(完整工程基于HAL库):
/* main.c 核心代码 */
#include "stm32l0xx_hal.h"
/* RTC唤醒周期:2秒 */
#define WAKEUP_PERIOD_SEC 2
/* LED引脚定义 */
#define LED_GPIO_PORT GPIOB
#define LED_PIN GPIO_PIN_3
/* 唤醒计数(调试用,通过串口输出) */
volatile uint32_t wakeup_count = 0;
/* RTC初始化:配置为周期唤醒 */
static void MX_RTC_Init(void)
{
RTC_HandleTypeDef hrtc;
RTC_WakeUpTypeDef wakeup_param;
__HAL_RCC_RTC_ENABLE();
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127; /* 异步分频:128分频 → 256Hz */
hrtc.Init.SynchPrediv = 255; /* 同步分频:256分频 → 1Hz */
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
HAL_RTC_Init(&hrtc);
/* 配置唤醒定时器:1Hz时钟,2秒周期 */
wakeup_param.WakeUpClock = RTC_WAKEUPCLOCK_CK_SPRE_1HZ;
wakeup_param.WakeUpCounter = WAKEUP_PERIOD_SEC - 1; /* 计数值=周期-1 */
wakeup_param.AutoWakeUp = RTC_WAKEUP_AUTO;
HAL_RTC_SetWakeUpTimer(&hrtc, &wakeup_param, 0);
}
/* GPIO初始化:PB3推挽输出 */
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef gpio_init = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
gpio_init.Pin = LED_PIN;
gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init.Pull = GPIO_NOPULL;
gpio_init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_GPIO_PORT, &gpio_init);
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, GPIO_PIN_RESET);
}
/* 进入停止模式 */
static void Enter_StopMode(void)
{
/* 确保RTC唤醒中断已使能 */
HAL_RTCEx_SetWakeUpTimer_IRQEnable(&hrtc);
/* 进入停止模式:仅保留RTC和LPTIM等低功耗外设 */
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
/* 唤醒后重新配置系统时钟(停止模式会关闭HSI/MSI) */
SystemClock_Config(); /* CubeMX生成的时钟配置函数 */
}
/* RTC唤醒中断回调(在stm32l0xx_it.c中调用) */
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
wakeup_count++;
/* 每2次唤醒翻转一次LED → 亮1秒、灭1秒 */
if (wakeup_count % 2 == 1) {
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, GPIO_PIN_SET);
} else {
HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, GPIO_PIN_RESET);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_RTC_Init();
/* 使能RTC唤醒中断 */
HAL_NVIC_SetPriority(RTC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RTC_IRQn);
while (1)
{
/* 进入停止模式,等待RTC唤醒 */
Enter_StopMode();
/* 唤醒后短暂停留(可选:用于调试观测) */
HAL_Delay(10);
}
}
中断处理说明:在stm32l0xx_it.c的RTC_IRQHandler中调用HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc),HAL库会自动调用上述回调函数。
功耗测量方法
- 硬件准备:断开VDD跳线,将万用表(电流档,建议6位半或精度≥0.1μA)串入供电回路;
- 测量步骤:
- 上电运行程序,等待LED进入稳定闪烁状态(约4秒后);
- 记录万用表显示的平均电流(停止模式期间电流远低于唤醒期间,万用表显示为时间加权平均值);
- 如需分别测量停止电流和运行电流,可在
Enter_StopMode()前后用示波器电流探头观测。
验证方法与判定标准
| 验证项 | 操作 | 通过标准 |
|---|---|---|
| LED闪烁功能 | 观察LED状态 | LED以约1Hz频率闪烁(亮1秒、灭1秒),周期稳定 |
| 唤醒周期 | 用示波器测LED引脚波形 | 高/低电平持续时间均为1.0s±0.1s |
| 停止模式功耗 | 万用表串接VDD测量 | 平均电流≤10μA(典型值3~5μA,取决于LDO配置和温度) |
| 唤醒可靠性 | 连续运行24小时 | 无死机,唤醒计数持续递增,LED无异常常亮/常灭 |
预期结果说明:根据STM32L0数据手册,停止模式下典型功耗为3.4μA(25°C,LDO低功耗模式),唤醒后运行电流约3~5mA(取决于系统时钟频率)。上述数值为芯片规格参数,非本案例实测数据;实际测量值需以你的硬件环境为准。