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.

interrupt subroutine not executing properly for longer subroutine

Other Parts Discussed in Thread: MSP430G2553

#include"msp430g2553.h"
void configTA0();
void configTA1();
unsigned int i =1,count=0,j=0,k,j_prev=0;                            // used as counters
unsigned int c1,c2,cc,dump;
char anand = 0x01;
// count for capacitance measure
//----------------------------------0bXXabcCBA     
#define sw1   0xF1               // 0b11110001     
#define sw2   0xC1               // 0b11000001        
//
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MAIN PROGRAM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void main(void) {
    WDTCTL = WDTPW + WDTHOLD;                  // stop watchdog timer
    BCSCTL1 = CALBC1_1MHZ;                     // Set range
    DCOCTL = CALDCO_1MHZ;                      // Set DCO step and modulation
    P1DIR = 0xFF;                              // Set all pins of P1 as output
    P1OUT = 0xFF;                              // Set all pins of P1 high to reduce power consumption
    P2DIR = 0xFF;                              // Set P2 as output port for switching signal
    configTA1();                               // config TIMERA1 for Integration switching time period(using ccr1) and fixed time(using ccr0)
    count=0;                                   // counter to keep track of 3 different cycles
   
   
    //while(1)
    //{
    TA1CTL |= TASSEL_2 + TACLR + MC_2 + ID_0;             // TACLK = SMCLK, clear timer
    __bis_SR_register(CPUOFF + GIE);           // enter low power mode with  global interrupt enabled (start charging for cycles (output is -ve) till fixed time)
    //i=1;
    //}
  while(1);                                                       // halt for testing single cycle
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MAIN PROGRAM END  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// ----------------- TIMER TA1 subroutine definition --------------------------
void configTA1()
{
    TA1CCR0 = 5000;                              // Overall time for integration
    TA1CCR1 = 30;                                // switching interval
    TA1CCTL0 |= CCIE;                            // Compare-mode interrupt enable for ccr0 (overall intg time)
    TA1CCTL1 |= CCIE;                            // compare mode interrupt enable for ccr1 (switching time)
    TA1CTL |= TASSEL_2 + TACLR;                  // TACLK = SMCLK, clear timer
}

//------------------ Timer TA1 CCR0 flag ISR ---------------------------------
#pragma vector=TIMER1_A0_VECTOR
__interrupt void ta1_ccr0(void)
{
                                                
    TA1CTL = MC_0;                              // stop TA1  (So N0 more INTERRUPT DUE TO TIMER1)
    k++;                                                    //  counter to check no of times this ISR executed
    __bic_SR_register_on_exit(CPUOFF);           // Exit LPM0 on return
}
//------------------ Timer TA1  TA1IV  ISR ---------------------------------
#pragma vector=TIMER1_A1_VECTOR
__interrupt void ta1_taiv(void)
{
                                   
    switch (i)
                        {
                        case 1:
                            P2OUT = sw1;
                            i=2;
                            break;
                        case 2:
                            P2OUT = sw2;
                            i=1;
                            break;
                        }
     j++ ;                                                       // counter to check no of times this ISR executed
     TA1CCR1 += 30;
     TA1CCTL1 &=~CCIFG;                    // clear flag (required to clear explicitly in TA1IV vector) and remain in LPM0 even after servicing interrupt
    //__bic_SR_register_on_exit(CPUOFF);         // Exit LPM0 on return
}

I am trying to send data at P2 after every 30 micro sec and stop sending after 5000 micro sec ( 5 milli sec)  but if  I use the switch case for sending two different data alternatively , counter values end up as j =1 and k =1 instead of j =167 and k =1. It works perfectly fine if the whole switch case code is not present in Timer TA1  TA1IV  ISR

Can anyone help me out , what is the problem?

Thanks in advance

  • If your ISR (ta1_taiv) takes longer than 30usec, TA1R will have counted past your next deadline, and you'll not see another interrupt until it wraps (at 5000). Adding the switch() presumably pushed you over this limit.

    You could speed up the processor (at 8MHz, you have 240usec to work with), though this still doesn't get rid of the race -- if some other ISR takes longer than 240usec, you'll still miss.

    For tight timings, your best bet is to use the timer compare mode hardware to wiggle the GPIOs. You can't do this with P2.4+P2.5 (since they're both TA1.2), but you could, e.g. do this with P2.2+P2.5 (TA1.1+TA1.2).

  • Bruce McKenney47378 said:
    (at 8MHz, you have 240usec to work with)

    It's still 30µs, but within these 30µs there ar 240 CPU cycles, not 30.

  • Thanks for fixing that. I should know better than to type before the coffee starts to work.

  • Bruce McKenney47378 said:
    I should know better than to type before the coffee starts to work.

    Well, if I'd do this, I'd never do anything as I have banned coffee from my life long ago (except if I want to get dizzy). A few pretty women would do, but unfortunately my colleagues are all males :(

    However, the MSP doesn't know about time at all, only clock cycles. so it doesn't really make a difference. The correction was only for us poor humans who live the illusion of time :)

**Attention** This is a public forum