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.

CCS/MSP430FR5994: TIMER_A NOT INITIALIZING AND CANNOT SET CSCTLO TO CSKEY WITHOUT CAUSING BUILD TO FAIL

Part Number: MSP430FR5994

Tool/software: Code Composer Studio

SO I AM TRYING TO LEARN HOW TO USE THE TIMERS ON THE MSP430FR5994 FOR INTERRUPTS HOWEVER I HAVE TRIED SETTING UP THE TIMER TO USE THE ACLK AND SET THE CSKEY IN THE CSCTLO REGISTER TO THE CSKEY THE USER GUIDE SAYS MUST BE SET BUT WHEN EVER WRITE EITHER CSCTLO_H = CSKEY_H OR  = 0x96 or FULL BINARY THE BUILD FAILS EVERY TIME AT THIS LINE. ALSO DID THE CODE WITHOUT SETTING BUT THE CLK AT THE TOP AND IT WILL BUILD AND RUN BUT THE TIMER IS NEVER INITIALIZED AND NEVER BEGINS COUNTING UP. CAN SOMEONE EXPLAIN OR SPOT MY ERROR PLEASE AND THANK YOU BELOW IS MY CURRENT CODE.

```

#include "msp430.h"
#include <stdbool.h>
#define COUNTER_VALUE 1250


int main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;

PM5CTL0 &= ~LOCKLPM5;

//establish what the clk source will be
CSCTLO_H = 0xA5;
CSCTL2 |= SELA__VLOCLK;
CSCTLO_H = 0;

//set up and enable timer A or TA0 for UP mode
TA0CCTL0 = CCIE;
TA0CCR0 = COUNTER_VALUE;
TA0CTL = TASSEL__ACLK + MC__UP + ID__8;
TA0CTL |= TAIE;

_BIS_SR(GIE); //ENABLE GLOBAL INTERRRUPTS

//set the max period for 16bit timer operation

//set up capare mode CAP = 0 CLLD = 00 for immediate data transfer from TBXCCRn TO TBxCLn
while(true){
//KEEP THE PROGRAM RUNNING WHILE WAITING FOR LEDS TO BLINK
}

}
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER_A(void){

P1OUT ^= BIT0 + BIT1; //TOGGLE THE LED PINS


TA0CTL |= TACLR; // CLEARING THE TIMER TO RESTART THE COUNT AFTER EACH TOGGLE

}

```

  • >CSCTLO_H = 0xA5;

    That really looks to me like an "oh" rather than a "zero".  That said, I don't see any "CSCTLO" names in msp430fr5994.h, so I don't know how this compiled.

    > TA0CTL |= TAIE;

    Remove this line. It will result in an interrupt you're not interested in, which will cause your program to hang.

    > TA0CTL |= TACLR; // CLEARING THE TIMER TO RESTART THE COUNT AFTER EACH TOGGLE

    Remove this line. For the particular (yet popular) case of CCR0 and Up mode, the timer counter register (TA0R) clears by itself. Doing it again will  actually throw the timing off slightly.

    [Edit: If you're looking for code to "borrow", msp430fr599x_ta1_06.c might be a source for copy/paste:

    http://dev.ti.com/tirex/explore/node?node=AAeWpvsnHIgaFbdPJYpWOg__IOGqZri__LATEST

    ]

  • Yes sorry in my actual code I wrote CSCTL0 but it still had problems with it, however I amended the code to work without it, I now have the timer working for a single interrupt but I was trying to get more than one compare interrupt to work. I have written a second interrupt triggered by A1 vector but the code works only for the red led and does not execute the second isr. I did implement your previous suggestions and they help and allowed me to get up to this point in the current code so thank you! In debugg I can see the CCIFG flag of the TA0CCTL1 reg being set to 1 but it never resets so the green led just stays on all the time while the red led flashes as it is supposed to. Any idea why the second isr is getting hung up on itself? I tried to simply replicate the first working isr only using vector A1.

    ```

    #include "msp430.h"
    #include <stdbool.h>
    #define COUNT_1 12000
    #define COUNT_2 800


    int main( void )
    {
    // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;

    PM5CTL0 &= ~LOCKLPM5;

    P1DIR |= BIT0 + BIT1;   //set port 1 pins 0 and 1 to output
    P1OUT = BIT0 + BIT1;  // initial led turn on


    //set up and enable timer A or TA0 for continous mode

    TA0CCR0 = COUNT_1;
    TA0CCR1 = COUNT_2;
    TA0CTL = TASSEL__ACLK + MC_2; //set the max period for 16bit continuous timer operation
    TA0CCTL0 = CCIE; //enable compare reg 0
    TA0CCTL1 = CCIE; //enable compare reg 1
    //TA0CTL |= TAIE;

    _BIS_SR( GIE); //ENABLE GLOBAL INTERRUPTS

    //set the max period for 16bit timer operation


    while(true){}


    }

    #pragma vector= TIMER0_A0_VECTOR //compare interrupt 0 flashes red led
    __interrupt void TIMER0_A0(void) {
    P1OUT ^= BIT0 ;

    }

    #pragma vector = TIMER0_A1_VECTOR //compare interrupt 1 flashes green led
    __interrupt void TIMER0_A1(void) {

    P1OUT ^= BIT1;

    }

    ```

  • The CCR0 interrupt (TIMER0_A0_VECTOR) is special in that it automatically clears CCTL0:CCIFG. The other interrupts (TIMER0_A1_VECTOR) don't, so you have to do it explicitly.

    If you don't do this, the A1 ISR triggers constantly, and the LED flashes so fast it appears to be on all the time. The CCR0 interrupt still works, since it is higher priority.

    Add this to TIMER0_A1():

    > TA0CCTL1 &= ~CCIFG;   // Clear CCR1 interrupt

  • Thank you Bruce you have been a huge help. I know this stuff is probably trivial for you but I am still getting use to reading data sheets and am working on pulling more info from them and faster as best I can. I have a decent conceptual understanding of the basic programming ways but all my technical details have been on avr and now spreading my wings to other mcu's has proven a challenge. Thanks again.  

**Attention** This is a public forum