求助: LM3S608深度睡眠无法通过定时器唤醒问题~

Other Parts Discussed in Thread: LM3S608

为了降低系统功耗,拟让系统处于深度睡眠状态,通过定时器定时唤醒,事务处理完毕后重新进入深度睡眠状态。

拟用方案是:配置定时器Timer1和定时器Timer2,使能定时器Timer1在深度睡眠状态下工作。事务处理放在Timer1中断处理函数中进行,处理完毕后使能Timer2,在Timer2定时器中断处理函数中进入深度睡眠状态。当Timer1定时器重新进入中断,唤醒MCU处理事务。

MCU: LM3S608,

开发平台IAR 5.5

下面为部分代码:

/*Timer1初始化*/

Timer1_Init(unsigned long ulSysClock)

{

     SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
     SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_TIMER1);
     TimerConfigure(TIMER1_BASE,TIMER_CFG_32_BIT_PER);
     /* 定时器周期 */
    TimerLoadSet(TIMER1_BASE, TIMER_A, (ulSysClock/10));
     /* 定时器优先级 */
     IntPrioritySet(INT_TIMER1A, 5 << 5);
     IntEnable(INT_TIMER1A);
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
     return 0;

}

/*Timer2定时器初始化为2个16位定时器,在Timer_B超时中断中进入深度睡眠,Timer_A另作他用*/

Timer2_init(unsigned long ulSysClock)

{

     SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
     TimerConfigure(TIMER2_BASE,TIMER_CFG_16_BIT_PAIR |  TIMER_CFG_A_PERIODIC | TIMER_CFG_B_ONE_SHOT );
     /* 定时器A周期 */
     TimerLoadSet(TIMER2_BASE, TIMER_A, 60000);
     /* 定时器B周期 */
     TimerLoadSet(TIMER2_BASE, TIMER_B, 60000);
     /* 定时器优先级 */
     IntPrioritySet(INT_TIMER2A, 6 << 5);
     IntPrioritySet(INT_TIMER2A, 1 << 5);   //尝试更改次定时器的优先级,以及周期都不起作用
     IntEnable(INT_TIMER2A);
     IntEnable(INT_TIMER2B);
    TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
     TimerIntEnable(TIMER2_BASE, TIMER_TIMB_TIMEOUT);
     return 0;

}

/* Timer1中断处理函数 */

Timer1_ISR(void)

{

    /* 清中断代码略 */

    /*处理事务代码略*/

   /*使能定时器2 TimerB*/

    TimerEnable(TIMER2_BASE,TIMER_B);

}

 

/* Timer2中断处理函数 */

Timer2_B_ISR(void)

{

     /* 清中断代码略 */

     /* 进入休眠模式 */

    DeepSleep();

}

/* 休眠 */

DeepSleep(void)

{

    /* 设置深度睡眠标志位 */
    g_ulSysDeepSleepModeFlag = 1;
    /*  允许在深度睡眠模式下外设采用寄存器DCGCn配置时钟 */
    SysCtlPeripheralClockGating(TRUE);
    /* 置位DSLPCLKCFG寄存器中的IOSC位,将来进入深度睡眠模式后,系统时钟改由IOSC提供*/
    HWREGBITW(SYSCTL_DSLPCLKCFG, 0) = 1;
    SysCtlDeepSleep();

}

中断向量表配置正确,此处略。定时器1的使能和系统中断使能放在启动函数中,此处略。

现在的问题是:系统运行后,当执行完Timer2_B_ISR中的DeepSleep函数后,就再也无法唤醒了。(在Timer1_Isr中添加打印,控制台没有打印。),尝试更改过定时器的优先级,也没有用。

我还使能了一个GPIO中断以唤醒MCU。如果不在定时器Timer2_B_ISR中断中进入DeepSleep模式,而是通过控制台输入命令让系统进入深度睡眠模式,GPIO产生中断能够正常唤醒MCU。但在定时器中断中进入睡眠模式,GPIO产生中断也不能唤醒MCU。

请大家帮我看看到底是什么问题,谢谢!

 

  • 经过试验,发现如果定时器2(Timer2_B)的优先级不超过

    定时器1,则能够正常唤醒。

    如果均不设置优先级,保持默认优先级,则不能唤醒。

    不知道是什么原因

  • 不知你对中断优先级是如何理解的,datasheet中有讲到:Vector Number大于等于4的异常类型的中断优先级都是programmable,并且0是所有programmable的default priority。谁先产生先处理谁。同时产生,则优先处理vector number较小的异常。

    所以,当Timer2_B触发休眠后,系统一直处于处理Timer2_B的中断中(未退出),因此当Timer1中断产生后,只能等到Time2_B退出后才能处理。因此一直处于“死锁”状态。只有当你设置了优先级并且Timer1的优先级比Timer2_B的优先级高,Timer1产生的中断才能preempt Timer2_B的中断,系统才能唤醒。