Let’s learn to use Tiva C UART to interface with devices which uses the UART interface. Like HC-05 bluetooth module. Although if we are going to use the HC05 bluetooth module, we have to use different pins but we are going to focus only onboard usb connecter which is attached with UART0.

Tiva C TM4C123 launch pad comes with a USB connector which we were using for debugging and uploading the code. We can use that for UART communication. TM4C123GH6PM microcontroller comes with up to 8 UART and the Tiva C TM4C123 launchpad is using the UART0 attached to the USB Virtual COM. So, if we want to use the Virtual COM with the USB interface, we have to configure the UART0.

TM4C123GH6PM UART Baud-Rate Generation

Baud-Rate generation is one of the major step for smooth serial communication. According to TM4C123GH6PM Datasheet under the UART section it is described how to calculate the buadrate divisor which is 22-bit number and required to properly initialize the UART with required baud rate. The Baud-Rate Divisor is a 22-bit number that determines the bit period for UART communication, composed of a 16-bit integer and a 6-bit fractional part. The fractional part allows for the generation of all standard baud rates.

Registers

The 16-bit integer is set via the UART Integer Baud-Rate Divisor UARTIBRD register, and the 6-bit fraction via the UART Fractional Baud-Rate Divisor UARTFBRD register. Which we can access in the code with UARTx->IBRD and UARTx->FBRD.

Calculation

The baud-rate divisor (BRD) is calculated as BRD = BRDI + BRDF which is equal to UARTSysClk / (ClkDiv * Baud Rate).

The 6-bit fractional number (that is to be loaded into the DIVFRAC bit field in the UARTFBRD register)
can be calculated by taking the fractional part of the baud-rate divisor, multiplying it by 64, and
adding 0.5 to account for rounding errors: UARTFBRD[DIVFRAC] = integer(BRDF * 64 + 0.5)

#define SysClk 50000000  // System clock frequency (50 MHz)
#define BaudRate 9600    // Desired baud rate
 // Calculate the BRD and BRF values
uint32_t brd = SysClk / (16 * BaudRate);
uint32_t brf = (((SysClk * 8) / BaudRate) % 16) << 4;

	
Code language: Arduino (arduino)

Board Clock

To calculate your board system clock, we can make use of the SystemCoreClock variable available in the ARM Cortex-M series microcontrollers. We can load that variable and in the debug mode check the value in it. We can use this method to find out clock source for any ARM Cortex-M series microcontroller. In the debug mode in Keil uVision you can copy the value available in that variable in the debug mode.

Keil debug mode to find SystemCoreClock

After that you can copy that sysClk variable value and paste it in the calculator and it will show you the clock which in my case is 50MHz

SystemCoreClock converting hex to decimal

TM4C123 UART Example Code

Here is the complete example code to transmit and receive on the UART0 of the TM4C123 microcontroller.

#include "TM4C123.h"

#define UART0_BAUDRATE 115200

void delay(uint32_t count) {
    while (count--) {
        // Delay loop
    }
}

void UART0_Init(void) {
   // as part of Lab 11, modify this program to use UART0 instead of UART1
//                 switching from PC5,PC4 to PA1,PA0
  SYSCTL->RCGC1 |= 0x00000001; // activate UART0
  SYSCTL->RCGC2 |= 0x00000001; // activate port A
  UART0->CTL &= ~0x00000001;      // disable UART
  UART0->IBRD= 27;                    // IBRD = int(80,000,000 / (16 * 115200)) = int(43.402778)
  UART0->FBRD= 8;                    // FBRD = round(0.402778 * 64) = 26
                                        // 8 bit word length (no parity bits, one stop bit, FIFOs)
  UART0->LCRH = 0x00000070;
  UART0->CTL |= 0x00000301;       // enable UART
  GPIOA->AFSEL |= 0x03;           // enable alt funct on PA1,PA0
  GPIOA->DEN |= 0x03;             // enable digital I/O on PA1,PA0
  // configure PA1,PA0 as UART0
  GPIOA->PCTL = (GPIOA->PCTL&0xFFFFFF00)+0x00000011;
  GPIOA->AMSEL &= ~0x03;          // disable analog functionality on PA1,PA0
}

void UART0_SendChar(char data) {
    // Wait until the transmit FIFO is not full
    while ((UART0->FR & (1U << 5)) != 0);
  // Write a character to the transmit FIFO
    UART0->DR = data;	
}

void UART0_SendString(const char *string) {
    while (*string != '\0') {
        UART0_SendChar(*string);
        string++;
    }
}

int main(void) {
	int i=0;
	uint32_t sysClk = SystemCoreClock;
    // Initialize UART0
    UART0_Init();
	//for(i=0;i<5;i++)
	//delay(1000);
	
	
	UART0_SendChar('H');
	UART0_SendChar('e');
	UART0_SendChar('l');
	UART0_SendChar('l');
	UART0_SendChar('0');
	UART0_SendChar('\r');
	UART0_SendChar('\n');
	

    // Send a string
    UART0_SendString("Hello, Bare-Metal World!\n");

    while (1) {
        // Your main loop
    }
}

Code language: Arduino (arduino)

References:

By Abdul Rehman

My name is Abdul Rehman and I love to do Reasearch in Embedded Systems, Artificial Intelligence, Computer Vision and Engineering related fields. With 10+ years of experience in Research and Development field in Embedded systems I touched lot of technologies including Web development, and Mobile Application development. Now with the help of Social Presence, I like to share my knowledge and to document everything I learned and still learning.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.