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.
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.
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
**Attention** This is a public forum