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.

MSP430G2231下的定时器中断

Other Parts Discussed in Thread: MSP430G2553

您好!我写了以下一段测试代码,用定时器控制使LED1的亮和灭。
#include "io430.h"
#include "io430G2231.h"

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;
  P1DIR |= BIT0;
  P1OUT |= BIT0; //LED1 亮
 
  CCTL0 = CCIE;
  CCR0 = 20000-1;
 
  TACTL = TASSEL_2 + MC_1; //SMCLK, 增计数模式
  __enable_interrupt();
  while(1);
}
#pragma vecter = TIMERA0_VECTOR
__interrupt void Timer_A(void)
{
  P1OUT ^= BIT0;
}

但是实际运行发现LED1灯一直亮着,无法实现原有的目的,请问程序哪里出错了呢?

  • 1、做做实验看看能不能进入中断;

  • 中断频率太快了吧,1Mhz/20000=50Hz的闪烁

  • 那应该设多少合适呢?我设了65535值也是一样的现象啊。

    32位寄存器最大存值65535,否则会出现warning:Warning[Pe069]: integer conversion resulted in truncation G:\IAR\Timer\mian.c 14

    1MHZ/65535= 15HZ,人眼应该能辨别出点现象吧?

  • 你参考这个程序

    //******************************************************************************

    //  MSP430G2xx3 Demo - Timer_A, Toggle P1.0, CCR0 Cont. Mode ISR, DCO SMCLK

    //

    //  Description: Toggle P1.0 using software and TA_0 ISR. Toggles every

    //  50000 SMCLK cycles. SMCLK provides clock source for TACLK.

    //  During the TA_0 ISR, P1.0 is toggled and 50000 clock cycles are added to

    //  CCR0. TA_0 ISR is triggered every 50000 cycles. CPU is normally off and

    //  used only during TA_ISR.

    //  ACLK = n/a, MCLK = SMCLK = TACLK = default DCO

    //

    //           MSP430G2xx3

    //         ---------------

    //     /|\|            XIN|-

    //      | |               |

    //      --|RST        XOUT|-

    //        |               |

    //        |           P1.0|-->LED

    //

    //  D. Dang

    //  Texas Instruments Inc.

    //  December 2010

    //   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10

    //******************************************************************************

    #include <msp430g2553.h>

    void main(void)

    {

     WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

     P1DIR |= 0x01;                            // P1.0 output

     CCTL0 = CCIE;                             // CCR0 interrupt enabled

     CCR0 = 50000;

     TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode

     _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt

    }

    // Timer A0 interrupt service routine

    #pragma vector=TIMER0_A0_VECTOR

    __interrupt void Timer_A (void)

    {

     P1OUT ^= 0x01;                            // Toggle P1.0

     CCR0 += 50000;                            // Add Offset to CCR0

    }

  • 我按照您的指导修改了程序,编译有错误:
    Error[e46]: Undefined external "_BIS_SR" referred in main ( G:\IAR\Timer\Debug\Obj\main.r43 )
    我做了以下修改:
    _BIS_SR(LPM0_bits + GIE); 用__enable_interrupt();并在其后面加了语句while(1)

    修改后重新编译运行,但是得到的结果还是和之前的一样,LED1无法像预想的那样闪烁...
    请问这会是TIMER坏了吗?

  • _BIS_SR(LPM0_bits + GIE); 是ccs下用的,在iar下是 __BIS_SR(LPM0_bits + GIE);

  • 改了make还是出现如下错误:

    Error[e46]: Undefined external "__BIS_SR" referred in main ( G:\IAR\Timer\Debug\Obj\main.r43 )

    用__enable_interrupt();代替可以吗?这两者有什么区别呢? 

  • _BIS_SR(GIE);可以代替__enable_interrupt();

  • 说反了,你需要的是__enable_interrupt();代替_BIS_SR(GIE);

  • Hardy Hu,您好!编译问题解决了,但是程序依然无法实现我预想的定时中断实现LED闪烁的功能,能帮我再看看是哪里的问题吗?

  • 您好!把期望闪烁频率调低一点,单步调试一下看能不能进中断,只要中断能进去,肯定就闪起来了