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 interrupt not working

Part Number: MSP430F5529
Other Parts Discussed in Thread: MSP-EXP430F5529LP

Hello,

I am having troubles making the interrupt to work. I want the red led to toggle every 1s.

After 1 toggle the code stays trapped in SFR trap. In debug I see GIE is cleared. In normal mode, after a reset, it toggles once or twice (randomly) and then nothing happens.

What am I missing?

#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;
    }
}

Thank you,

Catalin

  • You enabled the TAIFG interrupt but there is not an ISR for it. (TIMER0_A1_VECTOR) Well, sort of. Your ISR is written as if it were using the A1 vector although it wouldn't work since you use the CCR1 value. The A0_VECTOR services only the CCR0 interrupt.

    Leave TAIE clear since you don't need or want a second interrupt just after the CCR0 interrupt.

  • Thanks David,

    Reading your message along with Timer_A Block diagram made me understand what I did wrong. Thanks for the quick answer. Posting below the working code, just in case someone else wants to use it as a reference. For the record, I am using a MSP-EXP430F5529LP board.

    #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();
    }

    Cheers,

    Catalin

**Attention** This is a public forum