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.

MSP430FR2355: Receiving 9 bytes over UART? - How does the RXBuffer work?

Part Number: MSP430FR2355


Hello again,

my project includes a C02 sensor (MH-Z19C) wich sends the CO2 concentration over UART in 9 bytes (https://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19c-pins-type-co2-manual-ver1_0.pdf  page 6). However, I'm running into the isue, that the "Registers" Tab tells me, that there is a Value in the RX-Buffer, and my oscilloscope clearly shows that the MSP430 aswell as the sensor send the right signals, if i try to tred the value from the buffer, it doesn't work. I assume that my code is wrong, because there is a value in the Register UCA0RXBUF.

I have hooked up the TX cable from the sensor to the RX pin on the MSP430 (1.6) as well as the TX to the RX respectivley.
The Baudrate (9600) fits to both the MSP and the sensor.

Here`s my code:

_____________________________________________________________________________________________

#include <msp430.h>
#include <driverlib.h>
#include "eusci_a_uart.h"

//Counting variables
volatile uint16_t i;
volatile uint16_t k;
volatile uint16_t h;

// The Bytes Getting sent to the sensor
const char byte0 = 0xFF;
const char byte1 = 0x01;
const char byte2 = 0x86;
const char byte37 = 0x00;
const char byte8 = 0x79;

volatile char rbyte0;

//Delay Function
void delay_ms(unsigned int ms)
{
    while (ms)
    {
        __delay_cycles(1000); //1000 for 1MHz and 16000 for 16MHz
        ms--;
    }
}

void main(void) {
     // Stop watch dog timer
    WDT_A_hold(WDT_A_BASE);
    
    //variables for the receiving function
    volatile char currData;
    volatile uint16_t RecCount = 0;
    volatile char ReccData[9];
    volatile char oldData = 0x00;
    UCA0CTLW0 |= UCSWRST;
    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN7,
    GPIO_PRIMARY_MODULE_FUNCTION);
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN6,
    GPIO_PRIMARY_MODULE_FUNCTION);
    //activating the clock
    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN6,
    GPIO_SECONDARY_MODULE_FUNCTION);
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN7,
    GPIO_SECONDARY_MODULE_FUNCTION);
    PMM_unlockLPM5();

    EUSCI_A_UART_initParam eUSCI_initParam = {
                                              EUSCI_A_UART_CLOCKSOURCE_SMCLK, // selectClockSource
                                              6, // clockPrescalar UCBRx
                                              13,    // firstModReg UCBRFx
                                              34, // secondModReg UCBRSx
                                              EUSCI_A_UART_EVEN_PARITY, EUSCI_A_UART_LSB_FIRST,
                                              EUSCI_A_UART_ONE_STOP_BIT,EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE,
                                              EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION
                                          };
    
    EUSCI_A_UART_init(EUSCI_A0_BASE, &eUSCI_initParam);
    EUSCI_A_UART_enable(EUSCI_A0_BASE);
    EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE,
            EUSCI_A_UART_RECEIVE_INTERRUPT);

    while(1)
    {
        //Sending the Request to send the CO2 data to the sensor
                EUSCI_A_UART_transmitData(EUSCI_A0_BASE, byte0);
                EUSCI_A_UART_transmitData(EUSCI_A0_BASE, byte1);
                EUSCI_A_UART_transmitData(EUSCI_A0_BASE, byte2);
                for(k = 0; k<5;k++){
                    EUSCI_A_UART_transmitData(EUSCI_A0_BASE, byte37); // byte 3 to 7 are empty
                }
                EUSCI_A_UART_transmitData(EUSCI_A0_BASE, byte8);
                //Receiving the data (9 bytes) from the sensor
                while (RecCount <= 8)
                {
                    currData = OFS_UCAxRXBUF_L;
                    if (currData != oldData)
                    {
                        ReccData[RecCount] = currData;
                        oldData = currData;
                    }
                    RecCount++;
                }
                RecCount=0;
                delay_ms(15);
    }
}

_______________________________________________________________________________________________________________

The part in blue shows my problem: Every time there is a new value in the Buffer, it should be added to the ReccData[] array. However, it is empty. I also trid

Could somebody tell me how to solve this or at least provide me with a hint? Thank you greatly in Advance! (I am also terribly sorry for the low level of the question, but I have searched the web and multiple manuals.)

Kind regards,

Julius.

  • To a first approximation, it looks like you are not giving things enough time. Your computer is much faster than the UART, so while you should be able to send two bytes like this, I would think that the second one gets clobbered. (Transmit data is not blocking). Same thing for the receive. It is much better to use interrupts:

    http://www.simplyembedded.org/tutorials/msp430-uart/

  • The RXBUF always has "something" in it, so you can't look there to see if an Rx byte arrived. You need to check UCA0IFG:UCRXIFG instead.

    I suggest:

    1) Remove this line:

     EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);

    You don't use the interrupt, and enabling it will cause the Driverlib to do the wrong thing.

    2) Replace:

    >                     currData = OFS_UCAxRXBUF_L;

    with

    >                     currData = EUSCI_A_UART_receiveData(EUSCI_A0_BASE);

    That function will do the interlock for you by checking UCRXIFG.

**Attention** This is a public forum