这几天在调试stm32f030f4p6这颗芯片进入stop模式,然后被唤醒,我是用PA1做的,PA1配置成外部下降沿中断,来做开关键:板子开机 -> 按下PA1 -> 芯片进入stop模式 -> 按下PA1 -> 外部中断将芯片唤醒 。。。 程序处理如下: void EXTI0_1_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line1)!= RESET ) { if(mcu_state == MCU_IS_RUNNING) mcu_state = MCU_IS_STOP; else if(mcu_state == MCU_IS_STOP) mcu_state = MCU_IS_RUNNING; b_mcu_exti_has_intterrupt = 1; EXTI_ClearITPendingBit(EXTI_Line1); } } 然后在main里面: void MCU_State_Change(void) { if(b_mcu_exti_has_intterrupt) { b_mcu_exti_has_intterrupt = 0; if(mcu_state == MCU_IS_RUNNING) { } else if(mcu_state == MCU_IS_STOP) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI); } } } 现在发现两个问题: 1.感觉按键不是很灵敏,有时要按几下才能进入休眠,有时休眠要按几下才能唤醒,外部中断我仿真过,每次按下按键都能进到中断里面。 2.芯片进入stop模式之后被唤醒,时钟明显感觉变慢了,我在数码管上做了TIM16计数,我后来在: if(mcu_state == MCU_IS_RUNNING) { TIM16_For_Tick_Start(); /*开定时器*/ } 这里又将TIM16初始化了一次,感觉还是慢了,不知道是什么问题 |
If Flash memory programming is ongoing, the Stop mode entry is delayed until the memory
access is finished.
If an access to the APB domain is ongoing, The Stop mode entry is delayed until the APB
access is finished.
void EXTI0_1_IRQHandler(void)
{
unsigned int i;
for(i=0;i<200;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;
if(mcu_state == MCU_IS_STOP)
{
Wakeup_Form_Stop_Mode();
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
else if(EXTI_GetITStatus(EXTI_Line1)!= RESET )
{
EXTI_ClearITPendingBit(EXTI_Line1);
if(mcu_state == MCU_IS_RUNNING)
{
Enter_Stop_Mode();
}
else
{
Wakeup_Form_Stop_Mode();
}
}
}
void Enter_Stop_Mode(void)
{
mcu_state = MCU_IS_STOP;
sys_sleep_all();
NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
}
void Wakeup_Form_Stop_Mode(void)
{
mcu_state = MCU_IS_RUNNING;
SYSCLKConfig_STOP();
PWM_For_Light_Start(10);
TIM16_For_Tick_Start();
}
我还好是退回到最开始的那种做法了,不用定时器,按下按键进入中断,在中断里面判断当前芯片的状态,然后修改状态,执行相应的程序,这种做法休眠是进去了,但是休眠之后按此按键 还是唤醒不了芯片 PA0 PA1都唤醒不了,这个问题都困扰我三天了
你说的太对了,我在唤醒的地方加了个SystemInit()就没问题了,应该是进入stop的时候程序执行到哪里,唤醒之后接着从这里执行吧,关于按键的问题,我想有可能是因为按键抖动的原因,我在查查,非常感谢您
这个代码是你自己写的吗? 我在我的库文件里面找不到这个函数,我直接复制你的这段代码,试了下,也可以的,非常感谢
不要用SystemInit(),直接用我上面的那个代码SYSCLKConfig_STOP(void),因为调用SystemInit()的时间可能会大于SYSCLKConfig_STOP,这对于实时性要求高的系统是恢复系统时钟越快越好。唤醒之后从PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);后面的代码接着执行。
这个是官方提供的一个函数,你可以试着让系统启动后自动进入休眠模式然后再自动唤醒或者按键唤醒,这个可以测试是不是按键的问题。
我仿真看了下,有的时候连着发生了两次中断,这才是问题的根源,暂时还没想到什么办法
进入按键唤醒中断后马上调用恢复系统时钟函数SYSCLKConfig_STOP,然后重新初始化该按键引脚关闭掉中断使能,等需要进入时再次配置为中断引脚。
我这个引脚是做开关用,呵呵,这种办法我也想过,理论上都行不通,我可能会连续的按下这个按键来测试开关功能,也可能按下这个按键 半年不动它
你这种做法不对,我是做开关按键,所以不适用,我为了消抖,在按键按下进入中断之后,又开了一个定时器,定时时间为10ms,如果定时器时间到,就到定时器中断里面去处理进入stop模式,这么做进入stop模式很灵了,但是外部中断无法唤醒芯片了,我用了EXTI0和EXTI1这两个中断,都没办法唤醒了
你感觉对就行。
我也是作为开关机按键使用的,感觉特别灵敏,无论开机关机都没有误操作过。
我就是感觉IO口的状态切换上不知道什么时机最好,现在的问题是为什么外部中断都无法唤醒芯片了