This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

msp430 在低功耗下看门狗的问题

Other Parts Discussed in Thread: MSP430F1232, MSP430F1491

芯片型号为msp430f1232,晶振为32.768,电池3.6V供电。

看门狗选择aclk, 1s (WDT_ARST_1000),用定时器A定时为500ms一次,每一次TA中断(500ms)喂狗一次。

平时一般处于lpm3模式下,每500ms中断计数器taCount++,同时喂狗(WDTCTL = WDTPW +   WDTCNTCL )。当taCount大于设定值时唤醒_BIC_SR_IRQ(LPM3_bits); 进行处理。

现在的问题是 单片机总是自动重启,似乎喂狗功能没有起作用,但是单独只有定时器是,500ms计时是正常的。

  •   你好,程序不长的话建议贴出来~

  • 程序有点长, 我将主要部分贴出来。

    主程序main.c:

    void main( void )
    {
    STOP_WDT(); //关看门狗

    halInitClock(); //时钟初始化,DCO , 1000000

    halInitTimer(); //定时器初始化,TA , 500ms

    halInitPort(); //初始化端口

    halInitUart(B_9600); //串口初始化

    halInitWDT(); //看门狗始化,1s

    while(1)
    {
      read_send_evt(); //处理事件,lpm1模式下,与看门狗无关

      mcu_sleep(120); //休眠120,等待定时器唤醒
    }

    }

    定时器文件hal_timer.h


    #define TIMER_A_500MS_VALUE (32758/2)

    uint16 time_out ;
    volatile uint16 sleep_count = 0;
    volatile uint16 timer_count = 0;

    void halInitTimer(void)
    {
    TACTL |= TASSEL_1 + TACLR + ID_0 ; //选择ACLK作为定时器的时钟,1分频
    TACTL |= MC_1 + TAIE ; //增加模式,并且使能中断
    TACCR0 = TIMER_A_500MS_VALUE; //中断周期为500ms
    }


    void mcu_sleep(uint16 sleep_s)
    {
    sleep_count = 0 ;
    timer_count = 0 ;
    time_out = sleep_s;
    _BIS_SR(LPM3_bits + GIE); //进入休眠模式 ,在定时器中比较 time_out = 120,即60s
    }


    #pragma vector=TIMERA1_VECTOR
    __interrupt void TimerA1_IRQ(void)//500ms中断 
    {
    switch( TAIV )
    {
    case 2:break;
    case 4:break;
    case 10:
    halClearWdt(); //500ms清一次看门狗
    timer_count ++;//累计
    if(timer_count >= time_out )//time_out = 120,即60s
    {
    timer_count = 0 ;

    _BIC_SR_IRQ(LPM3_bits); //60s唤醒一次
    }

    break;
    }
    }

    看门狗文件hal_wdt.h

    #define STOP_WDT()   st( WDTCTL = WDTPW + WDTHOLD; )
    #define START_WDT() st( WDTCTL = WDTPW; )
    #define CLEAR_WDT() st( WDTCTL = WDTPW + WDTCNTCL; )

    void halInitWDT(void)
    {
    if( WDTIFG & IFG1 )
    {
    IFG1 &= ~WDTIFG; //清中断标志
    }
    WDTCTL = WDT_ARST_1000; //WDT看门狗1s一次,看门狗模式
    START_WDT();
    }
    monitor void halClearWdt(void)//清看门狗记时
    {
    WDTCTL = WDTPW + WDTCNTCL ;
    }

  • 程序有点长, 我将主要部分贴出来。

    主程序main.c:

    void main( void )
    {
    STOP_WDT(); //关看门狗

    halInitClock(); //时钟初始化,DCO , 1000000

    halInitTimer(); //定时器初始化,TA , 500ms

    halInitPort(); //初始化端口

    halInitUart(B_9600); //串口初始化

    halInitWDT(); //看门狗始化,1s

    while(1)
    {
      read_send_evt(); //处理事件,lpm1模式下,与看门狗无关

      mcu_sleep(120); //休眠120,等待定时器唤醒
    }

    }

    定时器文件hal_timer.h


    #define TIMER_A_500MS_VALUE (32758/2)

    uint16 time_out ;
    volatile uint16 sleep_count = 0;
    volatile uint16 timer_count = 0;

    void halInitTimer(void)
    {
    TACTL |= TASSEL_1 + TACLR + ID_0 ; //选择ACLK作为定时器的时钟,1分频
    TACTL |= MC_1 + TAIE ; //增加模式,并且使能中断
    TACCR0 = TIMER_A_500MS_VALUE; //中断周期为500ms 
    }


    void mcu_sleep(uint16 sleep_s)

    sleep_count = 0 ;
    timer_count = 0 ;
    time_out = sleep_s;
    _BIS_SR(LPM3_bits + GIE); //进入休眠模式 ,在定时器中比较 time_out = 120,即60s
    }


    #pragma vector=TIMERA1_VECTOR
    __interrupt void TimerA1_IRQ(void)//500ms中断 
    {
    switch( TAIV )
    {
    case 2:break;
    case 4:break;
    case 10:
    halClearWdt(); //500ms清一次看门狗
    timer_count ++;//累计
    if(timer_count >= time_out )//time_out = 120,即60s
    {
    timer_count = 0 ; 

    _BIC_SR_IRQ(LPM3_bits); //60s唤醒一次 
    }

    break; 
    }
    }

    看门狗文件hal_wdt.h

    #define STOP_WDT()   st( WDTCTL = WDTPW + WDTHOLD; )
    #define START_WDT() st( WDTCTL = WDTPW; )
    #define CLEAR_WDT() st( WDTCTL = WDTPW + WDTCNTCL; )

    void halInitWDT(void)
    {
    if( WDTIFG & IFG1 ) 
    {
    IFG1 &= ~WDTIFG; //清中断标志 
    }
    WDTCTL = WDT_ARST_1000; //WDT看门狗1s一次,看门狗模式 
    START_WDT();
    }
    monitor void halClearWdt(void)//清看门狗记时
    {
    WDTCTL = WDTPW + WDTCNTCL ;
    }

  • 在TA定时器中断函数中执行清狗的语句处设个断点啊,看看断点能命中不,如果不能命中就reset了,那一个是TA定时的时间间隔问题,再有就是逻辑问题,
    把中断函数中判断TAIV的部分去掉 ,也就是去掉switch语句,只保留case10下面的代码,看看结果如何。

  •   你好,一般不建议在中断里喂狗,建议在中断里退出低功耗,然后在while(1)里面喂狗~

  • 我的设备不能随便退出低功耗的,因为是电池供电,要保证时长。在LPM3的模式下,只有定时器还能工作,所以不得不在定时器中喂狗了。为什么不推荐在定时器中喂狗呢?

  • 调试确实是可以进入定时器中断喂狗,但是现象比较奇怪。设备的低功耗模式出现问题,无法唤醒了,但是在调试确实可以到退出低功耗模式语句_BIC_SR_IRQ(LPM3_bits);

  • 请问这个问题解决了吗,我也遇到了低功耗模式下喂狗的问题,不知道怎么弄

  • 您好,有LPM3模式下喂狗的参考例程什么的吗?我看到网上有不少人遇到这个问题

    包括http://bbs.eeworld.com.cn/thread-415367-1-1.html,期待您的回复

     

  • 一进入低功耗,CPU就死了,CPU是不会执行counter++这种代码的,应该是这个原因

  •  加一个额外的看门狗芯片,但是功耗还没具体测

  • 在LPM3模式下,定时器是工作的

  • 你好!

    MCU进入低功耗模式后调试不了,但是可以将断点打在中断里面,这样一旦中断被触发,又可以进行调试了,注意只要PC在走,也就是说程序由运行,那一定是在Active模式,进中断时MCU是被唤醒了的,只是退出后又继续休眠,除非在ISR里面退出LPMX。

    所以请在单步调试下,看WDT的喂狗是否成功。

  • 你好:

           看门狗启动了没有啊?把你启动看门狗的程序能否贴出来看看?我也在做低功耗产品用的是msp430f1491,我们交流交流。我的看门狗可以工作,但是板子在运行几个小时后就会死机。请问你的板子会死机吗?