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.
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