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: Need Help Verifying C Code using UART for MSP430FR5994 Implementation

Part Number: MSP430FR5994
Other Parts Discussed in Thread: MSP430FR2311

Tool/software:

I'm a student currently working on a project involving the MSP430FR5994 microcontroller. My task is to implement UART communication to send data from the microcontroller to my PC. To verify my C code before implementation.

The reception works perfectly when I send characters, but I encounter issues when sending integers. Surprisingly, I don't receive anything at all, and even the LED that indicates data transmission doesn't toggle.

Here's the C code I'm using:

#include <msp430.h>
#include <stdint.h>

// Déclarations des fonctions
void initClock(void);
void initUART(void);
void initPort(void);
void sendBuffer(void);

int main(void) {
// Stop watchdog timer
WDTCTL = WDTPW + WDTHOLD;

// Initialisation des périphériques
initClock();
initPort();
initUART();

while (1) {
// Send a predefined buffer via UART
sendBuffer();
P1OUT ^= BIT0; // Toggle LED to indicate sending data
__delay_cycles(1000000); // Add a delay to avoid too fast a loop
}

return 0;
}
// Initialisation de l'horloge
void initClock(void) {
CSCTL0_H = CSKEY >> 8; // Déverrouillage du module CS
CSCTL1 = DCOFSEL_6; // Sélection de DCO à 8 MHz (selon la documentation MSP430)
CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK; // Configuration des sources d'horloge
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Réglage des diviseurs d'horloge
CSCTL0_H = 0; // Verrouiller le module CS
}

// Initialisation de l'UART
void initUART(void) {
UCA0CTLW0 = UCSWRST; // Mise à la réinitialisation du module UART
P2SEL0 &= ~(BIT0 | BIT1); // Configuration des broches P2.0 et P2.1
P2SEL1 |= (BIT0 | BIT1);
UCA0CTLW0 |= UCSSEL__SMCLK; // Sélection de SMCLK comme source d'horloge UART
UCA0BRW = 52; // Configuration du débit en bauds à 9600 bauds
UCA0MCTLW = UCOS16 | UCBRF_1 | 0x49; // Configuration des paramètres de modulation
UCA0CTLW0 &= ~UCSWRST; // Sortie de la réinitialisation
UCA0IE |= UCRXIE; // Activation des interruptions de réception UART
}

// Initialisation des ports GPIO
void initPort(void) {
P1OUT = 0x00;
P1DIR = 0xFF;
P1OUT |= BIT0;

P2OUT = 0x00;
P2DIR = 0xFF;

P3OUT = 0x00;
P3DIR = 0xFF;

P4OUT = 0x00;
P4DIR = 0xFF;

P5OUT = 0x00;
P5DIR = 0xFF;

P6OUT = 0x00;
P6DIR = 0xFF;

P7OUT = 0x00;
P7DIR = 0xFF;

P8OUT = 0x04;
P8DIR = 0xFF;

P9OUT = 0x00;
P9DIR = 0xFF;

PAOUT = 0x00;
PADIR = 0xFF;

PBOUT = 0x00;
PBDIR = 0xFF;

PCOUT = 0x00;
PCDIR = 0xFF;

PDOUT = 0x00;
PDDIR = 0xFF;

PEOUT = 0x00;
PEDIR = 0xFF;

PJOUT = 0x00;
PJDIR = 0xFF;

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


// Function to send a predefined buffer via UART
void sendBuffer(void) {
// Data buffer to send
uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05};

// Send buffer via UART
int i;
for (i = 0; i < sizeof(buffer); i++) {
// Wait until transmission register is ready
while (!(UCA0IFG & UCTXIFG));

// Send buffer element
UCA0TXBUF = buffer[i];

// Wait until transmission is complete
while (UCA0STATW & UCBUSY);
}
}

I would appreciate any insights into what might be causing this issue and how I can rectify it. Additionally, if you have any suggestions or improvements for my C code, I'd be grateful for your input.

Thank you all for your time and assistance!

  • Are you saying that if you change

    uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05};

    to

    uint8_t buffer[] = {'h', 'e', 'l', 'l', 'o'};

    it works?

    You don't need both busy waits, the first: while (!(UCA0IFG & UCTXIFG)); should suffice.

  • that does not work too 

  • So what code "works perfectly when I send characters" ? Start from there. Also look into the interrupt based uart echo examples.

  • I used another code for sending characters. which convert the integer to character and send them one by one.

  • I assume you mean that you used something like sprintf() to create an ascii string of your integers. But now you want to send the integers directly.

    Take that original program. Instead converting, just send the integers directly. Does that work?

    If so, now just make it loop for each character in an array.

  • For the code pasted here:

    Did you remove the

    while (UCA0STATW & UCBUSY);

    busy wait?

  • Your original code works fine for me. I had to make a few changes in pins and clocks for the MSP430FR2311 I have available.

    #include <msp430.h>
    #include <stdint.h>
    
    void Software_Trim();            // Software Trim to get the best DCOFTRIM value
    #define MCLK_FREQ_MHZ 8                     // MCLK = 8MHz
    
    // Déclarations des fonctions
    
    void initUART(void);
    void initPort(void);
    void sendBuffer(void);
    
    int main(void)
    {
    // Stop watchdog timer
        WDTCTL = WDTPW + WDTHOLD;
    
    // Initialisation des périphériques
        initPort();
        PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
                              // to activate 1previously configured port settings
    
        __bis_SR_register(SCG0);                 // disable FLL
        CSCTL3 |= SELREF__REFOCLK;               // Set REFO as FLL reference source
        CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3; // DCOFTRIM=3, DCO Range = 8MHz
        CSCTL2 = FLLD_0 + 243;                  // DCODIV = 8MHz
        __delay_cycles(3);
        __bic_SR_register(SCG0);                // enable FLL
        Software_Trim();             // Software Trim to get the best DCOFTRIM value
    
        CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
                                                   // default DCODIV as MCLK and SMCLK source
        initUART();
    
        while (1)
        {
    // Send a predefined buffer via UART
            sendBuffer();
    
    
    
            P1OUT ^= BIT0; // Toggle LED to indicate sending data
            __delay_cycles(1000000); // Add a delay to avoid too fast a loop
        }
    
    }
    // Initialisation de l'horloge
    void Software_Trim()
    {
        unsigned int oldDcoTap = 0xffff;
        unsigned int newDcoTap = 0xffff;
        unsigned int newDcoDelta = 0xffff;
        unsigned int bestDcoDelta = 0xffff;
        unsigned int csCtl0Copy = 0;
        unsigned int csCtl1Copy = 0;
        unsigned int csCtl0Read = 0;
        unsigned int csCtl1Read = 0;
        unsigned int dcoFreqTrim = 3;
        unsigned char endLoop = 0;
    
        do
        {
            CSCTL0 = 0x100;                         // DCO Tap = 256
            do
            {
                CSCTL7 &= ~DCOFFG;                  // Clear DCO fault flag
            }
            while (CSCTL7 & DCOFFG);               // Test DCO fault flag
    
            __delay_cycles((unsigned int) 3000 * MCLK_FREQ_MHZ); // Wait FLL lock status (FLLUNLOCK) to be stable
                                                                 // Suggest to wait 24 cycles of divided FLL reference clock
            while ((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0))
                ;
    
            csCtl0Read = CSCTL0;                   // Read CSCTL0
            csCtl1Read = CSCTL1;                   // Read CSCTL1
    
            oldDcoTap = newDcoTap;               // Record DCOTAP value of last time
            newDcoTap = csCtl0Read & 0x01ff;       // Get DCOTAP value of this time
            dcoFreqTrim = (csCtl1Read & 0x0070) >> 4;       // Get DCOFTRIM value
    
            if (newDcoTap < 256)                    // DCOTAP < 256
            {
                newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256
                if ((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
                    endLoop = 1;                   // Stop while loop
                else
                {
                    dcoFreqTrim--;
                    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim << 4);
                }
            }
            else                                   // DCOTAP >= 256
            {
                newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256
                if (oldDcoTap < 256)                // DCOTAP cross 256
                    endLoop = 1;                   // Stop while loop
                else
                {
                    dcoFreqTrim++;
                    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim << 4);
                }
            }
    
            if (newDcoDelta < bestDcoDelta)         // Record DCOTAP closest to 256
            {
                csCtl0Copy = csCtl0Read;
                csCtl1Copy = csCtl1Read;
                bestDcoDelta = newDcoDelta;
            }
    
        }
        while (endLoop == 0);                      // Poll until endLoop == 1
    
        CSCTL0 = csCtl0Copy;                       // Reload locked DCOTAP
        CSCTL1 = csCtl1Copy;                       // Reload locked DCOFTRIM
        while (CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1))
            ; // Poll until FLL is locked
    }
    
    // Initialisation de l'UART
    void initUART(void)
    {
        // Configure UART pins
        P1SEL0 |= BIT6 | BIT7;                  // set 2-UART pin as second function
    
        UCA0CTLW0 = UCSWRST; // Mise à la réinitialisation du module UART
        UCA0CTLW0 |= UCSSEL__SMCLK; // Sélection de SMCLK comme source d'horloge UART
        UCA0BRW = 52; // Configuration du débit en bauds à 9600 bauds
        UCA0MCTLW = UCOS16 | UCBRF_1 | 0x49; // Configuration des paramètres de modulation
        UCA0CTLW0 &= ~UCSWRST; // Sortie de la réinitialisation
        UCA0IE |= UCRXIE; // Activation des interruptions de réception UART
    }
    
    // Initialisation des ports GPIO
    void initPort(void)
    {
        P1OUT = 0x00;
        P1DIR = 0xFF;
        P1OUT |= BIT0;
    
        P2OUT = 0x00;
        P2DIR = 0xFF;
    
        PAOUT = 0x00;
        PADIR = 0xFF;
    
        PJOUT = 0x00;
        PJDIR = 0xFF;
    
        P2SEL0 &= ~(BIT0 | BIT1);
        P2SEL1 |= (BIT0 | BIT1);
    }
    
    // Function to send a predefined buffer via UART
    void sendBuffer(void)
    {
    // Data buffer to send
        uint8_t buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
    
    // Send buffer via UART
        int i;
    
        for (i = 0; i < (sizeof(buffer)); i++)
        {
    // Wait until transmission register is ready
            while (!(UCA0IFG & UCTXIFG))
                ;
    
    // Send buffer element
            UCA0TXBUF = buffer[i];
    
    // Wait until transmission is complete
            while (UCA0STATW & UCBUSY)
            ;
        }
    }

  • Usually when this happens - especially if the LED stops toggling - it means that you got an interrupt that sends you to an endless while stub I see that you are activating the UART receive interrupt. If you receive any characters without a handler this could happen.

    Also comment out your sendBuffer() function to see if the delay loop + LED works. If not you have clock or other problems.

  • I have finally resolve it.In fact the problem was with the UART configuration (The MSB should be configured) and the function sizeof(Buffer) wasn't returning something precise to The IDE so the For Loop was not  treated  . Thank you for your help 

  • I looked at the sizeof() thing, but since sizeof(uint8_t) is 1, it seemed OK.

**Attention** This is a public forum