打印
[STM32L1]

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

[复制链接]
1223|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
原文:https://blog.csdn.net/wuhuijun165/article/details/62466739

#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)模式     
    }
}


使用特权

评论回复
沙发
renzheshengui|  楼主 | 2019-6-12 15:51 | 只看该作者
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);
}


使用特权

评论回复
板凳
renzheshengui|  楼主 | 2019-6-12 15:51 | 只看该作者
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
}   


使用特权

评论回复
地板
renzheshengui|  楼主 | 2019-6-12 15:52 | 只看该作者
/**
  * @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;
}


使用特权

评论回复
5
renzheshengui|  楼主 | 2019-6-12 15:52 | 只看该作者

  • 非待机模式,RTC Wakeup timer中断配置及中断处理

使用特权

评论回复
6
renzheshengui|  楼主 | 2019-6-12 15:52 | 只看该作者
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);  
}


使用特权

评论回复
7
renzheshengui|  楼主 | 2019-6-12 15:53 | 只看该作者
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 );
    }
}


使用特权

评论回复
8
Liu01551108| | 2020-3-16 17:56 | 只看该作者
renzheshengui 发表于 2019-6-12 15:53
void RTC_WKUP_IRQHandler(void)
{
    if(RTC_GetITStatus(RTC_IT_WUT) != RESET)

请问楼主,周期性的从STANDBY 中唤醒,上面的code有没有实际试过。 我运行STM32F205 发现只能wakeup
一次, 同时也发现唤醒后没有执行RTC_WKUP_IRQHandler 中断服务程序,中i断标志位WUTF 一直是SET 的, 所以第二次进入STANDBY 后就无法唤醒。 中断允许和RTC 初始化都是对的。不知道是什么原因。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

4079

帖子

2

粉丝