[STM32L4] STM32L476 低功耗模式唤醒

[复制链接]
 楼主| 旧年胶片 发表于 2025-7-10 18:51 | 显示全部楼层 |阅读模式
使用 STM32L476 的 STOP2 模式降低功耗,但发现 RTC 闹钟唤醒不稳定,有时需要多次尝试才能唤醒。

使用逻辑分析仪监测 WKUP 引脚,发现唤醒信号正常
检查 RTC 配置,发现 RTC 时钟源选择为 LSE (低速外部晶振),但没有正确启动
查看电源管理,发现进入 STOP2 模式前没有正确配置唤醒引脚

后续处理:
确保 LSE 晶振正确启动并稳定运行
增加 LSE 启动超时检测
优化低功耗模式配置和唤醒引脚设置

[color=rgba(0, 0, 0, 0.45)]// RTC初始化函数,增加LSE启动检测RTC_HandleTypeDef hrtc;void MX_RTC_Init(void){    RTC_TimeTypeDef sTime = {0};    RTC_DateTypeDef sDate = {0};    RTC_AlarmTypeDef sAlarm = {0};        [color=rgba(0, 0, 0, 0.45)]// 使能电源时钟    __HAL_RCC_PWR_CLK_ENABLE();        [color=rgba(0, 0, 0, 0.45)]// 使能备份域访问    HAL_PWR_EnableBkUpAccess();        [color=rgba(0, 0, 0, 0.45)]// 配置LSE作为RTC时钟源    __HAL_RCC_LSE_CONFIG(RCC_LSE_ON);        [color=rgba(0, 0, 0, 0.45)]// 等待LSE稳定,增加超时检测    uint32_t timeout = 10000;    while(!(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY)) && (timeout-- > 0))    {        [color=rgba(0, 0, 0, 0.45)]// 超时处理        if(timeout == 0)        {            printf("LSE start timeout!\r\n");            [color=rgba(0, 0, 0, 0.45)]// 可以选择切换到LSI或其他时钟源            __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);            __HAL_RCC_LSI_ENABLE();            while(!(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY)));            __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);            break;        }    }        [color=rgba(0, 0, 0, 0.45)]// 配置RTC时钟源    __HAL_RCC_RTC_ENABLE();        [color=rgba(0, 0, 0, 0.45)]// 配置RTC    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.OutPutRemap = RTC_OUTPUT_REMAP_NONE;    hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;    hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;        if (HAL_RTC_Init(&hrtc) != HAL_OK)    {        Error_Handler();    }        [color=rgba(0, 0, 0, 0.45)]// 配置时间和日期    [color=rgba(0, 0, 0, 0.45)]// ...省略部分代码...        [color=rgba(0, 0, 0, 0.45)]// 配置RTC闹钟,每30秒唤醒一次    sAlarm.AlarmTime.Hours = 0;    sAlarm.AlarmTime.Minutes = 0;    sAlarm.AlarmTime.Seconds = 30;    sAlarm.AlarmTime.SubSeconds = 0;    sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;    sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;    sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES;    sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;    sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;    sAlarm.AlarmDateWeekDay = 1;    sAlarm.Alarm = RTC_ALARM_A;        if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)    {        Error_Handler();    }}[color=rgba(0, 0, 0, 0.45)]// 进入STOP2模式函数void Enter_STOP2_Mode(void){    [color=rgba(0, 0, 0, 0.45)]// 保存当前RTC闹钟设置    RTC_AlarmTypeDef sAlarm;    HAL_RTC_GetAlarm(&hrtc, &sAlarm, RTC_ALARM_A, RTC_FORMAT_BIN);        [color=rgba(0, 0, 0, 0.45)]// 关闭不需要的外设时钟    __HAL_RCC_GPIOA_CLK_DISABLE();    __HAL_RCC_GPIOB_CLK_DISABLE();    __HAL_RCC_GPIOC_CLK_DISABLE();    __HAL_RCC_GPIOD_CLK_DISABLE();    __HAL_RCC_GPIOE_CLK_DISABLE();        [color=rgba(0, 0, 0, 0.45)]// 配置唤醒引脚    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);        [color=rgba(0, 0, 0, 0.45)]// 进入STOP2模式    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);        [color=rgba(0, 0, 0, 0.45)]// 系统从STOP2模式唤醒后会重新配置时钟    [color=rgba(0, 0, 0, 0.45)]// 重新初始化外设和GPIO    [color=rgba(0, 0, 0, 0.45)]// ...省略部分代码...}

小小蚂蚁举千斤 发表于 2025-7-28 23:02 | 显示全部楼层
RTC 闹钟唤醒不稳定,需要多次尝试才能唤醒。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

34

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部