你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32f072 通过RTC闹钟唤醒STOP睡眠模式问题

[复制链接]
rockt-210467 提问时间:2017-9-14 14:42 /
我通过设置RTC时钟定时每一分钟唤醒MCU一次进行一些查询检测工作。但会偶尔发现无法唤醒MCU,感觉RTC无法产生中断,应该是RTC的问题,现在就是不知道是硬件引起的还是软件引起的。因为有的机子从来没有问题,有的偶尔会有,但不是每次都出现,有的用了很久也没有出现过。很困扰。以下是RTC的处理代码,有哪位大侠搞过RTC闹钟唤醒睡眠的,帮看看有没有问题。

/******************************************************************************
**函数名: Init_RTC
**入      口:
**返      回:
**功            能: RTC配置初始化
*******************************************************************************/
void Init_RTC(void)
{
        RTC_Config();
        GetRTCTime();
        Set_RTC_Alarm_Minute();        //设置闹钟时间

}




/******************************************************************************
**函数名:RTC_Config
**入      口:
**返      回:
**功            能: RTC配置,24小时的时间格式
*******************************************************************************/
void RTC_Config(void)
{
        RTC_InitTypeDef RTC_InitStructure;
       
          RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE );     /* Enable the PWR clock */  
          PWR_BackupAccessCmd( ENABLE );                            /* Allow access to RTC */

          if( RTC_ReadBackupRegister( RTC_BKP_DR0 ) != RTC_BKP_VALUE )//如果掉电了,则重新初始化时间
            {
                    RCC_LSEConfig( RCC_LSE_ON);    /* Enable the LSE OSC */
                    while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET );   /* Wait till LSE is ready */  
            
                    RCC_RTCCLKConfig( RCC_RTCCLKSource_LSE );   /* Select the RTC Clock Source */
            
                    RCC_RTCCLKCmd( ENABLE );        /* Enable the RTC Clock */
                    RTC_WaitForSynchro();           /* Wait for RTC APB registers synchronisation */

                    //设置RTC时钟分频,1秒
                    RTC_InitStructure.RTC_AsynchPrediv = 127;
                    RTC_InitStructure.RTC_SynchPrediv = 255;//255
                    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //24小时的时间格式
                    if( RTC_Init( &RTC_InitStructure ) == ERROR )
                      {
                      /* 此处作设置失败处理 */   
                      }

                    //设置默认的时间:2017-1-1- 12:30:00
                    SetCalendarTime( DEFAULT_HOUR, DEFAULT_MIN, DEFAULT_SEC);        //时间
                    SetCalendarDate(3,DEFAULT_YEAR,DEFAULT_MON,DEFAULT_DAY);                //日期

                    bPowerDown = TRUE;//系统掉电,又重新上电
                    bSynchronizeTime = TRUE;
           
            }
          else
            {
                    RTC_WaitForSynchro();                   /* Wait for RTC APB registers synchronisation */
                    RTC_ClearFlag( RTC_FLAG_ALRAF );        /* Clear the RTC Alarm Flag */
            }
}


/******************************************************************************
**函数名:Set_RTC_Alarm_Minute
**入           口:
**返           回:
**功           能: 设置RTC报警时间,单位为分钟
*******************************************************************************/
void Set_RTC_Alarm_Minute(void)
{
        RTC_AlarmTypeDef RTC_AlarmStructure;
        unsigned char hour = 0;
        unsigned char min = 0;
//        unsigned char sec = 0;

        //GetRTCTime();                //获取系统时间
       
        hour = RTC_Time[3];
        min = RTC_Time[4];

        min += 1;
       
        if(min >= 60)
        {
                min = 0;
                hour += 1;
                if(hour >= 24) hour = 0;
        }

          RTC_ITConfig( RTC_IT_ALRA, DISABLE );    /* Enable the RTC Alarm A Interrupt */       
          RTC_AlarmCmd( RTC_Alarm_A, DISABLE );     /* Disable the Alarm A */

          RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
          RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = hour;
          RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = min;
          RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0;

  /* Set the Alarm A */
          RTC_AlarmStructure.RTC_AlarmDateWeekDay = 31;
          RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
          RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;

          RTC_SetAlarm( RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure ); /* Configure the RTC Alarm A register */

          RTC_ITConfig( RTC_IT_ALRA, ENABLE );    /* Enable the RTC Alarm A Interrupt */

          RTC_AlarmCmd( RTC_Alarm_A, ENABLE );    /* Enable the alarm  A */

         
}


/******************************************************************************
**函数名:GetRTCTime
**入           口:
**返           回:
**功           能: 读取RTC时间
*******************************************************************************/
void GetRTCTime(void)
{
        unsigned char Getweek = 0;

        GetCalendarTime(&RTC_Time[3],&RTC_Time[4],&RTC_Time[5]);
        GetCalendarDate(&Getweek,&RTC_Time[0],&RTC_Time[1],&RTC_Time[2]);

}


/******************************************************************************
**函数名:RTC_IRQHandler
**入      口:
**返      回:
**功            能: 日历报警中断
*******************************************************************************/
void RTC_IRQHandler( void )
{
          if( RTC_GetITStatus( RTC_IT_ALRA ) != RESET )
            {
                   
                if((gStatus != G_POWER_OFF)&&(gStatus != G_MODE_CHARGE))
                {
                        GprsConnectInTime++;
                }
                else
                {
                        GprsConnectInTime = 0;
                }

                bOneMinuteFlg = TRUE;//一分钟时间到
                bBatTest1Min = TRUE; //一分钟测量一次电量
                                                       
                RTC_ClearITPendingBit( RTC_IT_ALRA );
            }
           
            EXTI_ClearITPendingBit(EXTI_Line17);
           
}


                      }
            }
}

/******************************************************************************
**函 数 名:
**入      口:
**返      回:
**功      能:
*******************************************************************************/
void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        EXTI_InitTypeDef EXTI_InitStructure;
       
        //RTC时钟中断
          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;
          EXTI_Init(&EXTI_InitStructure);

          NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);

          RTC_ClearITPendingBit( RTC_IT_ALRA );
        EXTI_ClearITPendingBit(EXTI_Line17);
}

/******************************************************************************
**函数名:main
**入      口:
**返      回:
**功            能: 系统主程序
*******************************************************************************/
int main(void)
{        
        .............
        Init_RTC();                        //日历时间初始化
       ................
        NVIC_Configuration();        //系统中断配置初始化
       
          while(1)
        {
            //每分钟检测一次
           if(bOneMinuteFlg == TRUE)
          {
                bOneMinuteFlg = FALSE;
                GetRTCTime();                        //获取系统时间
                Set_RTC_Alarm_Minute();        //设置闹钟中断时间

          }
          ..........................
          SleepMode();
          ............................
       
}


收藏 评论12 发布时间:2017-9-14 14:42

举报

12个回答
MrJiu 回答时间:2017-9-14 14:52:42
哇,这种少量事件很难处理。。。有的行,有的不行。。。不能唤醒只的是,会漏掉一分钟?还是说一睡不醒?
rockt-210467 回答时间:2017-9-14 15:06:04
睡不醒了一样,通过按键中断唤醒后,又正常了
kylongmu 回答时间:2017-9-14 15:17:10
你的RTC时钟是外部还是内部?外部的话,Crystal的质量是否可靠,负载电容是否合适?
rockt-210467 回答时间:2017-9-14 15:26:18
使用的外部晶振32.768K。我要先确认如果软件没有问题再去排查硬件问题
回答时间:2017-9-14 16:32:15
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;这个把秒也加上
另外,如果是一分钟唤醒一次,不如使用RTC WakeUp,这个简单方便。
回答时间:2017-9-14 16:33:00
1分钟唤醒一次,这样只开分就可以了。把日、小时、秒都关了。
rockt-210467 回答时间:2017-9-14 18:01:54
如果不关会有问题吗
回答时间:2017-9-15 08:36:46
如果不关,他是要等到时分秒都匹配了才会唤醒。下面是我使用时分唤醒的配置:
RTC_AlarmStructure.RTC_AlarmMask             = RTC_AlarmMask_Seconds | RTC_AlarmMask_DateWeekDay;
rockt-210467 回答时间:2017-9-15 09:03:32
安 发表于 2017-9-15 08:36
如果不关,他是要等到时分秒都匹配了才会唤醒。下面是我使用时分唤醒的配置:
RTC_AlarmStructure.RTC_Ala ...

hour = RTC_Time[3];
        min = RTC_Time[4];

        min += 1;
        
        if(min >= 60)
        {
                min = 0;
                hour += 1;
                if(hour >= 24) hour = 0;
        }

          RTC_ITConfig( RTC_IT_ALRA, DISABLE );    /* Enable the RTC Alarm A Interrupt */        
          RTC_AlarmCmd( RTC_Alarm_A, DISABLE );     /* Disable the Alarm A */

          RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
          RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = hour;
          RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = min;
          RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0;

你说的这个我也会试试。不过以上我是根据每次当前时间设置下一次闹钟时间的,就是下一次分钟闹钟,我觉得这个也没有什么问题。
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版