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.

TM4C123GH UART Communication Problem

I am trying to communicate with a sensor via UART (UART1_BASE) while also communicating with a terminal (UART0_BASE). I have attached the communication portion of my program and it is currently set to only one UART at a time. When I select UART0 I have no problem transmitting all of the strings to the terminal, however I only get a set amount (with no delays I get 5 writes) when I use UART1 (Seen on oscilloscope). I change UART by switching commented portions of code and replace UARTX with correct number.

Please help!

/*
 * pH_Control.c
 *
 *  Created on: May 29, 2014
 *      Author: Jordan
 */

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "Setup.h" 	/*  Includes strings to be sent to stamp
					 *  Commands include: set_(4,7,10), reset,
					 *  info, led_(on,off)
					 */


// Commands:
void UART_write (uint32_t ui32Base);
void init_TM4C (void);

// Variables:
char pH_out[20];	// char array used to hold outgoing pH data


int main(void)
{
	//Initialize Microcontroller
	init_TM4C();

	//Initialize Port to write to sensor

	ROM_UARTCharPutNonBlocking(UART1_BASE, '5');


	while(1)
	{
		//
		// Blink the LED to show a character transfer is occurring.
		//
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

		//
		// Delay for 1 millisecond.  Each SysCtlDelay is about 3 clocks.
		//
		SysCtlDelay(SysCtlClockGet() / (1 * 3));

		//
		// Turn off the LED
		//
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
	}
}


void init_TM4C (void)
{
	//
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPUEnable();
    ROM_FPULazyStackingEnable();

    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Enable the GPIO pins for the LED (PF2).
    //
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);

    //
    // Enable the peripherals used by this example.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

    //
    // Enable processor interrupts.
    //
    ROM_IntMasterEnable();

    //
    // Set GPIO A0 and A1 as UART pins.
    //
    GPIOPinConfigure(GPIO_PC4_U1RX);
    GPIOPinConfigure(GPIO_PC5_U1TX);
    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    //
    // Configure the UART for 115,200, 8-N-1 operation.
    //
    ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 115200,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                             UART_CONFIG_PAR_NONE));

    //
    // Enable the UART interrupt.
    //
    ROM_IntEnable(INT_UART1);
    ROM_UARTIntEnable(UART1_BASE, UART_INT_RX | UART_INT_RT);
}

// Write relevant string to given base
void UART_write (uint32_t ui32Base)
{
//	init_base1();
	b = sizeof(pH_out);
	for (a = 0; a < b; a++)
	{
		ROM_UARTCharPutNonBlocking(ui32Base, pH_out[a]);

		//
		// Blink the LED to show a character transfer is occuring.
		//
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

		//
		// Delay for 1 millisecond.  Each SysCtlDelay is about 3 clocks.
		//
		SysCtlDelay(SysCtlClockGet() / (1000 * 3));

		//
		// Turn off the LED
		//
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
	}
	SysCtlDelay(SysCtlClockGet() / (1));
}

/*
* Setup.h
*
* Created on: May 27, 2014
* Author: Jordan
*/

#ifndef SETUP_H_
#define SETUP_H_

//*********************************************************************************************//
// Internal Strings:
//*********************************************************************************************//


//*********************************************************************************************//
// Stamp Commands:
//*********************************************************************************************//

//Universal Commands:
char reset[20] = "X\r"; // Command to reset the device to factoy default mode (R)
char read_cont[20] = "c\r"; // Command to put stamp in continuous reading mode (C)
char cont_esc[20] = "e\r"; // Command to take stamp out of continuous mode (E)
char read_one[20] = "R\r"; // Command to put stamp in single-read mode (S)
char info[20] = "I\r"; // Command to query the information (Q)
char led_off[20] = "L0\r"; // Command to turn leds OFF (0)
char led_on[20] = "L1\r"; // Command to turn leds ON (L)

//pH Commands:
char set_4[20] = "f\r"; // Command to calibrate to a pH of 4.00 (1)
char set_7[20] = "s\r"; // Command to calibrate to a pH of 7.00 (2)
char set_10[20] = "t\r"; // Command to calibrate to a pH of 10.00 (3)


#endif /* SETUP_H_ */

  • Hello Jordan,

    So when UART-1 stops, the code must be hung in some loop or waiting for some status? Can you check the same with the debugger?

    Also the code does not seem complete as it is not clear where UART_write is being called from and how the Interrupt is being used as well.

    Regards

    Amit

  • Hello Amit,

    UART_write is a function I call in my full program, but to minimize the number of variables that could be affecting my code I call the ROM_...Put... function directly. I am also not using the interrupt; my thinking being that I am solely trying to output the full string then add additional code later. As for the loop status, I think there may be an internal timer that is stopping the code from outputting all of the strings. When I change the delays between the individual strings I still only see the same length of data on the oscilloscope.

    Cheers,

    Jordan

  • Hello Jordan,

    That could be possible. The code may be in a while or an Interrupt Loop (from the timer which is not there in the code) and hence not progressing for UART_write

    If you can send the entire project (CCS) then I may be able to help as there are no input devices to the TIVA device.

    Regards

    Amit

  • Hello Amit, I have attached a zip file with my current full project. The code is very different from the code I posted earlier. This program works perfectly when the PC acts as the peripheral also (ie, only use UART0 and type in expected results). When I try to write to UART1 using my WRITE command or the provided ROM_..._PUT command I don't see anything on the oscilloscope. Any suggestions on how to proceed would be greatly appreciated!

    Multiple_UART.zip
  • Hello Jordan,

    I will try it on my setup. For clarification

    1. The code send data to PC only on UART-0 and not on UART-1?

    2. OR when you use UART-0 for PC and UART-1 for write command and nothing comes on the scope for UART1TX pins?

    Regards

    Amit

  • Hello Amit, 

    I am using UART0 to communicate with the PC and UART1 to communicate with the pH sensor. To test the code I simply used UART0 to write similate writing to/reading from the sensor. When I test the UART1 interface I should see changes on the UART1 transmission pin, but it just goes high and stays high.

    Cheers,

    Jordan

  • In case it isn't clear, I have attached a "program flow" with an example terminal conversation that shows the error is specific to UART1. I have also attached a sample output from the previous code we were discussing. Although the entire string is cutoff prematurely and isn't the correct baud-rate, this is what the transmission gate should be sending. (In case it helps, the first two groups are "e\r", the next two are "L1\R", then "L0\R", then L1\R" and then it stops prematurely).

    Thank you again for helping me,

    Jordan

  • Hello Jordan,

    Thanks for the added info. To make my understanding clear, in the case of the code the toggle itself is missing and the line stays high?

    Regards

    Amit

  • Hello Amit,

    If you are referring to BTN1 then yes, I still need to add the interrupt code for sw1 (left button) which will eventually allow the user to bypass initital calibration (the calibrate function from the first code I posted).

    Cheers,

    Jordan

  • By the way, I found quite a lot of information on UART1 here: (http://users.ece.utexas.edu/~valvano/Volume1/E-Book/C11_SerialInterface.htm). However I can't quite see how to use it in my program, maybe it can help you see what I am doing wrong.

    Cheers,

    Jordan

  • Hello Jordan,

    In the init_TM4C function there is no configuration of UART1 module. I found only the following for UART-9

        ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 38400,
                                (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                 UART_CONFIG_PAR_NONE));

    The IO Configuration and Interrupt configuration is done, but not UART module configuration.

    Regards,

    Amit

  • Hello Amit,

    That did it! Thank you for helping me out, I can't believe I forgot to put that in. Again, I really appreciate your help.

    Cheers,

    Jordan