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.

TM4C123GH6PM: UART communication between devices not functional

Part Number: TM4C123GH6PM

I'm trying to set up a UART communication that reads a string from a serial terminal and sends it to one microcontroller. That microcontroller is connected to a second and sends the string from the terminal to it. Below I have the code and the issue I am having is that the second microcontroller does not seem to be receiving the string. I know that the communication is working becuase, if I test by send a single character using UART1_OutChar() in the MCU1 project file and UART_InChar() in the MCU2 project file, it is received by the second MCU. But when it comes to sending a string of characters, it appears to get "stuck" (see code for debug notes).

/***************Project file for MCU1*****************************/
// UART Connection between MCU1 and MCU2
#include "UART_C.h"

#define GPIO_PORTC_AFSEL_R      (*((volatile unsigned long *)0x40006420))
#define GPIO_PORTC_DEN_R        (*((volatile unsigned long *)0x4000651C))
#define GPIO_PORTC_AMSEL_R      (*((volatile unsigned long *)0x40006528))
#define GPIO_PORTC_PCTL_R       (*((volatile unsigned long *)0x4000652C))
#define UART1_DR_R              (*((volatile unsigned long *)0x4000D000))
#define UART1_FR_R              (*((volatile unsigned long *)0x4000D018))
#define UART1_IBRD_R            (*((volatile unsigned long *)0x4000D024))
#define UART1_FBRD_R            (*((volatile unsigned long *)0x4000D028))
#define UART1_LCRH_R            (*((volatile unsigned long *)0x4000D02C))
#define UART1_CTL_R             (*((volatile unsigned long *)0x4000D030))
#define UART_FR_TXFF            0x00000020  // UART Transmit FIFO Full
#define UART_FR_RXFE            0x00000010  // UART Receive FIFO Empty
#define UART_LCRH_WLEN_8        0x00000060  // 8 bit word length
#define UART_LCRH_FEN           0x00000010  // UART Enable FIFOs
#define UART_CTL_UARTEN         0x00000001  // UART Enable
#define SYSCTL_RCGC1_R          (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R          (*((volatile unsigned long *)0x400FE108))
#define SYSCTL_RCGC1_UART1      0x00000002  // UART1 Clock Gating Control
#define SYSCTL_RCGC2_GPIOC      0x00000004  // port C Clock Gating Control

//------------UART_Init------------
// Initialize the UART for 115,200 baud rate (assuming 80 MHz UART clock),
// 8 bit word length, no parity bits, one stop bit, FIFOs enabled
// Input: none
// Output: none
void UART1_Init(void){
  SYSCTL_RCGC1_R |= SYSCTL_RCGC1_UART1; // activate UART1
  SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOC; // activate port C
  UART1_CTL_R &= ~UART_CTL_UARTEN;      // disable UART
	// Set Baud rate
																				//           (Bus clock  /const*  Baud rate)
  UART1_IBRD_R = 27;                    // IBRD = int(50,000,000 / (16 * 115,200)) = int(27.12673)
  UART1_FBRD_R = 8;                     // (^-bit fraction) FBRD = int(0.12673 * 64) = 8
                                        // 8 bit word length (no parity bits, one stop bit, FIFOs)
																				// Creating binary fraction by multiplying by 64
  UART1_LCRH_R = (UART_LCRH_WLEN_8|UART_LCRH_FEN);
  UART1_CTL_R |= UART_CTL_UARTEN;       // enable UART
  GPIO_PORTC_AFSEL_R |= 0x30;           // enable alt funct on PC5-4
  GPIO_PORTC_DEN_R |= 0x30;             // enable digital I/O on PC5-4
                                        // configure PC5-4 as UART
  GPIO_PORTC_PCTL_R = (GPIO_PORTC_PCTL_R&0xFF00FFFF)+0x00220000; // Sets PC to be UART
  GPIO_PORTC_AMSEL_R &= ~0x30;          // disable analog functionality on PC
}

//------------UART_InChar------------
// Wait for new serial port input
// Input: none
// Output: ASCII code for key typed
unsigned char UART1_InChar(void){
	// Where we read 8-bit data, logic says to check flag (RxFE)
  while((UART1_FR_R&UART_FR_RXFE) != 0); // While flag is = 1, RxFE empty. Repeat loop until not empty
																				 // Note UART_FR_RXFE = 0x0010
  return((unsigned char)(UART1_DR_R&0xFF)); // Look at data reg and read it and return
}
//------------UART_OutChar------------
// Output 8-bit to serial port
// Input: letter is an 8-bit ASCII character to be transferred
// Output: none
// busy wait sync and outputs to serial port
void UART1_OutChar(unsigned char data){
  while((UART1_FR_R&UART_FR_TXFF) != 0); // 1 means FIFO is busy outputting
  UART1_DR_R = data; // Write next data to device
}


//------------UART_OutString------------
// Output String (NULL termination)
// Input: pointer to a NULL-terminated string to be transferred
// Output: none
void UART1_OutString(char *pt){
  while(*pt){
    UART1_OutChar(*pt);
    pt++;
  }
}
//------------UART_InString------------
// Accepts ASCII characters from the serial port
//    and adds them to a string until <enter> is typed
//    or until max length of the string is reached.
// It echoes each character as it is inputted.
// If a backspace is inputted, the string is modified
//    and the backspace is echoed
// terminates the string with a null character
// uses busy-waiting synchronization on RDRF
// Input: pointer to empty buffer, size of buffer
// Output: Null terminated string
// -- Modified by Agustinus Darmawan + Mingjie Qiu --
void UART1_InString(char *bufPt, unsigned short max) {
int length=0;
char character;
  character = UART1_InChar();
  while(character != CR){
    if(character == BS){
      if(length){
        bufPt--;
        length--;
        UART1_OutChar(BS);
      }
    }
    else if(length < max){
      *bufPt = character;
      bufPt++;
      length++;
      UART1_OutChar(character);
    }
    character = UART1_InChar();
  }
  *bufPt = 0;
}

// UART Connection between MCU1 and computer serial terminal
#include "UART.h"

#define GPIO_PORTA_AFSEL_R      (*((volatile unsigned long *)0x40004420))
#define GPIO_PORTA_DEN_R        (*((volatile unsigned long *)0x4000451C))
#define GPIO_PORTA_AMSEL_R      (*((volatile unsigned long *)0x40004528))
#define GPIO_PORTA_PCTL_R       (*((volatile unsigned long *)0x4000452C))
#define UART0_DR_R              (*((volatile unsigned long *)0x4000C000))
#define UART0_FR_R              (*((volatile unsigned long *)0x4000C018))
#define UART0_IBRD_R            (*((volatile unsigned long *)0x4000C024))
#define UART0_FBRD_R            (*((volatile unsigned long *)0x4000C028))
#define UART0_LCRH_R            (*((volatile unsigned long *)0x4000C02C))
#define UART0_CTL_R             (*((volatile unsigned long *)0x4000C030))
#define UART_FR_TXFF            0x00000020  // UART Transmit FIFO Full
#define UART_FR_RXFE            0x00000010  // UART Receive FIFO Empty
#define UART_LCRH_WLEN_8        0x00000060  // 8 bit word length
#define UART_LCRH_FEN           0x00000010  // UART Enable FIFOs
#define UART_CTL_UARTEN         0x00000001  // UART Enable
#define SYSCTL_RCGC1_R          (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R          (*((volatile unsigned long *)0x400FE108))
#define SYSCTL_RCGC1_UART0      0x00000001  // UART0 Clock Gating Control
#define SYSCTL_RCGC2_GPIOA      0x00000001  // port A Clock Gating Control

//------------UART_Init------------
// Initialize the UART for 115,200 baud rate (assuming 80 MHz UART clock),
// 8 bit word length, no parity bits, one stop bit, FIFOs enabled
// Input: none
// Output: none
void UART_Init(void){

  SYSCTL_RCGC1_R |= SYSCTL_RCGC1_UART0; // activate UART0
  SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOA; // activate port A (which is connected to on-board Tx & Rx)
  UART0_CTL_R &= ~UART_CTL_UARTEN;      // disable UART
	// Set Baud rate
																				//           (Bus clock  /const*  Baud rate)
  UART0_IBRD_R = 27;                    // IBRD = int(50,000,000 / (16 * 115,200)) = int(27.12673)
  UART0_FBRD_R = 8;                    // (^-bit fraction) FBRD = int(0.12673 * 64) = 8
                                        // 8 bit word length (no parity bits, one stop bit, FIFOs)
																				// Creating binary fraction by multiplying by 64
  UART0_LCRH_R = (UART_LCRH_WLEN_8|UART_LCRH_FEN);
  UART0_CTL_R |= UART_CTL_UARTEN;       // enable UART
  GPIO_PORTA_AFSEL_R |= 0x03;           // enable alt funct on PA1-0
  GPIO_PORTA_DEN_R |= 0x03;             // enable digital I/O on PA1-0
                                        // configure PA1-0 as UART
  GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFFF00)+0x00000011; // Sets PA to be UART
  GPIO_PORTA_AMSEL_R &= ~0x03;          // disable analog functionality on PA
}
//------------UART_InChar------------
// Wait for new serial port input
// Input: none
// Output: ASCII code for key typed
unsigned char UART_InChar(void){
	// Where we read 8-bit data, logic says to check flag (RxFE)
  while((UART0_FR_R&UART_FR_RXFE) != 0); // While flag is = 1, RxFE empty. Repeat loop until not empty
																				 // Note UART_FR_RXFE = 0x0010
  return((unsigned char)(UART0_DR_R&0xFF)); // Look at data reg and read it and return
}
//------------UART_OutChar------------
// Output 8-bit to serial port
// Input: letter is an 8-bit ASCII character to be transferred
// Output: none
// busy wait sync and outputs to serial port
void UART_OutChar(unsigned char data){
  while((UART0_FR_R&UART_FR_TXFF) != 0); // 1 means FIFO is busy outputting
  UART0_DR_R = data; // Write next data to device
}
//------------UART_OutString------------
// Output String (NULL termination)
// Input: pointer to a NULL-terminated string to be transferred
// Output: none
void UART_OutString(char *pt){
  while(*pt){
    UART_OutChar(*pt);
    pt++;
  }
}
//------------UART_InString------------
// Accepts ASCII characters from the serial port
//    and adds them to a string until <enter> is typed
//    or until max length of the string is reached.
// It echoes each character as it is inputted.
// If a backspace is inputted, the string is modified
//    and the backspace is echoed
// terminates the string with a null character
// uses busy-waiting synchronization on RDRF
// Input: pointer to empty buffer, size of buffer
// Output: Null terminated string
// -- Modified by Agustinus Darmawan + Mingjie Qiu --
void UART_InString(char *bufPt, unsigned short max) {
int length=0;
char character;
  character = UART_InChar();
  while(character != CR){
    if(character == BS){
      if(length){
        bufPt--;
        length--;
        UART_OutChar(BS);
      }
    }
    else if(length < max){
      *bufPt = character;
      bufPt++;
      length++;
      UART_OutChar(character);
    }
    character = UART_InChar();
  }
  *bufPt = 0;
}

// main()
#include "tm4c123gh6pm.h"
#include "PLL.h"
#include "UART.h"
#include "UART_C.h"
#include "PortF.h"

void DisableInterrupts(void); // Disable interrupts
void EnableInterrupts(void);  // Enable interrupts
void WaitForInterrupt(void);

char data[15];
unsigned char i;

// MCU 1
int main(void){
	DisableInterrupts();	
  PLL_Init();										// 50 MHz
  UART_Init();              		// initialize UARTs
	UART1_Init();
	
	// get character from terminal
  while(1){
	  UART_OutString("Enter a frequency in the form of fxxx: ");OutCRLF(); // Debug to test 
	  UART_InString(data, 15); OutCRLF(); // input from the terminal
		UART1_OutString(data); // send to MCU 2
		Delay();Delay();Delay();
 }
}

/***************Project file for MCU2*****************************/
// UART Connection between MCU2 and MCU 1
#include "UART.h"

#define GPIO_PORTC_AFSEL_R      (*((volatile unsigned long *)0x40006420))
#define GPIO_PORTC_DEN_R        (*((volatile unsigned long *)0x4000651C))
#define GPIO_PORTC_AMSEL_R      (*((volatile unsigned long *)0x40006528))
#define GPIO_PORTC_PCTL_R       (*((volatile unsigned long *)0x4000652C))
#define UART1_DR_R              (*((volatile unsigned long *)0x4000D000))
#define UART1_FR_R              (*((volatile unsigned long *)0x4000D018))
#define UART1_IBRD_R            (*((volatile unsigned long *)0x4000D024))
#define UART1_FBRD_R            (*((volatile unsigned long *)0x4000D028))
#define UART1_LCRH_R            (*((volatile unsigned long *)0x4000D02C))
#define UART1_CTL_R             (*((volatile unsigned long *)0x4000D030))
#define UART_FR_TXFF            0x00000020  // UART Transmit FIFO Full
#define UART_FR_RXFE            0x00000010  // UART Receive FIFO Empty
#define UART_LCRH_WLEN_8        0x00000060  // 8 bit word length
#define UART_LCRH_FEN           0x00000010  // UART Enable FIFOs
#define UART_CTL_UARTEN         0x00000001  // UART Enable
#define SYSCTL_RCGC1_R          (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R          (*((volatile unsigned long *)0x400FE108))
#define SYSCTL_RCGC1_UART1      0x00000002  // UART1 Clock Gating Control
#define SYSCTL_RCGC2_GPIOC      0x00000004  // port C Clock Gating Control

//------------UART_Init------------
// Initialize the UART for 115,200 baud rate (assuming 80 MHz UART clock),
// 8 bit word length, no parity bits, one stop bit, FIFOs enabled
// Input: none
// Output: none
void UART_Init(void){
  SYSCTL_RCGC1_R |= SYSCTL_RCGC1_UART1; // activate UART1
  SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOC; // activate port C
  UART1_CTL_R &= ~UART_CTL_UARTEN;      // disable UART
	// Set Baud rate
																				//           (Bus clock  /const*  Baud rate)
  UART1_IBRD_R = 27;                    // IBRD = int(50,000,000 / (16 * 115,200)) = int(27.12673)
  UART1_FBRD_R = 8;                     // (^-bit fraction) FBRD = int(0.12673 * 64) = 8
                                        // 8 bit word length (no parity bits, one stop bit, FIFOs)
																				// Creating binary fraction by multiplying by 64
  UART1_LCRH_R = (UART_LCRH_WLEN_8|UART_LCRH_FEN);
  UART1_CTL_R |= UART_CTL_UARTEN;       // enable UART
  GPIO_PORTC_AFSEL_R |= 0x30;           // enable alt funct on PC5-4
  GPIO_PORTC_DEN_R |= 0x30;             // enable digital I/O on PC5-4
                                        // configure PC5-4 as UART
  GPIO_PORTC_PCTL_R = (GPIO_PORTC_PCTL_R&0xFF00FFFF)+0x00220000; // Sets PC to be UART
  GPIO_PORTC_AMSEL_R &= ~0x30;          // disable analog functionality on PC
}

//------------UART_InChar------------
// Wait for new serial port input
// Input: none
// Output: ASCII code for key typed
unsigned char UART_InChar(void){
	// Where we read 8-bit data, logic says to check flag (RxFE)
  while((UART1_FR_R&UART_FR_RXFE) != 0); // While flag is = 1, RxFE empty. Repeat loop until not empty
																				 // Note UART_FR_RXFE = 0x0010
  return((unsigned char)(UART1_DR_R&0xFF)); // Look at data reg and read it and return
}
//------------UART_NonBlockingInChar------------
// Get serial port input and return immediately
// Input: none
// Output: ASCII code for key typed or 0 if no character
unsigned char UART_NonBlockingInChar(void) {
	if((UART1_FR_R&UART_FR_RXFE) == 0) {
		return((unsigned char)(UART1_DR_R&0xFF));
	}
	else {
		return 0;
	}
}
//------------UART_OutChar------------
// Output 8-bit to serial port
// Input: letter is an 8-bit ASCII character to be transferred
// Output: none
// busy wait sync and outputs to serial port
void UART_OutChar(unsigned char data){
  while((UART1_FR_R&UART_FR_TXFF) != 0); // 1 means FIFO is busy outputting
  UART1_DR_R = data; // Write next data to device
}
//------------UART_OutString------------
// Output String (NULL termination)
// Input: pointer to a NULL-terminated string to be transferred
// Output: none
void UART_OutString(char *pt){
  while(*pt){
    UART_OutChar(*pt);
    pt++;
  }
}
//------------UART_InString------------
// Accepts ASCII characters from the serial port
//    and adds them to a string until <enter> is typed
//    or until max length of the string is reached.
// It echoes each character as it is inputted.
// If a backspace is inputted, the string is modified
//    and the backspace is echoed
// terminates the string with a null character
// uses busy-waiting synchronization on RDRF
// Input: pointer to empty buffer, size of buffer
// Output: Null terminated string
// -- Modified by Agustinus Darmawan + Mingjie Qiu --
void UART_InString(char *bufPt, unsigned short max) {
int length=0;
char character;
  character = UART_NonBlockingInChar();
  while(character != CR){
    if(character == BS){
      if(length){
        bufPt--;
        length--;
        //UART_OutChar(BS);
      }
    }
    else if(length < max){
      *bufPt = character;
      bufPt++;
      length++;
      //UART_OutChar(character);
    }
    character = UART_NonBlockingInChar();
  }
  *bufPt = 0;
}

// main()
#include "tm4c123gh6pm.h"
#include <stdio.h>
#include <string.h>
#include "PLL.h"
#include "UART.h"
#include "PortF.h"

//void EnableInterrupts(void);  // Enable interrupts
void DisableInterrupts(void); // Disable interrupts
void WaitForInterrupt(void);

char data2[15];
unsigned char i;
unsigned long note;

// MCU 2
int main(void){
	DisableInterrupts();					// doing a software trigger on the ADC read. Disable before  
	PLL_Init();										// 50 MHz
  UART_Init();              		// initialize UART
	PortF_Init();									// initialize Port F
	
	// default 
	GPIO_PORTF_DATA_R = 0x08; // debug
	
	// select frequency
  while(1){
		//i = UART_InChar();

		UART_InString(data2, 15); // input from MCU 1 THIS IS WHERE IT GETS STUCK. LED should change but remains green
		
		if (strcmp(data2, "l") == 0) {
			GPIO_PORTF_DATA_R ^= 0x02; // debug toggle
		}
		else if (strcmp(data2, "f0") == 0) {
			GPIO_PORTF_DATA_R = 0x0E; // turn all on
		}
		
		else if (strcmp(data2, "f262") == 0) {
			GPIO_PORTF_DATA_R = 0x02; // turn red
		}
		
		else {
			GPIO_PORTF_DATA_R = 0x00; // debugging purposes
		}
  }
}

  • Hi,

      Please refer to FAQ #4. Basically, we do not support DRM style of coding. DRM coding is very prone to mistake and is very hard to debug. The TivaWare library offers peripheral drivers that much ease your development.

    https://e2e.ti.com/support/microcontrollers/other/f/908/t/695568

     I will suggest you:

     - Look at the TivaWare UARTCharGetNonBlocking and compare with yours. You might want to check other functions too.

    int32_t
    UARTCharGetNonBlocking(uint32_t ui32Base)
    {
        //
        // Check the arguments.
        //
        ASSERT(_UARTBaseValid(ui32Base));
    
        //
        // See if there are any characters in the receive FIFO.
        //
        if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE))
        {
            //
            // Read and return the next character.
            //
            return(HWREG(ui32Base + UART_O_DR));
        }
        else
        {
            //
            // There are no characters, so return a failure.
            //
            return(-1);
        }
    }

     - use the scope to check if the MCU1 is sending data to the the MCU2. 

     - Put your MCU2 in a loopback mode. Can the MCU2 receive what it puts out itself?

     - Check if both MCU1 and MCU2 are configured with the same baud rate, stop bit(s) and parity.