STM32L151C8周期性从待机模式唤醒(RTC Wakeup Timer)

#include "stm32l1xx.h"
#include "system_stm32l1xx.h"
#include "OLED.h"
#include "delay.h"

void RtcWakeUpConfig(void);
u8 RtcInit(void);
u8 RtcConfig(void);

int main()
{
    DelayInit();    //延时初始化
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR时钟
    if(PWR_GetFlagStatus(PWR_FLAG_SB))  //从待机模式唤醒 
    {
        PWR_ClearFlag(PWR_FLAG_SB);
        PWR_ClearFlag(PWR_FLAG_WU);
    }
    OLED_Init();
    RtcInit();

    while(1)    
    {
        OLED_8x16StrP(0,0,"Runing...");         //液晶提示在运行中
        DelayS(2);                              //延时2秒
        RtcWakeUpConfig();                      //RTC wakeup 配置:间隔500ms自动唤醒
//      PWR_WakeUpPinCmd(PWR_WakeUpPin_1,ENABLE);  //Periodic auto-wakeup不需要外部唤醒管脚,故不需要这句
        PWR_EnterSTANDBYMode();   //进入待机(STANDBY)模式     
    }
}

void RtcWakeUpConfig(void)
{
    RTC_WakeUpCmd(DISABLE);
    RTC_ClearFlag(RTC_FLAG_WUTF);
    RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div8);     //选择时钟为外部32.768KHz 8分频
    RTC_SetWakeUpCounter(2047);         //间隔500ms
    RTC_ClearITPendingBit(RTC_IT_WUT);
    RTC_ITConfig(RTC_IT_WUT,ENABLE);    //需要使能中断,不需要中断函数
    RTC_WakeUpCmd(ENABLE);
}


u8 RtcInit(void)
{
    //检查是不是第一次配置时钟
    u8 flag = 0;
    if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)      //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
    {
        /* RTC configuration  */
        flag = RtcConfig();
        if(flag == 0)
        {
            RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
        }
        else
            return flag;
    }
    else
    {
        /* Enable the PWR clock */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

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

        /* Wait for RTC APB registers synchronisation */
        RTC_WaitForSynchro();
    }
    return 0; //ok
}   

/**
  * @brief  Configure the RTC peripheral by selecting the clock source.
  * @param  None
  * @retval None
  */
u8 RtcConfig(void)
{
    /* Enable the PWR clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

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

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

    /* Wait till LSE is ready */ 
    u32 temp = 0;
    while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
    {
        temp++;
        delay_ms(10);
        if(temp >= 250) return 1;//初始化时钟失败,晶振有问题,32768晶振起振极限时间1-5S 
    }

    /* Select the RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

    /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);

    /* Wait for RTC APB registers synchronisation */
    RTC_WaitForSynchro();

    /* Configure the RTC data register and RTC prescaler */
    RTC_InitTypeDef RTC_InitStructure;
    RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
    RTC_InitStructure.RTC_SynchPrediv = 0xFF;
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
    RTC_Init(&RTC_InitStructure);

    return 0;
}

这里写图片描述

  • 非待机模式,RTC Wakeup timer中断配置及中断处理
void RTC_IRQConfig(void)
{
    NVIC_InitTypeDef NVIC_InitStructure; 
    EXTI_InitTypeDef EXTI_InitStructure;
    /* EXTI configuration *******************************************************/
    EXTI_ClearITPendingBit(EXTI_Line20);
    EXTI_InitStructure.EXTI_Line = EXTI_Line20;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Enable the RTC Wakeup Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);  
}

void RTC_WKUP_IRQHandler(void)
{
    if(RTC_GetITStatus(RTC_IT_WUT) != RESET) 
    {
        EXTI_ClearITPendingBit(EXTI_Line20); 
        PWR_RTCAccessCmd(ENABLE);//如果之前禁止了,要重新打开
        RTC_ClearITPendingBit(RTC_IT_WUT);
        PWR_RTCAccessCmd(DISABLE);//可以再关上
        GPIO_ToggleBits( GPIOB, GPIO_Pin_4 );
    }
}

你可能感兴趣的:(STM32)