0
\$\begingroup\$

I'll post my code below.

The problem is that the MSP's ISR_TRAP function (a function that handles ISRs that are not otherwise handled) is triggering and trapping me in its endless loop. This happens after P2.1's ISR has successfully triggered, and before the Timer B ISR does anything.

The problems is that TB0CCR4 (Timer B's Capture and Compare Register #4) should trigger an ISR when TB0R counts up to the value contained in it. That value is TB0R+delay, where delay is currently just a global variable at the top of the code. According to the debugger in CCS, the timer is counting up to and past the value stored in CCR4, but not triggering the interrupt.

If the program worked as intended, the MSP's onboard red led would turn on when the button is pressed for P2.1, and then off when the timer reaches the value stored in CCR4.

I can't figure out what's going on here, and any help would be much appreciated. Especially if the explanation can shed some light on what the timer is doing/not doing.

#include <msp430.h> 

//GLOBALS
unsigned int delay = 0x00ff;


//Main
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;

    P8OUT &= ~0xff;
    P2OUT &= ~0xff;
    P1OUT &= ~BIT0;

    P2DIR &= ~BIT1;//input
    P2REN |= BIT1;//pullup
    P2OUT |= BIT1;//sit high

    P8DIR |= BIT4;//output
    P8OUT &= ~BIT4;//output low

    TB0CTL = TBSSEL__ACLK | ID__1 | MC__CONTINUOUS | TBCLR;//enable TB0R and choose its options
    TB0CCR4 = 0x0000;//Initialize TB0CCR4, just in case there's garbage in the register

    PM5CTL0 &= ~LOCKLPM5;

    __enable_interrupt();//enable interrupts

    P2IES |= BIT1;//falling edge interrupt on P2.1
    P2IFG &= ~0xff;//clear flags
    P2IE |= BIT1;//interrupts enabled on P2.1

    while(1){}//go forever
    
    return 0;
}


//INTERRUPTS
#pragma vector = PORT2_VECTOR    //interrupt vector for port 2
__interrupt void Port_2(void)    //interrupt function names can be anything      
{
    switch(__even_in_range(P2IV,P2IV_P2IFG7))
    {
    case P2IV_NONE:   break;
    case P2IV_P2IFG0: break; 

    case P2IV_P2IFG1:    //P2.1 vector
        P2IE &= ~BIT1;   //disable interrupts
        P2IFG &= ~0xff;

        TB0CCTL4 |= CCIE;   //enable timer interrupts
        TB0CCR4 = TB0R + delay;    //set next event

        P1DIR ^= BIT0;   //enable output
        P1OUT ^= BIT0;   //turn on onboard led
        break;

    case P2IV_P2IFG2: break;
    case P2IV_P2IFG3: break;
    case P2IV_P2IFG4: break;
    case P2IV_P2IFG5: break;   
    case P2IV_P2IFG6: break; 
    case P2IV_P2IFG7: break;
    default: break;
    }
}

#pragma vector = TIMER0_B0_VECTOR    //interrupt vector for timer B
__interrupt void T0B7_ISR(void)
{
    switch(__even_in_range(TB0IV,14))
        {
        case  0: break;                         
        case  2: break;                         
        case  4: break;                          
        case  6: break;                         
        case  8:                                 // ccr4

            P1OUT ^= BIT0;    //toggle onboard LED
            P2IE |= BIT1;    //re-enable interrupts after delay
            TB0CCTL4 &= ~CCIE;   //disable interrupts on CCR4

            break;
        case 10: break;
        case 12: break;
        case 14: break;
        default: break;
        }
}
\$\endgroup\$
1
  • \$\begingroup\$ Which MSP430? If I have the same one, I will try this on mine. \$\endgroup\$ – Mattman944 Oct 19 '20 at 8:40
0
\$\begingroup\$

The manual says:

Timer_B Interrupts

Two interrupt vectors are associated with the 16-bit Timer_B module:

  • TBxCCR0 interrupt vector for TBxCCR0 CCIFG
  • TBIV interrupt vector for all other CCIFG flags and TBIFG

TIMER0_B0_VECTOR is for TB0CCR0; TIMER0_B1_VECTOR is for the other CCRs and TBIFG and is handled with TB0IV. Your CCR4 must be handled with the latter.

(And there are symbols for the vector values, something like TB0IV_TBCCR4 or TBIV__TBCCR4.)

\$\endgroup\$
1
  • \$\begingroup\$ That's absolutely right. Changing the vector fixed the problem. For some reason I thought the B0 vector was a superset of the B1 vector, but reviewing the user guide, I see that it isn't. Thanks! \$\endgroup\$ – Formeanlegion Oct 19 '20 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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