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.

MSP430FR5994: UART not printing every value before termination

Part Number: MSP430FR5994

I have written some code for a UART transmitter, based on the code used in the UART tutorial. In my code, the transmitter converts two ints into strings and then transmits the two across UART onto a UART terminal on my computer.

In my code, I am sending the values "120" and "23". However, I am only receiving "1" from the terminal, like so.

My code, as follows.

#include <msp430.h>
#include <stdio.h>

int i = 120;
int j = 23;
char message1[3];
char message2[3];

unsigned char TXbytes_A = 0;
unsigned char TXbytes_B = 0;

int main(void)
{

    WDTCTL = WDTPW | WDTHOLD;               // Stop Watchdog


    // Configure GPIO
    P2SEL0 &= ~(BIT0 | BIT1);
    P2SEL1 |= (BIT0 | BIT1);                // USCI_A0 UART operation (p93_s)

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    // Startup clock system with max DCO setting ~8MHz
    CSCTL0_H = CSKEY_H;                       // Unlock CS registers
    CSCTL1 = DCOFSEL_3 | DCORSEL;             // Set DCO to 8MHz
    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
    CSCTL0_H = 0;                             // Lock CS registers

    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST;                    // Put eUSCI in reset (p788)
    UCA0CTLW0 |= UCSSEL__SMCLK;             // CLK = SMCLK
    // Baud Rate calculation for 19200
    // 8000000/(16*19200) = 26.042
    // Fractional portion = 0.042
    // User's Guide Table 21-4: UCBRSx = 0xD6
    // UCBRFx = int ( (52.083-52)*16) = 1
    UCA0BRW = 26;                           // 8000000/16/19200, p789
    UCA0MCTLW |= UCOS16 | UCBRF_1 | 0xD600; // UCOS16 = Oversampling enable, used when high frequency clk is used, probably divides everything by 16, UCBRF = fine turner when UCOS16 is active
                                            // 0xD600 is for first 8 bits,
    UCA0CTLW0 &= ~UCSWRST;                  // Initialize eUSCI
    UCA0IE |= UCRXIE;                       // Enable USCI_A0 RX interrupt
    while(1){
    __delay_cycles(200000);
    UCA0IE |= UCTXIE;
    //i++;
    __bis_SR_register(LPM3_bits | GIE);       // Enter LPM3, interrupts enabled
    __no_operation();                           // For debugger
    }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=EUSCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
    {
      case USCI_NONE: break;
      case USCI_UART_UCRXIFG:
          break;

      case USCI_UART_UCTXIFG:           //TXIFG = transmission flag, needs manual activation

          sprintf(message1, "%d", i);

          sprintf(message2, "%d", j);

          // Transmit the byte
          // UCA0TXBUF is taking char message.
          for(TXbytes_A = 0; TXbytes_A < 3; TXbytes_A++){
              UCA0TXBUF = message1[TXbytes_A];   //TXBUF = Transmit Buffer, p791
              }

          // If last byte sent, start sending next message
          if(TXbytes_A == 3)
          {
              UCA0TXBUF = 13; //Next line, see ASCII chart
          }

          for(TXbytes_B = 0; TXbytes_B < 3; TXbytes_B++){
              UCA0TXBUF = message2[TXbytes_B];   //TXBUF = Transmit Buffer, p791
              }
          if(TXbytes_B == 3)
          {
              UCA0TXBUF = 13; //Next line
              UCA0IE &= ~UCTXIE;
          }
          __bic_SR_register_on_exit(LPM3_bits);
          break;

      case USCI_UART_UCSTTIFG: break;
      case USCI_UART_UCTXCPTIFG: break;
      default: break;
    }
}

However, I am able to receive the full set of values when I place a sizable delay within the for-loops of lines 78 and 88 housing the interrupts. Like so:

#include <msp430.h>
#include <stdio.h>

int i = 120;
int j = 23;
char message1[3];
char message2[3];

unsigned char TXbytes_A = 0;
unsigned char TXbytes_B = 0;

int main(void)
{

    WDTCTL = WDTPW | WDTHOLD;               // Stop Watchdog


    // Configure GPIO
    P2SEL0 &= ~(BIT0 | BIT1);
    P2SEL1 |= (BIT0 | BIT1);                // USCI_A0 UART operation (p93_s)

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    // Startup clock system with max DCO setting ~8MHz
    CSCTL0_H = CSKEY_H;                       // Unlock CS registers
    CSCTL1 = DCOFSEL_3 | DCORSEL;             // Set DCO to 8MHz
    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
    CSCTL0_H = 0;                             // Lock CS registers

    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST;                    // Put eUSCI in reset (p788)
    UCA0CTLW0 |= UCSSEL__SMCLK;             // CLK = SMCLK
    // Baud Rate calculation for 19200
    // 8000000/(16*19200) = 26.042
    // Fractional portion = 0.042
    // User's Guide Table 21-4: UCBRSx = 0xD6
    // UCBRFx = int ( (52.083-52)*16) = 1
    UCA0BRW = 26;                           // 8000000/16/19200, p789
    UCA0MCTLW |= UCOS16 | UCBRF_1 | 0xD600; // UCOS16 = Oversampling enable, used when high frequency clk is used, probably divides everything by 16, UCBRF = fine turner when UCOS16 is active
                                            // 0xD600 is for first 8 bits,
    UCA0CTLW0 &= ~UCSWRST;                  // Initialize eUSCI
    UCA0IE |= UCRXIE;                       // Enable USCI_A0 RX interrupt
    while(1){
    __delay_cycles(200000);
    UCA0IE |= UCTXIE;
    //i++;
    __bis_SR_register(LPM3_bits | GIE);       // Enter LPM3, interrupts enabled
    __no_operation();                           // For debugger
    }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=EUSCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
    {
      case USCI_NONE: break;
      case USCI_UART_UCRXIFG:
          break;

      case USCI_UART_UCTXIFG:           //TXIFG = transmission flag, needs manual activation

          sprintf(message1, "%d", i);

          sprintf(message2, "%d", j);

          // Transmit the byte
          // UCA0TXBUF is taking char message.
          for(TXbytes_A = 0; TXbytes_A < 3; TXbytes_A++){
              UCA0TXBUF = message1[TXbytes_A];   //TXBUF = Transmit Buffer, p791
              __delay_cycles(10000);
              }

          // If last byte sent, start sending next message
          if(TXbytes_A == 3)
          {
              UCA0TXBUF = 13; //Next line, see ASCII chart
          }

          for(TXbytes_B = 0; TXbytes_B < 3; TXbytes_B++){
              UCA0TXBUF = message2[TXbytes_B];   //TXBUF = Transmit Buffer, p791
              __delay_cycles(10000);
              }
          if(TXbytes_B == 3)
          {
              UCA0TXBUF = 13; //Next line
              UCA0IE &= ~UCTXIE;
          }
          __bic_SR_register_on_exit(LPM3_bits);
          break;

      case USCI_UART_UCSTTIFG: break;
      case USCI_UART_UCTXCPTIFG: break;
      default: break;
    }
}

With this code, involving the delays, I am able to receive this.

I'd love to deal with the empty array values eventually, but that's another issue entirely. Please let me know if more information is needed. Tangible suggestions on how to modify my code would be well appreciated.

**Attention** This is a public forum