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.
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
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)