请问stm32f030f4p6进入stop外部中断唤醒之后会进入中断处理函数吗?

2019-07-14 17:15发布

          前两天发过一篇帖子,但是还没有结果,重新发一个帖子吧,重新思路,因为之前做的时候很多问题没想明白。
         处理方式:看过很多帖子以及自己实验的结果,如果在中断里面进入stop模式,会导致异常,外部中断无法唤醒的,一般的做法都是在中断里面设置一个标志位,在主程序里面再进入stop模式。

         贴上我昨晚重新修改的程序:                        void Sys_WakeUp(void)        
       {
             SYSCLKConfig_STOP();
             PWM_For_Light_Start(10);
             tiM16_For_Tick_Start();        
             RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
             RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
       }

       void Sys_Sleep(void)
      {   
            PWM_For_Light_Start(0);
            TIM16_For_Tick_Stop();        
            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, DISABLE);
            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, DISABLE);
            EXTI_ClearITPendingBit(EXTI_Line0 | EXTI_Line1);         
            EXTI_ClearFlag(EXTI_Line0 | EXTI_Line1);     
            PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
      }

     在main函数里面添加:
     if(b_sys_enter_stop_mode )
     {
              b_sys_enter_stop_mode = 0;
              Sys_Sleep();
             Sys_WakeUp();                        
     }
     然后在外部中断函数里面添加:
     void EXTI0_1_IRQHandler(void)
    {
          unsigned int i;
          for(i=0;i<2000;i++);
          if(EXTI_GetITStatus(EXTI_Line0)!= RESET )
          {               
                if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)
                     b_current_source = CURRENT_FORM_BAT;
                else
                     b_current_source = CURRENT_FORM_AC;

                b_current_has_change = 1;
                EXTI_ClearITPendingBit(EXTI_Line0);               
                EXTI_ClearFlag(EXTI_Line0);
          }               
          else if(EXTI_GetITStatus(EXTI_Line1)!= RESET )
         {               
                EXTI_ClearITPendingBit(EXTI_Line1);               
                EXTI_ClearFlag(EXTI_Line1);
                if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)
               {
                   b_sys_enter_stop_mode = 1;
                }
        }
        
    }
    我的测试方法是接了数码管,内部有ADC+DMA,还有定时器,数码管上有定时器计时和转换的AD值。
    按照这种处理方式,按下PA1(EXI1),能正常的进入STOP模式,但再次按下PA1(EXTI1),芯片能被唤醒,但马上又进入stop模式了 。    进入休眠的现象是AD值不变化,定时器计数也不走了。
    这个时候如果按下PA0(EXTI0),是能正常唤醒的。

    疑问:
              1. 外部中断唤醒之后,会进入中断处理函数吗?
              2. 如果会进入中断处理函数,那是先进入中断处理函数,还是先恢复到进入stop模式下面的语句开始执行呢?

    根据我上面的现象,我感觉是进入中断处理函数了,让b_sys_enter_stop_mode =1,所以才导致又进入休眠了。
    于是在进入休眠时改成:
           if(b_sys_enter_stop_mode )
          {
                 b_sys_enter_stop_mode = 0;
                 Sys_Sleep();
               
                  Sys_WakeUp();        
                delay_ms(1000);
       }
       现象还是一样。
       于是我再改成:
        if(b_sys_enter_stop_mode )
       {
               b_sys_enter_stop_mode = 0;
                Sys_Sleep();

               Sys_WakeUp();        
               while(1)
              {               
                   DataToDspBuf(tick_for_sys_dida,0);
                   DspLcd3();
             }
       }
       有时能进入休眠,现象是显示的AD值不变,定时器数值也不变,但有时似乎冲过去了,能看到执行了while(1)里面的函数。
       如果是进入了休眠,再次按下PA1(EXTI1),程序就进到while(1)里面执行了,也没有再进STOP模式,这样是比较符合期望的。

       接着修改:
       if(b_sys_enter_stop_mode )
       {
               b_sys_enter_stop_mode = 0;
               Sys_Sleep();

               PA1_Interrupt_Config(DISABLE);
               Sys_WakeUp();        
       }   
       现象是:按下PA1(EXTI1),芯片进入stop模式,但再按PA1,就唤不醒了,我的程序是唤醒之后才禁止中断,似乎程序又冲过了一样,搞不明白。

      其实我想到了用独立看门狗IWDG,修改代码如下:
      if(b_sys_enter_stop_mode )
      {
            b_sys_enter_stop_mode = 0;
            Sys_Sleep();

            Sys_WakeUp();        
                IWdog_Init();
            while(1);
       }

      我的独立看门狗是1s,这样按下PA1(EXTI1),进入休眠,再次按下PA1(EXTI1),马上看门狗就导致系统复位了,我的项目这么做也可以,
      只是还搞不清楚外部中断唤醒到底问题出在哪里?还请高手指点一二。。。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。