[STM32F1] 奇怪的STM32 rtc alarm 中断

[复制链接]
7021|2
 楼主| wilson970 发表于 2014-5-10 23:23 | 显示全部楼层 |阅读模式
本帖最后由 wilson970 于 2014-5-11 09:20 编辑

在调试STM32 RTC ALARM中断退出STOP模式时,刚开始中断能进入,走着走着就不进去苏醒了。
只有在单步运行的时候才可以醒过来,不然一直在 __WFI();这句停留着;
但接着下一次又退不出低功耗了,很奇怪的问题。
众高手有何高见呀?

代码:
/***********************/
void RTC_Configuration1(void)
{
    if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
    {
        PWR_ClearFlag(PWR_FLAG_SB);
        RTC_WaitForSynchro();
    }
    else
    {
        BKP_DeInit();
        RCC_LSEConfig(RCC_LSE_ON);
        //  RCC_LSICmd(ENABLE);
        while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
        {
        }
        /* 选择 LSE 为 RTC 时钟源 */
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

        //   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
        RCC_RTCCLKCmd(ENABLE);
        RTC_WaitForSynchro();
        //    RTC_SetPrescaler(39999);
        RTC_SetPrescaler(32767);

        RTC_WaitForLastTask();
    }
    RTC_ITConfig(RTC_IT_ALR, ENABLE);
    RTC_ITConfig(RTC_IT_SEC, ENABLE);
    RTC_WaitForLastTask();
}

/***********************/
void NVIC_Configuration1(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

      NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;// 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}

/***********************/
int main(void)
{
    RCC_Configuration();
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    //PWR_WakeUpPinCmd(ENABLE);
    PWR_BackupAccessCmd(ENABLE);
    GPIO_Configuration();


   // GPIO_Configuration1();
    EXTI_Configuration();
    RTC_Configuration1();
    NVIC_Configuration1();
    #ifndef  EMB_FLASH
        /* Set the Vector Table base location at 0x20000000 */
        NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
    #else  /* VECT_TAB_FLASH  */
        /* Set the Vector Table base location at 0x08000000 */
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    #endif

        USART1_Init();
        TIM3_PWM_Init();
        Beep_PWMOff();
        TIM2_Config();
        Applications_Init();



    while(1)
    {

        LCD_PowerOff(); //LCD power off
        Beep_PWMOff();
        LCD_BackLightOff();
       // SysTick_ITConfig(DISABLE);
        RTC_ClearFlag(RTC_FLAG_SEC);
        while (RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET)
            ;
        RTC_WaitForSynchro();
        RTC_SetAlarm(RTC_GetCounter() + 3);
        RTC_WaitForLastTask();
        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

        //RCC_Configuration();
        SetHsiSysClock();
       // SysTick_ITConfig(ENABLE);
       // LCD_BackLightOn();
        Beep_PWMOn();
        LCD_BackLightOff();
       // SysTick_ITConfig(DISABLE);
        RTC_ClearFlag(RTC_FLAG_SEC);
        while (RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET)
            ;
        RTC_WaitForSynchro();
        RTC_SetAlarm(RTC_GetCounter() + 3);
        RTC_WaitForLastTask();
        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
        //RCC_Configuration();
        SetHsiSysClock();


    }

}




/*******************************************************************************
* Function Name  : RTC_IRQHandler
* Description    : This function handles RTC global interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTC_IRQHandler(void)
{

//    NVIC_ClearPendingIRQ(RTC_IRQn);

    if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒钟中断
    {
       // LowPowerFlag |= BIT0;
        RTCInterruptCount_Handler();

    }

//        if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//闹钟中断
//        {
//            RTC_ClearITPendingBit(RTC_IT_ALR);  //清闹钟中断
//            RTC_SetAlarm(RTC_GetCounter()+1);
//            LowPowerFlag |= BIT0;
//
//        }

          NVIC_ClearPendingIRQ(RTC_IRQn);
         // NVIC_ClearPendingIRQ(RTCAlarm_IRQn);
          RTC_ClearITPendingBit(RTC_IT_SEC);
         // RTC_ClearITPendingBit(RTC_IT_OW);  //清闹钟中断
}



/*******************************************************************************
* Function Name  : RTCAlarm_IRQHandler
* Description    : This function handles RTC Alarm interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTCAlarm_IRQHandler(void)
{

    if (RTC_GetITStatus(RTC_IT_ALR) != RESET)
    {
        LowPowerFlag |= BIT0;
    //  RCC_ClearFlag();
    }
         EXTI_ClearITPendingBit(EXTI_Line17);
         RTC_WaitForLastTask();
         RTC_ClearITPendingBit(RTC_IT_ALR);
         RTC_WaitForLastTask();
  //  RTC_WaitForSynchro();

}


598330983 发表于 2016-3-22 11:32 | 显示全部楼层
  1. /*
  2. 该模块启动STM32的AWU功能,采用LSI作为RTC时钟,周期性待机和唤醒单片机
  3. 移植该模块 :
  4. 1、只需调用RTC_Alarm_Configuration配置启动函数,
  5. 2、修改工作时间WORK_TIMES、待机时间STANDBY_TIMES,单位秒s,
  6.         设置的为32为闹钟寄存器,0-4294967295s(71582788.25min)

  7. */
  8. #ifndef __RTC_Alarm_H
  9. #define __RTC_Alarm_H

  10. //外部提供接口
  11. #include "main.h"

  12. //宏定义,单位s,0-4294967295s(71582788.25min)
  13. //运行时间
  14. #define WORK_TIMES 2
  15. //待机时间
  16. #define STANDBY_TIMES 2

  17. extern void RTC_Alarm_Configuration(void);

  18. #endif



  1. #include "RTC_Alarm.h"

  2. //RTC中断配置
  3. static void RTC_NVIC_Config(void)
  4. {   
  5.     NVIC_InitTypeDef NVIC_InitStructure;

  6.     NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;        //RTC全局中断
  7.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;    //先占优先级1位,从优先级3位
  8.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;   
  9.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //使能该通道中断
  10.     NVIC_Init(&NVIC_InitStructure);        //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
  11. }

  12. //RTC闹钟初始化:启动时钟、配置LSI做RTC时钟、设置预分频40000得到1Hz
  13. //设置运行时间WORK_TIMES
  14. void RTC_Alarm_Configuration(void)
  15. {
  16.         /* Enable PWR and BKP clocks */
  17.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  18.         /* Allow access to BKP Domain */
  19.         PWR_BackupAccessCmd(ENABLE);       
  20.         /* Reset Backup Domain */
  21.         BKP_DeInit();

  22.     /* RTC clock source configuration ----------------------------------------*/
  23.         /* Enable the LSI OSC */
  24.           RCC_LSICmd(ENABLE);
  25.     /* Wait till LSI is ready */
  26.     while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
  27.     {
  28.     }
  29.     /* Select the RTC Clock Source */
  30.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  31.     /* Enable the RTC Clock */
  32.     RCC_RTCCLKCmd(ENABLE);
  33.         /* Wait for RTC registers synchronization */
  34.         RTC_WaitForSynchro();
  35.         /* Wait until last write operation on RTC registers has finished */
  36.         RTC_WaitForLastTask();
  37.         /* 使能RTC闹钟中断*/
  38.         RTC_ITConfig(RTC_IT_ALR, ENABLE);       
  39.         /* Wait until last write operation on RTC registers has finished */
  40.         RTC_WaitForLastTask();       
  41.         /* Set RTC prescaler: set RTC period to 1sec */
  42.         RTC_SetPrescaler(40000);       
  43.         /* Wait until last write operation on RTC registers has finished */
  44.         RTC_WaitForLastTask();
  45.                
  46.         //中断配置
  47.         RTC_NVIC_Config();

  48.         //设置运行WORK_TIMES
  49.         RTC_SetAlarm(RTC_GetCounter() + WORK_TIMES);
  50.         RTC_WaitForLastTask();
  51. }

  52. //设置闹钟时长并进入待机
  53. //s为中断秒数
  54. void RTC_Enter_StandbyMode(u32 s)
  55. {

  56.     RTC_SetAlarm(RTC_GetCounter() + s);
  57.     RTC_WaitForLastTask();
  58.     // 进入待机模式, 此时所有1.8V域的时钟都关闭,HIS和HSE的振荡器关闭, 电压调节器关闭.
  59.     // 只有WKUP引脚上升沿,RTC警告事件,NRST引脚的外部复位,IWDG复位.
  60.         /* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
  61.     PWR_EnterSTANDBYMode();
  62. }

  63. //中断服务函数
  64. void RTC_IRQHandler(void)
  65. {
  66. if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//闹钟中断
  67. {
  68.           RTC_ClearITPendingBit(RTC_IT_ALR);  //清闹钟中断

  69.         RTC_Enter_StandbyMode(STANDBY_TIMES);//进入待机
  70. }                 
  71. }



zhuomuniao110 发表于 2016-3-22 15:38 | 显示全部楼层
谁有这个报警中断的教程啊,不是很理解这个概念。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

13

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部