关于待机模式,我仔细的看了相关的资料!
进入待机模式后,如何退出待机模式有四种方式,在实验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);
}
}
---------------------------------
明白了,其实这个实验关键是要明白是初始化里的Check_WKUP()先执行还是中断里的Check_WKUP()先执行,即你说的1、2点和原子哥在1楼的回复,对吧。
一周热门 更多>