0
\$\begingroup\$

I recently starting learning how to program a MSP430 and thought I'd start by writing a program to turn a LED on and off every second. However, when I run my code the LED goes on an stays on. When I try stepping through my program, it seems like after going into low power mode the MSP430 never enters the interrupt service routine. Below is my code.

#include <msp430.h> 

/**
 * main.c
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    //set clock to 1 MHz and to use DCO
    DCOCTL = DCO1 + DCO0;
    BCSCTL1 = 7;//RSEL0 + RSEL1 + RSEL2;
    BCSCTL2 = DIVS0 + DIVS1; //SMCLK = MCLK / 8, everything else 0 so it uses DCO as source

    //timer settings
    TA0CTL = TASSEL1 + ID1 + ID0 + MC1 + TACLR; //set SMCLK as source, divide source by 8, set to continuous mode, enable interrupts
    TA0CCTL1 &= ~CAP; //set CAP to 0 for compare mode
    TA0CCTL1 |= CCIE; //enable interrupts

    TA0CCR1 = 15625; //1usec * 8 * 8 * 15625 should give an interrupt once a second

    //set pin 1 for output
    P1DIR = BIT0;

    //enable interrupts globally
    //_BIS_SR(CPUOFF + GIE);
    //GIE;
    _EINT();
    LPM0;
}

#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer_A (void) {
    TA0CCR1 += 15625;
    TA0CCTL1 &= ~CCIFG;
    P1OUT ^= BIT0;
}

As you can see, I've tried a few methods of enabling interrupts globally and entering low power mode at the end of the main fuction, but they all produced the same result. When I try to suspend the program in Code Composer Studio nothing happens and I have to terminate it, which makes it hard to troubleshoot the program.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I wrote some lessons for exactly this question here. It's a ZIP file with, I think, 12 lessons. Feel free. \$\endgroup\$
    – jonk
    Oct 4, 2021 at 7:13

1 Answer 1

1
\$\begingroup\$

You didn't post the processor, so I'll assume MSP430G2553. The TACCR1 (and the others) works differently than TACCR0. The TI user guide says "Any access, read or write, of the TAIV register automatically resets the highest pending interrupt flag" for it. Since your code does not read (or write) to the TAIV register inside the interrupt routine, then it will be stuck with the interrupt flag set but never clearing, so then it will never retrigger again. To fix this problem you can add the following TA0IV read since you don't currently use the other interrupt sources for TIMER0_A1_VECTOR:

#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer_A (void) {
    if (TA0IV == TA0IV_TACCR1) { // add read to TA0IV register to clear interrupts
        TA0CCR1 += 15625;
        TA0CCTL1 &= ~CCIFG;
        P1OUT ^= BIT0;
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.