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: Transmitting a varying int with UART

Part Number: MSP430FR5994

Hi. I am trying to transmit a sequence from 1 to 100 with UART with the MSP430FR5994. I have been unable to do so as my code seems to not accept variable values.

My code:

#include <msp430.h>

char RXbuffer[32];
const unsigned char maxRXbytes = sizeof(RXbuffer);
unsigned char RXbytes = 0;
int i = 0;

char message[] = i;
const unsigned char messageLength = sizeof(message);
unsigned char TXbytes = 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(20000);
    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

          // Transmit the byte
          //UCA0TXBUF = UCA0RXBUF;
          UCA0TXBUF = message[TXbytes++];   //TXBUF = Transmit Buffer, p791

          // If last byte sent, disable the interrupt
          if(TXbytes == messageLength)
          {
              UCA0IE &= ~UCTXIE;
              TXbytes = 0;
          }
          __bic_SR_register_on_exit(LPM3_bits);
          break;

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

Please let me know if more information is needed to solve this issue; I'm very much new to this.

  • I have no idea what you think this is doing:

    char message[] = i;
    const unsigned char messageLength = sizeof(message);

    Much more useful would be char message[] = "This is a test.\r\n"; since it has an actual string of data to send.

  • My attempt with that piece of code is to have the value of i increment every time a piece of UART is sent. So that on UART, I will receive "1", "2", "3", "4", etc...
    I probably have a few misunderstandings on how UART works.

  • You don't understand how C initializers work. Exactly once before main() begins.

    Or when a function starts if it is for an auto variable.

  • I've modified my code; I'm now going for printing an int with UART before varying the UART. This is what I have so far.

    #include <msp430.h>
    
    
    int message = 65;
    //const char message2[] = "/n";
    const unsigned char messageLength = sizeof(message);
    
    unsigned char TXbytes = 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
    
              // Transmit the byte
              //UCA0TXBUF is taking char message.
              UCA0TXBUF = message;   //TXBUF = Transmit Buffer, p791
    
              // If last byte sent, disable the interrupt
              if(TXbytes == messageLength)
              {
                  UCA0IE &= ~UCTXIE;
                  TXbytes = 0;
              }
              __bic_SR_register_on_exit(LPM3_bits);
              break;
    
          case USCI_UART_UCSTTIFG: break;
          case USCI_UART_UCTXCPTIFG: break;
          default: break;
        }
    }
    

    Right now, my UART terminal (I'm using Termite) prints "A" from the int. This makes sense, 65 means A in ASCII code. The issue is that I wanted to print "65", not "A". What are some ways to do this? I was able to find someone with a similar issue but the answer was incomplete.

    I suppose this ties back to my misunderstanding of how exactly "UCA0TXBUF = message;" works. If it takes the ASCII code, what happens when I give message a value of more than 127? Since UART is 8-bit, does it just not transmit the message? Or does it split the message?

    Please let me know if more info is needed to solve this issue.

**Attention** This is a public forum