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.

MSP430FR5739: MSP430 UART not receiving data

Part Number: MSP430FR5739
Other Parts Discussed in Thread: MSP-EXP430FR5739

Hello,

I'm working on a project that will have an MSP430FR5739 incorporated into a device. This is the first time I've worked with a microcontroller, so I'm just trying to figure out how to use each sub-system. I'm trying to figure out how to send UART data to the chip. I have the MSP-EXP430FR5739 Experimenter's Board, and I'm using that to test my code before moving to the real-life device.

In order to test the UART, I've got code that looks like the following:

#include <msp430.h>
#include <string.h>
//UART parameters, pulled directly from example code.
#define SMCLK_115200     0
#define SMCLK_9600      1
#define ACLK_9600       2
//These are just arbitrary constants for the set_GPIO function.
#define Pin_J0 99
#define Pin_J1 98

#define UART_MODE       SMCLK_9600

void initGPIO()
{
      PJDIR = 0b00000011; //PJ.1, PJ.0
}
void initClockTo16MHz()
{
    // Clock System Setup
    CSCTL0_H = CSKEY_H;                     // Unlock CS registers
    CSCTL1 = 0;                             // Clear DCO settings
    CSCTL1 |= DCORSEL | DCOFSEL_2;          // Set DCO to 16MHz

    // Set all clocks to run off the DCO
    CSCTL2 = SELA__DCOCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA_0 | DIVS_0 | DIVM_0;      // set all dividers to /1

    CSCTL4 |= XT1DRIVE_0;
    CSCTL4 &= XT1OFF;

    do
    {
      CSCTL5 &= ~XT1OFFG;
                                              // Clear XT1 fault flag
      SFRIFG1 &= ~OFIFG;
    }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

    CSCTL0_H = 0;                           // Lock CS registers
}

void initUART()
{
    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST;                      // Put eUSCI in reset

    #if UART_MODE == SMCLK_115200

        UCA0CTLW0 |= UCSSEL__SMCLK;               // CLK = SMCLK

        // Baud Rate Setting
        // Use Table 30-5 in Family User Guide
        UCA0BR0 = 8;
        UCA0BR1 = 0;
        UCA0MCTLW |= UCOS16 | UCBRF_10 | 0xF700;   //0xF700 is UCBRSx = 0xF7

    #elif UART_MODE == SMCLK_9600

        UCA0CTLW0 |= UCSSEL__SMCLK;               // CLK = SMCLK

        // Baud Rate Setting
        // Use Table 30-5 in Family User Guide
        UCA0BR0 = 104;
        UCA0BR1 = 0;
        UCA0MCTLW |= UCOS16 | UCBRF_2 | 0xD600;   //0xD600 is UCBRSx = 0xD6

    #elif UART_MODE == ACLK_9600

        UCA0CTLW0 |= UCSSEL__ACLK;               // CLK = ACLK
        // Baud Rate calculation
        // 32768/(9600) = 3.4133
        // Fractional portion = 0.4133
        // Use Table 24-5 in Family User Guide
        UCA0BR0 = 3;                             // 32768/9600
        UCA0BR1 = 0;
        UCA0MCTLW |= 0x9200;    //0x9200 is UCBRSx = 0x92

    #else
        # error "Please specify baud rate to 115200 or 9600"
    #endif

    UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
}
void set_GPIO(pin, state)
{
    if(pin == Pin_J0)
    {
        if (PJOUT & 0b00000001)
            PJOUT &= (state * 0b00000001);
        else
            PJOUT |= (state * 0b00000001);
    }
    if(pin == Pin_J1)
        {
            if (PJOUT & 0b00000010)
                PJOUT &= (state * 0b00000010);
            else
                PJOUT |= (state * 0b00000010);
        }
}
void delay_milliseconds(int duration)
{
    //Each loop here will wait 1 ms (since clock is 16 MHz) until duration is empty.
    while(duration)
    {
        __delay_cycles(16000);
        duration --;
    }
}

//*************************************************************
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer


    //UART stuff is here
    initClockTo16MHz();
    initUART();
    initGPIO();

    while(1)
    {
        delay_milliseconds(1000);
        if (UCA0IFG & UCRXIFG)
        {
            set_GPIO(Pin_J1,1);
            delay_milliseconds(1000);
            set_GPIO(Pin_J1,0);
        }
        set_GPIO(Pin_J0,1);
        delay_milliseconds(1000);
        set_GPIO(Pin_J0,0);
    }
}

I understand that this code could be greatly improved, and I should probably be using interrupts, but right now I just want to get some evidence that my board is receiving UART data. As far as I understand, my code should run, flashing the J0 LED, forever, until it receives UART data. Once it receives data, the UCRXIFG flag should activate and therefore UCA0IFG & UCRXIFG should return "true", and it should flash the J1 LED once. When I send data from a terminal on my computer (using the Serial Monitor in the Arduino IDE, with baud rate set to 9600), I don't get the second blinking LED. I have attached an oscilloscope to the RXD line to confirm data being sent. With the oscilloscope connected, I punched an R into the Serial Monitor on my computer. I measured a waveform that went (Where H is high and L is low): HHHHHHHHHHHHHHHLLHLLHLHLHLLHLHLLLLHHHHHHHHHHHH. I picked apart this data using an ASCII table, and it shows a start bit, an R, a stop bit, a start bit, a NL line feed, and a final stop bit (which blends into the signal going back to its resting high state). So the correct data is definitely getting sent along to the board. I have all the jumpers set up on the board so that they're arranged the way it came, with the jumpers all lined up to jump across the dotted line on the board. So if I have verified that the right data exists on the board, why am I not seeing my code flash the J1 LED, given that sending an R should result in the UCRXIFG flag being set? I think I did everything right in my UART setup to end up with a 9600 baud rate, one stop bit, and no parity, but maybe there's something else I'm missing?

Unfortunately all the example code in the Resource Explorer uses interrupts, which I'm not looking to do yet. Again, just trying to start getting my feet wet with simple, linear-executing programming before I then move on to handling interrupts and how those work. Thanks!

  • Hello Thomas,

    Thank you for posting, we'll start to look into this issue.

    All the best,

    Colin Adema

  • Hello Thomas,

    I believe you forgot to set the eUSCIA0 UART pins to serve their alternate functions. In your code they're currently just serving as GPIO pins so they won't detect any UART data even though it's on the line.

    Writing these 2 lines in either your GPIO initialization or UART initialization will configure them to be UART pins:

    P2SEL1 |= BIT0 + BIT1;
    P2SEL0 &= ~(BIT0 + BIT1);

    I've tested this and was able to get both LEDs blinking.

    All the best,

    Colin Adema

  • Marvelous! That did the trick! Thank you so much!

    Edit: Actually, I'm not so sure. So yes, that makes the chip able to receive data, but I can't actually read in that data. Once I'm into the "if (UCA0IFG & UCRXIFG)" block, I'm trying to say "long received = UCA0RXBUF", and then make decisions based on what was received. But no matter what I send into the UART, I end up only receiving the newline character (0x000A) into the UCA0RXBUF. It seems like whenever I send data into the UART, all I can retrieve is the LAST character that came in. If I send a character without the trailing newline, then it successfully receives that single character. But I want to be able to send a string of characters in, resulting in behaviors happening. I expected to be able to read from the UCA0RXBUF one character at a time, but instead it looks like each incoming character kicks out whatever might be sitting in the RX buffer, before I get a chance to copy from the buffer to a variable. Is there a "trick" I'm missing for how to do this?

  • Hello Thomas,

    Do you still have those delays in your code when you tried to modify it to receive strings? Those delays will actively work against you when polling to read in more than one byte.

    For instance, if you were to send a string while you're in a delay_milliseconds(1000) line, then the data will fill the buffer while you're waiting to check to see if you've received anything. By the time you check, the last byte of data will be the only thing left, which is why you witness that behavior.

    Removing those delays will fix the problem in the code you posted, I was able to test by creating a receive buffer array and filling it with sample strings like "Hello World!" and was able to see all the data in the buffer. However, if you plan on writing much more code and/or want to keep the delays in the code, then I would highly recommend using interrupts so that you can store data you receive almost immediately after it's sent.

    All the best,

    Colin Adema

  • Understood. I thought the buffer would hang on or something despite the delays. Thanks for your help!

**Attention** This is a public forum