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

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条回答
STM32新学习者
1楼-- · 2019-07-23 18:23
谢谢 ,明白了!!!!
421181705
2楼-- · 2019-07-23 22:59
回复【23楼】正点原子:
---------------------------------
原子哥,那我要是想换其他的IO口唤醒怎办配置?比如我要用PB12口。
正点原子
3楼-- · 2019-07-24 02:15
 精彩回答 2  元偷偷看……
421181705
4楼-- · 2019-07-24 03:48
回复【27楼】正点原子:
---------------------------------


void HW_WKUP_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef   GPIO_InitStructure;
EXTI_InitTypeDef   EXTI_InitStructure;

  /* Enable GPIOB clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

  /* Enable SYSCFG clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);


  /* Configure KEY_WEAKUP pin as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /* Connect EXTI Line to KEY_WEAKUP pin */
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);
  
  /* Configure EXTI line */
  EXTI_InitStructure.EXTI_Line = (uint32_t)0x00000001 << EXTI_PinSource12;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI4_15 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}



这样配置中断唤醒,为什么有下降沿不会从STOP Mode唤醒呢?stop模式唤醒后程序也是从头开始运行(等效于复位)???
x1213378204
5楼-- · 2019-07-24 07:55
回复【27楼】正点原子:
---------------------------------
原子哥,如果我在主函数中主动待机,不配置中断,然后给wkup上升沿,是不是也能唤醒呢
x1213378204
6楼-- · 2019-07-24 13:07
回复【27楼】正点原子:
---------------------------------
待机之后断电,然后再上电,能正常启动吗?

一周热门 更多>