stm32进入stop后,部分高优先级中断能唤醒的问题
我用的是stm32l152rbt6的片子,利用WFI进入stop模式,开启了4个外部中断和一个RTC定时唤醒喂狗的中断,void EXTIX_Init(void) {EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDefGPIO_InitStructure;
//
GlobalInitFlag =0;
GlobalOperateFlag =0;
GlobalFeedFlag =0;
cardsuccess = 0;
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOC, ENABLE); //使能PB,PE端口时钟
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //下拉
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOC,EXTI_PinSource2);
SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOC,EXTI_PinSource6);
SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOC,EXTI_PinSource11);
SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOC,EXTI_PinSource5);
//
EXTI_ClearITPendingBit(EXTI_Line2);
EXTI_InitStructure.EXTI_Line=EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line6);
EXTI_InitStructure.EXTI_Line=EXTI_Line6;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x05;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line11);
EXTI_InitStructure.EXTI_Line=EXTI_Line11;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_WackupConfig(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* EXTI configuration */
EXTI_ClearITPendingBit(EXTI_Line20);
EXTI_InitStructure.EXTI_Line = EXTI_Line20;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RTC_ITConfig(RTC_IT_WUT, ENABLE);
RTC_ClearFlag(RTC_FLAG_WUTF);
RTC_WakeUpCmd(DISABLE);
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_SetWakeUpCounter(20);
/* Enable the alarmA */
RTC_WakeUpCmd(ENABLE);
}
正常情况五个中断都能唤醒单片机,但有时会出现只有两个最高优先级的中断能唤醒单片机,其它3个都唤醒不了单片机
下面是进入低功耗的代码
void LowerPoer() {
CloseLight();
// __set_PRIMASK(1);
KeyCloseInterrupt();
CardCloseInterrupt();
FingerCloseInterrupt();
NrfCloseInterrupt();
GlobalInitFlag = 0;
delay_ms(1);
// if(GPIO_ReadInputDataBit(GPIOC ,GPIO_Pin_5 )!=0x01){
// if(EnterLPCD()){
// MFRST_L ;
// }
// }
EXTI_ClearITPendingBit(EXTI_Line2);
NVIC_ClearPendingIRQ(EXTI2_IRQn);
EXTI_ClearITPendingBit(EXTI_Line11);
NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
EXTI_ClearITPendingBit(EXTI_Line6);
EXTI_ClearITPendingBit(EXTI_Line5);
NVIC_ClearPendingIRQ(EXTI9_5_IRQn);
EntryLowerPoer();
}
void EntryLowerPoer(void ) {
GPIO_InitTypeDefGPIO_InitStructure;
RCC->AHBENR = 0x00000000;
RCC->APB1ENR = 0x00000000;
RCC->APB2ENR = 0x00000000;
RCC->AHBLPENR= 0x00000000;
RCC->APB1LPENR = 0x00000000;
RCC->APB2LPENR = 0x00000000;
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA |
RCC_AHBPeriph_GPIOB |
RCC_AHBPeriph_GPIOC |
RCC_AHBPeriph_GPIOD |
RCC_AHBPeriph_GPIOE |
RCC_AHBPeriph_GPIOH, ENABLE );
/* Set all unused GPIO pins as analog inputs to reduce the power consumption */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_Init(GPIOH, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7
|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA |
RCC_AHBPeriph_GPIOB |
RCC_AHBPeriph_GPIOC |
RCC_AHBPeriph_GPIOD |
RCC_AHBPeriph_GPIOE |
RCC_AHBPeriph_GPIOH, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_FastWakeUpCmd(ENABLE);
PWR_UltraLowPowerCmd(ENABLE);
// Rtc_Init(); //RTC初始化
// RTC_WackupConfig();
EXTIX_Init();
// SysTick->CTRL &= (~SysTick_CTRL_ENABLE);
//
/* Disable VREFINT to save current */
PWR->CR |= PWR_CR_ULP; //10ua
/* Disable PVDE to save current */
PWR->CR &= (~PWR_CR_PVDE);
// RTC_configration();
// exti.ReceiveInitFlag= 1;
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
// __set_PRIMASK(0);
////// GPIO_ResetBits(GPIOC,GPIO_Pin_0);
////// delay_ms(500);
}
有谁遇到类似的问题吗,麻烦解答一下
如果那3个中断没有唤醒的话,一个方法就是直接调试那三个中断,看看原因在哪里。先不用进入低功耗,看看中断能否发生,然后再进去试试。注意尽量不要用到调试脚,否则不好观测了。 butterflyspring 发表于 2018-12-5 15:36
如果那3个中断没有唤醒的话,一个方法就是直接调试那三个中断,看看原因在哪里。先不用进入低功耗,看看中 ...
查了一些资料,说进入低功耗模式前关闭所有中断,唤醒后在打开全部中断,可以避免这个现象,测试的结果短期内没有复现这个现象 当然关闭所有中断就不会有唤醒源了,所以要关闭不相关的中断。
页:
[1]