stop_mode:
#if DEBUG
printf("MCU Enter Stop Mode!
");
#endif
//set the all GPIO as general GPIO 、remap IRDA in EXIT0 and disable TIM4 interrupt
lowLevelGPIOCfg(); //将一些GPIO打到低电平,避免休眠耗电
ADC_Cmd(ADC1, DISABLE);//关闭ADC
DMA_Cmd(DMA1_Channel1, DISABLE);//关闭DMA
WireControl_EXTI_Enable(); //配置一个外部中断
GPIO_ResetBits(Led_Power, Led_Power_Pin);//关闭电源灯
//GPIO_SetBits(Led_Power, Led_Power_Pin);
BKP_WriteBackupRegister(BKP_DR3, 0xFFFF); //设置一个备份寄存器,作为复位之后的判断标志
//Enter a stop mode
//Request to enter STOP mode with regulator in low power mode, wake by any exit interrupt
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//看门狗计数器访问使能
IWDG_SetReload(0xfff);//设置看门狗重载值,由原来的3秒,改为26秒
IWDG_ReloadCounter();//装载看门狗计数器
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);//进入停止模式
//以下是唤醒之后的配置操作
reconfigSysClkConfig(); //重新配置系统时钟
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);//
//Configure EXTI0 line
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = ACC_EXTI_Trigger ;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising ;
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
EXTI_Init(&EXTI_InitStructure);
WireControl_EXTI_Disable();
//restore the GPIO configurate
GPIO_Configuration(0);
GPIO_SetBits(Led_Power, Led_Power_Pin);
USART_Configuration();
NVIC_Configuration();
TIM_Configuration();
TIM_ITConfig(TIM2, TIM_IT_Update , DISABLE);//开启计数中断
DMA_Configuration();
ADC_Configuration();
BKP_WriteBackupRegister(BKP_DR3, 0x0000);//修改备份寄存器的值
IWDG_Config();
SysTick_Config(SystemCoreClock / 5);
}
本人解释一下大体代码思路,进入休眠之后,会拉低相关的GPIO,确保省电;配置一些外部中断,用来唤醒停止模式;休眠前写入一个值到备份寄存器。
然后休眠,休眠26秒后,看门狗复位,程序重启,判断是否由看门够引起的复位(第一次肯定是由看门够引起的复位,因为备份寄存器里面有休眠之前写入的值),若是由看门狗引起的复位,则不会开启看门狗功能,直接再次进入到这段代码,再次进入休眠,这次休眠,因为没有看门狗,所以可以一直休眠下去(只要没有外部中断触发),当外部中断触发以后,程序就唤醒,之后修改备份寄存器里面的值。
以下是问题:
个人倒是觉得代码和思路都没问题。但是测试的时候发现一个问题。而且是概率性的。
偶尔进入停止模式的时候,我的所有外部中断都无法将其唤醒。非要等复位过后,再次进入停止模式,才能由
外部中断唤醒。这真的是让我蛋碎了一地。。
看各位有啥高见。
此帖出自
小平头技术问答
可能跟我的工程有关。
业务上是这样的,
在程序正常运行的时候,红外接收头的GPIO被定义为定时器捕获的输入,红外POWER键长按5秒之后关机,
在关机之前,将红外接收头的GPIO配置为外部中断(因为停止模式只能由外部中断唤醒或者RTC、USB等唤醒)
然后休眠后,就可以由红外信号唤醒MCU,唤醒后再把红外接收头的GPIO被定义为定时器捕获的输入。
为什么有时候唤不醒,个人推测原因:
在红外POWER键长按的时候,定时器捕获中断一直在触发,当确定收到POWER键长按5秒信号之后关机。
但是手不一定会立刻放开POWER键,所以定时器捕获中断一直在触发,但是在这个时候,我们又在重新配置
红外接收头的GPIO,EXTI,NVIC。所以我推测这里出现了问题。说简单一点就是,在中断函数不断触发的同时
我们在配置它的中断模式,NVIC,这样导致了矛盾。
这只是我的推测,不知大家有何看法。
另外加一条,在我实验的时候发现,虽然在休眠,但是可以响应外部中断(会执行中断服务函数),但就是唤不醒
一周热门 更多>