关于stm32l151c8t6在stop低功耗模式下通过RTC alarm唤醒的方法总结

首先,看一下stop模式下的说明:这是stm32l1xx 参考手册的说明,如果英文看不懂的话,可以查找stm32f10x的中文参考手册的说明看一下,意思差不多。

关于stm32l151c8t6在stop低功耗模式下通过RTC alarm唤醒的方法总结_第1张图片

关于stm32l151c8t6在stop低功耗模式下通过RTC alarm唤醒的方法总结_第2张图片

//RTC 时钟配置

void rtc_init(void) {
    uint32_t timeout = 600000;

    RTC_InitTypeDef RTC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Enable the PWR clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

    /* Allow access to RTC */
    PWR_RTCAccessCmd(ENABLE);
    RTC_WaitForSynchro();

    /* Enable the LSE OSC */
    RCC_LSEConfig(RCC_LSE_ON);

    /* Wait till LSE is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {
        timeout--;
        if (timeout == 0)
            break;
    }
    if (timeout == 0) {
        RCC_LSICmd(ENABLE);
        while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
            ;
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
    } else {
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); /* Select the RTC Clock Source */
    }

    /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);
    RTC_WaitForSynchro(); /* Wait for RTC APB registers synchronisation */

    /* Configure the RTC data register and RTC prescaler */
    if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2) { //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
        RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
        RTC_InitStructure.RTC_SynchPrediv = 0xFF;
        RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
        RTC_Init(&RTC_InitStructure);
        RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
    }
    RTC_WaitForSynchro();

    /* RTC 唤醒中端配置: Clock Source: RTCDiv_16, Wakeup Time Base: 4s */
//    RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);   //这两句不需要
//    RTC_SetWakeUpCounter(0x1FFF); //0x1FFF = 8191; 4s = (8191+1)*(1/(32768/16))

//RTC定时器A的配置

void platform_rtc_set_alarmA(void) {
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    RTC_AlarmTypeDef RTC_AlarmStructure;
    //非待机模式,RTC alarm timer中断配置及中断处理
    EXTI_ClearITPendingBit(EXTI_Line17);
    EXTI_InitStructure.EXTI_Line = EXTI_Line17;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断事件
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能LINE17
    EXTI_Init(&EXTI_InitStructure);

    /* Enable the RTC Wakeup Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn; //RTC_Alarm_IRQn RTC_WKUP_IRQn
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


    RTC_GetTime(RTC_Format_BIN, &RTC_AlarmStructure.RTC_AlarmTime);

//每月29号的上午8点定时器唤醒,也可以配制成按星期唤醒,如每周一的早上8点唤醒 

 RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = 8; //小时
    RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = 0; //分钟
    RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0;
    RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;

    RTC_AlarmStructure.RTC_AlarmDateWeekDay = 0x29;
    RTC_AlarmStructure.RTC_AlarmDateWeekDaySel =
            RTC_AlarmDateWeekDaySel_Date; //按日期, 也可以按星期几
    RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay; //屏蔽星期和日期

    RTC_AlarmCmd(RTC_Alarm_A, DISABLE); //关闭闹钟A,以便进行配置参数写入。
    RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);

    RTC_AlarmCmd(RTC_Alarm_A, ENABLE); //开启闹钟A
    RTC_ClearITPendingBit(RTC_IT_ALRA); //清除RTC闹钟A的标志
    EXTI_ClearITPendingBit(EXTI_Line17); //清除LINE17上的中断标志位

}

//定时器唤醒处理中断。

void RTC_Alarm_IRQHandler(void) {
    if (RTC_GetITStatus(RTC_IT_ALRA) != RESET) {
        RTC_ClearITPendingBit(RTC_IT_ALRA);
        EXTI_ClearITPendingBit(EXTI_Line17);
        CHECK_VOL_FLAG = 1; //唤醒后置位检测电压的标志
    }
}

定时每月28日的上午8点唤醒后,程序会从进入stop模式的下一句开始执行。

执行效果

关于stm32l151c8t6在stop低功耗模式下通过RTC alarm唤醒的方法总结_第3张图片

int main(void) {
    platform_rcc_init(); //SYSCLK,PLLCKL,HCLK,PCK1(APB1),PLK2(APB2)时钟初始化配置
    rtc_init(); 
    printf("Boot Initialization!\n");
    SetRTC(75900, 191029, 2);
    platform_rtc_set_alarmA();
    while (1) {
        printf("\r\nwhile begin!\n");
        process_usart(); //对于串口命令的处理
        updatetime();
        printf("datetime:%02d-%02d-%02d %02d:%02d:%02d weakday:%d\n", year, mon,
                day, hour, min, sec, wkday);

        Sys_Standby(); 

    }

}

 

void Sys_Standby(void) {

    PWR_ClearFlag(PWR_FLAG_WU);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);        //使能PWR外设时钟
    printf("\r\n entry stop mode!\n ");
    PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);  //进入stop模式
    Usart1_Init(9600, USART_Parity_No, USART_WordLength_8b);
    printf("\r\n WKUP_DELAY = %d!\n ",WKUP_DELAY);
}

你可能感兴趣的:(学习总结)