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
}
}
}