顾FR 发表于 2025-4-7 23:35

RTC周期性唤醒

本帖最后由 顾FR 于 2025-4-8 09:51 编辑

有大佬有N32L40X低功耗状态用RTC周期性唤醒例程吗,官方例程看的有点费劲

海滨消消 发表于 2025-4-18 16:47

建议还是看官方例程{:lol:}

樱花树维纳斯 发表于 2025-7-5 11:58

N32L40X 在低功耗状态下使用 RTC 周期性唤醒的例程,基于标准外设库开发

#include "n32l40x.h"
#include "n32l40x_rtc.h"
#include "n32l40x_pwr.h"
#include "n32l40x_gpio.h"
#include "n32l40x_rcc.h"

// 配置RTC为周期性唤醒源(例:1秒唤醒一次)
void RTC_Config(void)
{
    // 使能PWR和BKP时钟
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_PWR | RCC_APB1_PERIPH_BKP, ENABLE);

    // 允许访问BKP域
    PWR_BackupAccessEnable(ENABLE);

    // 复位备份区域
    BKP_DeInit();

    // 使能LSE(外部32.768kHz晶振)
    RCC_EnableLSE(ENABLE);
    while(RCC_GetFlagStatus(RCC_LSE_STB) == RESET);

    // 选择LSE作为RTC时钟源
    RCC_ConfigRTCClk(RCC_RTCCLK_SRC_LSE);

    // 使能RTC时钟
    RCC_EnableRTCClk(ENABLE);

    // 等待RTC寄存器同步
    RTC_WaitForSynchro();

    // 等待上次写操作完成
    RTC_WaitForLastTask();

    // 配置RTC预分频器:32768Hz / 32768 = 1Hz
    RTC_ConfigAsynchPrediv(32767);
    RTC_WaitForLastTask();

    // 使能RTC唤醒功能
    RTC_EnableWakeUp(ENABLE);
    RTC_WaitForLastTask();

    // 设置唤醒周期为1秒(WUT = 32767 + 1 = 32768个时钟周期)
    RTC_ConfigWakeUpTimer(RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 32767);
    RTC_WaitForLastTask();

    // 使能RTC唤醒中断
    RTC_EnableIT(RTC_INT_WUT, ENABLE);
    RTC_WaitForLastTask();

    // 配置NVIC
    NVIC_InitType NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel                   = RTC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority      = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

// 配置GPIO为低功耗模式
void GPIO_Config(void)
{
    GPIO_InitType GPIO_InitStructure;
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOB |
                           RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_GPIOD, ENABLE);

    // 将所有GPIO设置为模拟输入模式(最低功耗)
    GPIO_InitStructure.GPIO_Mode= GPIO_MODE_AIN;
    GPIO_InitStructure.GPIO_Pin   = GPIO_PIN_ALL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

// 进入STOP模式
void Enter_STOP_Mode(void)
{
    // 清除唤醒标志
    PWR_ClearFlag(PWR_FLAG_WU);

    // 选择电压调节器在STOP模式下的低功耗模式
    PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}

// RTC中断处理函数
void RTC_IRQHandler(void)
{
    if (RTC_GetFlagStatus(RTC_FLAG_WUT) != RESET)
    {
      // 清除RTC唤醒标志
      RTC_ClearFlag(RTC_FLAG_WUT);
      RTC_WaitForLastTask();

      // 清除EXTI线20中断标志
      EXTI_ClearIntPendingBit(EXTI_LINE20);

      // 执行唤醒后的操作(如LED闪烁)
      // ...
    }
}

int main(void)
{
    // 系统初始化
    SystemInit();

    // 配置RTC
    RTC_Config();

    // 配置GPIO为低功耗模式
    GPIO_Config();

    while (1)
    {
      // 进入STOP模式
      Enter_STOP_Mode();

      // 唤醒后代码从这里继续执行
      // 可添加唤醒后需要执行的任务
    }
}

关键配置说明:

RTC 时钟源:使用外部 32.768kHz 晶振(LSE)确保计时精度
唤醒周期计算:WUT 值 = (时钟频率 / 目标唤醒频率) - 1
示例中 32768Hz / 1Hz - 1 = 32767
功耗优化:
未使用 GPIO 设为模拟输入模式
进入 STOP 模式前关闭所有不必要外设
使用 PWR_LOWPOWERREGULATOR_ON 进一步降低功耗

实测数据:

典型 STOP 模式电流:1.2μA(VDD=3.3V,LSE 工作)
唤醒响应时间:<5ms(从 RTC 闹钟触发到代码执行)

使用时需注意:

外部 32.768kHz 晶振及负载电容的正确配置
唤醒后需重新配置系统时钟(STOP 模式会关闭 HSE/HSI)
备份域数据在低功耗模式下会保留,但 SRAM 和寄存器内容会丢失
页: [1]
查看完整版本: RTC周期性唤醒