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.

MSP430FR6989: Why does TB0R not increment?

Part Number: MSP430FR6989

I have the code below, where I am attempting to debounce a button press, and to use the button to toggle the onboard LED.

As can be seen in the msp_init() function, I have set up the B timer to use as my debounce timer, and I am using CCR4 as the register to trigger the B1 vector ISR. When I run the program in debug mode, I've noticed that TB0R is not incrementing, although the family user guide (S. 26.2.1) suggests it should count up with each rising edge of the clock. As a result, TB0R is always 0x0000, and as a result of that, CCR4 always ends up as whatever value I plug into the debounce variable. 

Since I have not set a low power mode, I believe I must be in active mode, and as such all the clocks should be running. Thus, TB0CTL |= TBSSL__ACLK should cause TB0R to increment in step with the ACLK. However, in the debugger TB0R simply does not increment at all. This is true whether I use the step-through functions (which other posts suggest sometimes do not let the timer increment), or the "run/play" button, and whether I set breakpoints within ISRs. Likewise, if I flash the program, I'll be able to turn the light on, but the debounce timer interrupt is never reached, and so I'm never able to turn the light back off with a second button press.

Why doesn't TB0R increment, and what do I need to do to get it to count up?

#include <msp430.h>

//===============FUNCTION PROTOTYPES==========================
void msp_init();

//=====================     GLOBAL SCOPE    =====================
//DEFINITIONS
#define ROWS (BIT1 | BIT2 | BIT3 | BIT4)
#define COLS (BIT4 | BIT5 | BIT6 | BIT7)

//USEFUL CONSTANTS AND OTHER VALUES
unsigned int debounce = 0x01ff;//debounce delay will be finalized later.








//======================    MAIN    =============================
void main(void)
{
    //TIMER STUFF
    WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
    PM5CTL0 &= ~LOCKLPM5;

    //Constants
    unsigned char numbers[3] = {0xff,0xff,0xff};//ones, tens, hundreds
    unsigned char i = 0;
    unsigned char sum;

    //Initialization
    P2OUT &= ~0xff;
    P8OUT &= ~0xff;
    P9OUT &= ~BIT0;
    msp_init();

    __enable_interrupt();

    //Port Interrupts on P2.
    P2IES |= ROWS;//falling edge
    //P2IES &= ~ROWS;//rising edge
    P2IFG &= ~0xff;//clear interrupt flags
    P2IE |= ROWS;//interrupts on 1-4

    //Testing Loop:
    while(1){}

}









//======================    FUNCTIONS   ==============================



//MSP INITIALIZATION
void msp_init()
{
    //Set up output ports for LEDs

    P2DIR   |= BIT6 | BIT7;      // P2.6 and P2.7 set as output
    P2SEL1  &= ~(BIT6 | BIT7);   // connect P2.6 and P2.7
    P2SEL0  |= BIT6 | BIT7;      // to TB0.5 and TB0.6
    P3DIR   |= BIT6 | BIT7;      // P3.6 and P3.7 set as output
    P3SEL1  |= BIT6 | BIT7;      // connect P3.6 and P3.7
    P3SEL0  &= ~(BIT6 | BIT7);   // to TB0.2 and TB0.3

    //Initialization:
    P8DIR |= COLS;//Output
    P8OUT &= ~COLS;//Output 0
    P2DIR &= ~ROWS;//Input
    P2REN |= ROWS;//Pullup Resistor
    P2OUT |= ROWS;//Output to 1 (will be pulled down later)

    TB0CTL = TBSSEL__ACLK | ID__1 | MC__UP | TBCLR;//setup timer b
}




//==========================    INTERRUPTS  ========================

#pragma vector = TIMER0_B1_VECTOR
__interrupt void T0B1_ISR(void)
{
    switch(__even_in_range(TB0IV,14))
        {
        case  0: break;                          // No interrupt
        case  2: break;                          // CCR1 not used
        case  4: break;                          // CCR2
        case  6: break;

        case  8://ccr4
            TB0CCTL4 &= ~CCIE;//disable interrupts
            P2IE |= ROWS;//re-enable interrupts after debounce delay
            break;

        case 10: break;
        case 12: break;
        case 14: break;
        default: break;
        }
}

#pragma vector = PORT2_VECTOR      // associate funct. w/ interrupt vector
__interrupt void Port_2(void)      // name of ISR
{
    switch(__even_in_range(P2IV,P2IV_P2IFG7))
    {
    //I'm using P2.1-2.4 as inputs.
    case P2IV_NONE:   break;   // Vector  0: no interrupt
    case P2IV_P2IFG0: break;   // Vector  2: P2.0

    case P2IV_P2IFG1://BIT1, and so on below
        //On the interrupt:
        P2IE &= ~ROWS;//disable interrupts
        P2IFG &= ~0xff;//clear interrupt flags
        TB0CCR4 = TB0R + debounce;//disable button interrupts for debounce period
        TB0CCTL4 = CCIE;//enable interrupts on TB0CCR4
        //testing
        P1DIR ^= BIT0;
        P1OUT ^= BIT0;
        break;

    case P2IV_P2IFG2: break;
    case P2IV_P2IFG3: break;
    case P2IV_P2IFG4: break;
    case P2IV_P2IFG5: break;   // Vector 12: P2.5
    case P2IV_P2IFG6: break;   // Vector 14: P2.6
    case P2IV_P2IFG7: break;   // Vector 16: P2.7
    default: break;
    }
}

**Attention** This is a public forum