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.

[参考译文] MSP430F5529:Timer0中断不工作

Guru**** 2589275 points
Other Parts Discussed in Thread: MSP-EXP430F5529LP

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1182756/msp430f5529-timer0-interrupt-not-working

器件型号:MSP430F5529
主题中讨论的其他器件:MSP-EXP430F5529LP

您好!

我在使中断正常工作时遇到了困难。 我希望红色 LED 每1秒切换一次。

1次切换后、代码停留在 SFR 陷阱中。 在调试中、我看到 GIE 被清除。 在正常模式下、复位后、它会进行一次或两次(随机)切换、然后什么也不会发生。

我缺少什么?

#include <msp430.h>				
#include <lcd.h>
#include <stdlib.h>
#include <stdio.h>

#define RED_LED_ON()        P1OUT |= BIT0
#define RED_LED_OFF()       P1OUT &= ~BIT0
#define RED_LED_TOGGLE()    P1OUT ^= BIT0

void SetupUCS(void);
void SetupTimers(void);

void main(void)
{
	WDTCTL = WDTPW | WDTHOLD;		// stop watchdog timer
	P1DIR |= BIT0;                  // configure P1.0 as output
	P4DIR |= BIT7;                  // configure P4.7 as output
	SetupUCS();
	SetupTimers();

	while(1)
	{
	    GREEN_LED_TOGGLE();
	    __bis_SR_register(LPM0_bits + GIE);
	    __no_operation();
	}
}

void SetupUCS(void)
{
    //set clock source to XT1
    P5SEL |= BIT2+BIT3+BIT4+BIT5;                       // Port PINs function select XT1 32768Hz and XT2 4MHz
    UCSCTL6 &= ~(XT1OFF);                               // XT1 On
    UCSCTL6 &= ~(XT2OFF);                               // XT2 On
    //UCSCTL6 |= XCAP_3;                                  // Internal load cap. necesar? exista 2 condensatori pe placa!

    // Loop until XT1,XT2 & DCO fault flag is cleared
    do
    {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);     // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                              // Clear fault flags
    }
    while (SFRIFG1 & OFIFG);                              // Test oscillator fault flag

    UCSCTL4 &= ~(SELA0 + SELA1 + SELA2);                // ACLK source set to XT1CLK
    UCSCTL4 &= ~ SELS1;                                 // SMCLK source set to XT2CLK
    UCSCTL4 |= SELS0 + SELS2;
    UCSCTL4 &= ~ SELM1;                                 // MCLK source set to XT2CLK
    UCSCTL4 |= SELM0 + SELM2;
    UCSCTL5 &= ~ DIVA1;                                 // divide ACLK by 32
    UCSCTL5 |= DIVA0 + DIVA2;
    UCSCTL5 &= ~ (DIVS0 + DIVS2);                       // divide SCLK by 4
    UCSCTL5 |= DIVS1;
}


void SetupTimers(void)
{
    TA0CCTL0 |= CCIE;                                   // CCR0 interrupt enabled
    TA0CCR0 = 1023;                                     // get an interrupt every 1s
    TA0CTL |= TASSEL0 + MC0 + TAIE + TACLR;             // ACLK, up-mode, TA0 clear, Enable TA0 interrupts
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void TIMER0_A0_ISR(void)
#elif defined(__GNUC__)
    void __attribute__((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
#else
    #error Compiler not supported!
#endif

{
    /* Any access, read or write, of the TA0IV register automatically resets the
    highest "pending" interrupt flag. */
    RED_LED_TOGGLE(); //any timer 0 interrupt. for debug
    switch( __even_in_range(TA0IV,14) )
    {
        case  0: break;                          // No interrupt
        case  2:                                 // CCR1
            RED_LED_TOGGLE();
            break;
        case  4: break;
        case  6: break;
        case  8: break;
        case 10: break;
        case 12: break;
        case 14: break;
        default: break;
    }
}

谢谢、

Catalin

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您启用了 TAIFG 中断、但没有用于它的 ISR。 (TIMER0_A1_Vector)嗯、有点像。 尽管由于使用 CCR1值、ISR 不起作用、但您的 ISR 的编写方式与使用 A1矢量的编写方式相同。 A0_Vector 仅处理 CCR0中断。

    使 TAIE 保持清零、因为您不需要或不想在 CCR0中断之后再使用第二个中断。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 David、

    阅读您的消息以及 Timer_A 方框图让我了解了我的错误。 感谢您的快速回答。 在工作代码下方发布、以防其他人想将其用作参考。 为了进行记录、我使用的是 MSP-EXP430F5529LP 板。

    #include <msp430.h>				
    #include <lcd.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #define RED_LED_ON()        P1OUT |= BIT0
    #define RED_LED_OFF()       P1OUT &= ~BIT0
    #define RED_LED_TOGGLE()    P1OUT ^= BIT0
    
    void SetupUCS(void);
    void SetupTimers(void);
    
    void main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;		// stop watchdog timer
    	P1DIR |= BIT0;                  // configure P1.0 as output
    	P4DIR |= BIT7;                  // configure P4.7 as output
    	SetupUCS();
    	SetupTimers();
    
    	while(1)
    	{
    	    __bis_SR_register(LPM0_bits + GIE);
    	    //For debugger
            __no_operation();
    	}
    }
    
    void SetupUCS(void)
    {
        //set clock source to XT1
        P5SEL |= BIT2+BIT3+BIT4+BIT5;                       // Port PINs function select XT1 32768Hz and XT2 4MHz
        UCSCTL6 &= ~(XT1OFF);                               // XT1 On
        UCSCTL6 &= ~(XT2OFF);                               // XT2 On
        //UCSCTL6 |= XCAP_3;                                  // Internal load cap. necesar? exista 2 condensatori pe placa!
    
        // Loop until XT1,XT2 & DCO fault flag is cleared
        do
        {
            UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);     // Clear XT2,XT1,DCO fault flags
            SFRIFG1 &= ~OFIFG;                              // Clear fault flags
        }
        while (SFRIFG1 & OFIFG);                              // Test oscillator fault flag
    
        UCSCTL4 &= ~(SELA0 + SELA1 + SELA2);                // ACLK source set to XT1CLK
        UCSCTL4 &= ~ SELS1;                                 // SMCLK source set to XT2CLK
        UCSCTL4 |= SELS0 + SELS2;
        UCSCTL4 &= ~ SELM1;                                 // MCLK source set to XT2CLK
        UCSCTL4 |= SELM0 + SELM2;
        UCSCTL5 &= ~ DIVA1;                                 // divide ACLK by 32
        UCSCTL5 |= DIVA0 + DIVA2;
        UCSCTL5 &= ~ (DIVS0 + DIVS2);                       // divide SCLK by 4
        UCSCTL5 |= DIVS1;
    }
    
    
    void SetupTimers(void)
    {
        TA0CCTL0 |= CCIE;                                   // CCR0 interrupt enabled
        TA0CCR0 = 1023;                                     // get an interrupt every 1s
        TA0CTL |= TASSEL0 + MC0 + TACLR;                    // ACLK, up-mode, TA0 clear
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
        #pragma vector = TIMER0_A0_VECTOR
        __interrupt void TIMER0_A0_ISR(void)
    #elif defined(__GNUC__)
        void __attribute__((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
    #else
        #error Compiler not supported!
    #endif
    
    {
        RED_LED_TOGGLE();
    }

    谢谢、

    Catalin