关于待机唤醒实验中的疑惑?

2019-07-21 04:48发布

 关于待机模式,我仔细的看了相关的资料! 进入待机模式后,如何退出待机模式有四种方式,在实验12中用的是WKUP上升沿来出发唤醒中断;
我想询问的是,假如当前CPU处于待机模式,那么我只用按一下那个WKUP按键,就会响应相应的唤醒中断,此时是先执行完这个中断的程序,再复位还是其他?
如果在执行唤醒中断程序,在唤醒中断程序中又进入了待机模式那么之前按下的唤醒中断相当于没有能够唤醒?
在下面的代码中,当我开机后没有按键,那么会进入待机模式,此刻下面这句话是不是相当于没有执行?( MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);//抢占2,子优先级2,组2)
那么这个没有设置EXTI0_IRQChannel优先级以及使能中断,后面怎么会通过WKUP来触发唤醒中断呢?
而当我只是按了一下WKUP按键的时候,应该会进入唤醒中断函数void EXTI0_IRQHandler(void),此时会执行这句if(Check_WKUP())//关机?
 {   
  Sys_Enter_Standby(); 
 }
但是因为Check_WKUP()返回的是0所以执行下面的那句话;
假如我只是按了一下的话,那么这个不会进入待机,这时候从中断返回后就重新复位,从main函数的第一句话开始执行么?那样的话,在执行void WKUP_Init(void)这个函数的时候又进入待机模式;
我再长按WKUP按键的时候,会进入唤醒中断,然后因为Check_WKUP()返回的是1,那么会执行  Sys_Enter_Standby();  这时候会进入待机模式啊?怎么会出现实验中的长按然后会进入正常模式呢?
根据实验来说我上面的理解肯定有误,希望有好心人能够帮忙解答下,万分感谢!
下面附上原子的代码:
void Sys_Enter_Standby(void)
{   
 //关闭所有外设(根据实际情况写)
    RCC->APB2RSTR|=0X01FC;//复位所有IO口
 Sys_Standby();//进入待机模式
}
//检测WKUP脚的信号
//返回值1:连续按下3s以上
//      0:错误的触发 
u8 Check_WKUP(void)
{
 u8 t=0;
 u8 tx=0;//记录松开的次数
 LED0=0; //亮灯DS0
 while(1)
 {
  if(WKUP_KD)//已经按下了
  {
   t++;
   tx=0;
  }else
  {
   tx++; //超过300ms内没有WKUP信号
   if(tx>3)
   {
    LED0=1;
    return 0;//错误的按键,按下次数不够
   }
  }
  delay_ms(30);
  if(t>=100)//按下超过3秒钟
  {
   LED0=0;   //点亮DS0
   return 1; //按下3s以上了
  }
 }

//中断,检测到PA0脚的一个上升沿.  
//中断线0线上的中断检测
void EXTI0_IRQHandler(void)
{                           
 EXTI->R=1<<0;  //清除LINE10上的中断标志位   
 if(Check_WKUP())//关机?
 {   
  Sys_Enter_Standby(); 
 }
}
//PA0 WKUP唤醒初始化
void WKUP_Init(void)
{      
 RCC->APB2ENR|=1<<2;     //先使能外设IO PORTA时钟   
 RCC->APB2ENR|=1<<0;     //开启辅助时钟   
  
 GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入  
 GPIOA->CRL|=0X00000008; 
 Ex_NVIC_Config(GPIO_A,0,RTIR);//PA0上升沿触发   
                      
 //(检查是否是正常开)机      
    if(Check_WKUP()==0)Sys_Standby();    //不是开机,进入待机模式 
 MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);//抢占2,子优先级2,组2
}
int main(void)
{
 Stm32_Clock_Init(9);
 delay_init(72);
 uart_init(72,9600);
 LED_Init();
 WKUP_Init();
 while(1)
 {
  LED0=!LED0;
  delay_ms(200);
 }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
49条回答
笨笨的小马驹爱奔跑
1楼-- · 2019-07-21 04:51
 精彩回答 2  元偷偷看……
正点原子
2楼-- · 2019-07-21 10:37
回复【楼主位】sweet0429:
---------------------------------
先执行初始化复位,再进入中断程序。明白这点,上面的问题你就都明白了。
根本原因就是你搞错顺序了。

如果是正常运行,先执行中断程序。
如果是待机状态,则先复位并初始化。
sweet0429
3楼-- · 2019-07-21 14:44
回复【2楼】正点原子:
---------------------------------
嗯!非常感谢,似乎我就是这里弄晕了!听你一说,逻辑上基本就顺了!
但是还有个问题
当我开机后没有按键,那么会进入待机模式,此刻下面这句话是不是相当于没有执行?( MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);//抢占2,子优先级2,组2)
那么这个没有设置EXTI0_IRQChannel优先级以及使能中断,后面怎么会通过WKUP来触发唤醒中断呢?
正点原子
4楼-- · 2019-07-21 15:09
《STM32参考手册》:
退出待机模式
当一个外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件发生时,微控制器从待机模式退出。从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有寄存器被复位。

这里并没有说要WKUP的中断。而是WKUP的上升沿!
sweet0429
5楼-- · 2019-07-21 19:13
 精彩回答 2  元偷偷看……
一信
6楼-- · 2019-07-21 21:57
我也被类似的问题困扰,看上面的一答一问,也明白啦,谢谢大家

一周热门 更多>