1. 基于STM32L0的定时唤醒GPIO控制LED

基于STM32L0的定时唤醒GPIO控制LED 学习卡片

任务定义

本案例基于STM32L0系列MCU(以STM32L053R8为例),实现以下完整闭环:

  1. MCU进入停止模式(Stop Mode),RTC周期唤醒(每2秒);
  2. 唤醒后翻转GPIO控制LED状态(亮/灭各1秒,通过两次唤醒实现完整周期);
  3. 提供功耗测量方法及判定标准。

硬件连接

  • LED阳极通过1kΩ限流电阻接PB3,阴极接GND;
  • 调试串口PA2(USART2_TX)用于输出唤醒计数(可选,不影响核心功能);
  • 供电:VDD接3.3V,测量时串入万用表电流档或使用评估板IDD测量跳线。
STM32L053R8 Stop Mode + RTC Wakeup PB3 1kΩ LED GND 32.768kHz PC14/PC15 电流表串接点 (VDD) GND

代码实现

使用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库会自动调用上述回调函数。

功耗测量方法

  1. 硬件准备:断开VDD跳线,将万用表(电流档,建议6位半或精度≥0.1μA)串入供电回路;
  2. 测量步骤:
  • 上电运行程序,等待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(取决于系统时钟频率)。上述数值为芯片规格参数,非本案例实测数据;实际测量值需以你的硬件环境为准。