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

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;

你说的这个我也会试试。不过以上我是根据每次当前时间设置下一次闹钟时间的,就是下一次分钟闹钟,我觉得这个也没有什么问题。
五哥1 回答时间:2017-9-17 21:32:36
换个硬件再测试下是否为软件问题
rockt-210467 回答时间:2017-9-19 10:52:16
不过还有一个现象,我设定的是每分钟闹钟中断一次并更新时间,但是偶尔发现中间有一次一分钟时间过来也不产生中断,然后时间就慢了一分钟,过了大概过10分钟这样然后时间又对应上了,感觉是连续产生两次中断,时间刷了两次。每次中断都是读取RTC时间,不是人为加一累计。
rockt-210467 回答时间:2017-10-11 17:11:16
这个问题有可能是GetRTCTime这个函数调用中处理有问题,读取时间存储是数组,则是通过指针传递,然后这个数据没有得到及时更新,造成时间延后。但本身时间已经是走了,而读取的时间没有更新,则设定的闹钟就永远的错过了

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版