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.

multiple interrupt problem in msp430f5438 experimenter board

sir,

   when i am writing code for which it has to send a charecter through uart for every 50msec and if the receiver microcontroller after receiving the character it has to retransmit  a character and the code follows like this...the problem which i am getting it is transmitting the character after recieving the character it is transmitting back butr the microcontroller cannot recieve it...i think the problem is the way i wrote the interrupts ... please help me with interrupts

//#include <msp430.h>

#include "msp430x54xA.h"
int i=0,j=0,a=0;
int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x03;                            // P1.0 output
  P3SEL = 0x30;                        // P3.4,5 = USCI_A0 TXD/RXD
  TA1CCTL0 = CCIE;                          // CCR0 interrupt enabled
  TA1CCR0 = 50000;
  TA1CTL = TASSEL_2 + MC_1 + TACLR;         // SMCLK, upmode, clear TAR
UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
      UCA0CTL1 |= UCSSEL_2;                     // SMCLK
      UCA0BR0 = 109;                              // 1MHz 115200 (see User's Guide)
      UCA0BR1 = 0;                              // 1MHz 115200
      UCA0MCTL |= UCBRS_1 + UCBRF_0;             // Modulation UCBRSx=1, UCBRFx=0
      UCA0CTL1 &= ~UCSWRST;    
      UCA0IV=0x02;                 // **Initialize USCI state machine**
      UCA0IE |= UCTXIE + UCRXIE;
  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, enable interrupts
  __no_operation();                         // For debugger
}

// Timer A0 interrupt service routine
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{UCA0TXBUF = 'a';
  //P1OUT ^= 0x01;     
  a++;                       // Toggle P1.0
}

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
 {
  switch(__even_in_range(UCA0IV,4))
  {
  case 0:break;                             // Vector 0 - no interrupt
  case 2:                                   // Vector 2 - RXIFG
    while (!(UCA0IFG&UCTXIFG));
    if( UCA0RXBUF == 'B')
   {           // USCI_A0 TX buffer ready?
      
   P1OUT=0x02;
   for(i=0;i<=255;i++)
   {for(j=0;j<=255;j++);
   }
   P1OUT=0x00;
UCA0TXBUF = 'b';
  for(i=0;i<=255;i++)
  {for(j=0;j<=255;j++);
  }
   }  
   if( UCA0RXBUF == 'A')
   {           // USCI_A0 TX buffer ready?
     
   P1OUT=0x01;
   for(i=0;i<=255;i++)
   {for(j=0;j<=255;j++);
   }
   P1OUT=0x00;
   }
                 // TX -> RXed character
    break;
  case 4:

     break;                             // Vector 4 - TXIFG
 default: break;

  }
}

please solve my problem

Regards,

Lokesh Bathala.

  • lokesh bathala said:
        while (!(UCA0IFG&UCTXIFG));

    This line is superfluous (well, even more than that, see below). Even if it is in the original code. Since transmit and receive run on the same boudrate, you can be sure that the previous byte has been sent when you received a new one. Even in case of a delay, you won't overwrite an unwritten TXBUF content, because in this case you'd have an RX buffer overrun too and skipped receiving a byte (and therefore skipped echoing a byte).

    It is also strongly discouraged to use any type of busy-waiting loop inside an ISR. ISRs are there to react on events, do the necessary things and exit. The are not intended to wait for a second event. If you cannot think of a different way to do it, you should use a global buffer and handle the second event in a second interrupt. E.g. writing the received byte to a global variable, and when teh TX interrupt comes, read the global variable. But in any case don't do any waiting loops or other time-consuming stuff inside an ISR.

    Why don't you get your data echoed? Well, it is related to the wait for TXIFG. You enabled the TX interrupt (UCTXIE) too. So when TXBUF is empty, the ISR is called. It reads UCA0IV and gets '4', but at the same time clears UCTXIFG. Then you don't write to TXBUF in case 4. This means, the USCI will never set TXIFG again. Now teh RX interrupt comes. You wait for TXIFG to be set. But you already cleared it in the previous TX interrupt. And it is never set again since it only sets when TXBUF goes empty (which already happened and won't happen again since nothing was written to TXBUF), so you eternally wait at this point.

    I know that you copied the waiting loop from demo code. But the demo code didn't use TX interrupt and therefore it worked. Sort of.

    Hint:never try to expand demo code before you completely understood how and why it works.

**Attention** This is a public forum