es
es
Theory:
UART module Introduction:
•
A universal asynchronous receiver/transmitter (UART) module is used to interface the Tiva microcontroller with
your PC.
• •
The TM4C123 microcontrollers has 8 universal asynchronous receiver/transmitter (UART) modules. [pg 892]
Two devices communicating with asynchronous serial interfaces (UART) operate at the same frequency (baud
rate) but have two separate clocks.
• •
With a UART protocol, the clock signal is not included in the interface cable between devices. Two UART devices
can communicate with each other as long as the two clocks have frequencies within ±5% of each other.
Example Exercise:
Aim: Control on-board LED color by sending commands from PC using UART module.
Code:
#include "tm4c123gh6pm.h"
#include <stdint.h>
#include "PLL.h"
#include "string.h"
char string[20];
// standard ASCII symbols
#define CR 0x0D // carriage return (return to beginning of current line)
#define LF 0x0A //line feed or newline character '\n'
#define BS 0x08 //backspace
//------------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 |= 0x01; // activate UART0 Clock Gating Control
SYSCTL_RCGC2_R |= 0x01; // activate port A Clock Gating Control
UART0_CTL_R &= ~(0x01); // disable UART
UART0_IBRD_R = 43; // IBRD = int(80,000,000 / (16 * 115,200)) = int(43.40278)
UART0_FBRD_R = 26; // FBRD = int(0.40278 * 64 + 0.5) = 26
UART0_LCRH_R = 0x70; // 8 bit word length, no parity bits, one stop bit, Enable FIFOs
UART0_CTL_R |= 0x01; // 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
GPIO_PORTA_PCTL_R = 0x00000011; // configure PA1-0 as UART
GPIO_PORTA_AMSEL_R &= ~0x03; // disable analog functionality on PA }
//------------UART_OutChar------------
// Output 8-bit to serial port
// Input: letter is an 8-bit ASCII character to be transferred
// Output: none
void UART_OutChar(unsigned char data)
{ while((UART0_FR_R&0x20) != 0); // UART Transmit FIFO Full
UART0_DR_R = data;
}
//------------
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_InChar------------ // Wait for
new serial port input
// Input: none
// Output: ASCII code for key typed
unsigned char UART_InChar(void){
while((UART0_FR_R&0x10) != 0); // UART Receive FIFO Empty
return((unsigned char)(UART0_DR_R&0xFF));
}
//------------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;
}
void PortF_Init(void)
{
unsigned long delay;
SYSCTL_RCGC2_R |= 0x20;// clock for Port F delay =
SYSCTL_RCGC2_R;// wait 3-5 bus cycles
GPIO_PORTF_LOCK_R = 0x4C4F434B;//unlock
GPIOPortF
GPIO_PORTF_CR_R = 0x1F; // allow changes to PF4-0
// only PF0 to be unlocked, other bits can't be
GPIO_PORTF_AMSEL_R = 0x00;// disable analog
GPIO_PORTF_PCTL_R = 0x00;// bits for PF4-0
GPIO_PORTF_DIR_R = 0x0E;// PF4,0 in, PF3,1 out
GPIO_PORTF_AFSEL_R = 0x00;//disable alt func
GPIO_PORTF_PUR_R = 0x11;// enable pullup on PF0,4
GPIO_PORTF_DEN_R = 0x1F;// enable digital I/O
}
int main(void){
UART_OutChar(LF);
}
}
Output:
(i) Red Glowing:
Hardware Output:
Practice Exercise:
Aim: Control speed and direction of DC motor by sending commands from PC using UART module. Code:
//Include header files
#include "tm4c123gh6pm.h"
#include <stdint.h>
#include "PLL.h"
#include "string.h"
char string[20]; //string array
// standard ASCII symbols
#define CR 0x0D // carriage return (return to beginning of current line)
#define LF 0x0A //line feed or newline character '\n'
#define BS 0x08 //backspace
//------------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 |= 0x01; // activate UART0 Clock Gating Control
SYSCTL_RCGC2_R |= 0x01; // activate port A Clock Gating Control
UART0_CTL_R &= ~(0x01); // disable UART
UART0_IBRD_R = 43;// IBRD = int(80,000,000 / (16 * 115,200)) = int(43.40278)
UART0_FBRD_R = 26; // FBRD = int(0.40278 * 64 + 0.5) = 26
UART0_LCRH_R = 0x70;//8 bit word length, no parity bits,one stop bit,Enable FIFOs
UART0_CTL_R |= 0x01; // 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
GPIO_PORTA_PCTL_R = 0x00000011; // configure PA1-0 as UART
GPIO_PORTA_AMSEL_R &= ~0x03; // disable analog functionality on PA
}
//------------UART_OutChar------------
// Output 8-bit to serial port
// Input: letter is an 8-bit ASCII character to be
transferred // Output: none
void UART_OutChar(unsigned char data)
{ while((UART0_FR_R&0x20) != 0); // UART Transmit FIFO Full
UART0_DR_R = data;
}
//------------
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_InChar------------ // Wait for
new serial port input
// Input: none
// Output: ASCII code for key typed
unsigned char UART_InChar(void){
while((UART0_FR_R&0x10) != 0); // UART Receive FIFO Empty
return((unsigned char)(UART0_DR_R&0xFF));
}
//------------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;
}
//port D initialization
void PortD_Init(void)
{
volatile unsigned long delay;
SYSCTL_RCGC2_R |= 0x08;// clock for Port D
delay = SYSCTL_RCGC2_R;// wait 3-5 bus
cycles GPIO_PORTD_LOCK_R =
0x4C4F434B;//unlock GPIOPortD
GPIO_PORTD_CR_R = 0x03; // allow changes to PD1-0
// only PF0 to be unlocked, other bits can't be
GPIO_PORTD_AMSEL_R = 0x00;// disable analog
GPIO_PORTD_PCTL_R = 0x00;// bits for PD1-0
GPIO_PORTD_DIR_R = 0x03;// PD-1 PD-0
GPIO_PORTD_AFSEL_R = 0x00;//disable alt func
GPIO_PORTD_PUR_R = 0x03;// enable pullup on PD1-0
GPIO_PORTD_DEN_R = 0x03;// enable digital I/O
}
void SysInit(void) //Defining the SysInit function
{
NVIC_ST_CTRL_R = 0; //clear this register initially
NVIC_ST_CURRENT_R = 0;// any write to current clears it
NVIC_ST_CTRL_R = 0x00000005;// enable with core clock and interrupts
//00000101
//(last eight bit of CTRL register)
//defines that enabling clock system
//& enable clock counter & disabling auto-interrupt
}
void SysLoad(unsigned long period) //Defining the SysLoad function
{
NVIC_ST_RELOAD_R = period -1;
//Since we are comparing to 0 hence -1 is done to count those many times
NVIC_ST_CURRENT_R = 0;
// any value written to CURRENT clears
while((NVIC_ST_CTRL_R&0x00010000)==0){ // wait for count flag
}
}
/*STRELOAD register: It is a 32 bit register,
out of which first 8 bits are reserved and last
24 bits are editable by the user.
Hence it can take max value as
24’b111111111111111111111111, which essentially means
16777215 as decimal value. Hence this is the max value we can
pass as a parameter in function for which we can get correct
output. Using this function, we can create a 0.2097151875 sec
delay for input clock frequency as 80MHz. */ void SysFun(void){
NVIC_ST_CTRL_R = 0;//disable SysTick during setup
NVIC_ST_CTRL_R = 0x00000005; // enable with core clock and interrupts
//00000101
}
//code starts from main function
int main(void){
PLL_Init(); // set system clock to 50 MHz
UART_Init();// initialize UART
PortD_Init(); // initialize portD
SysFun();// initialize sysfun
SysInit(); // initialize sys_init
while(1){
UART_OutString("Enter Speed and Direction: "); //output
data UART_InString(string,19); // input data
if( strcmp(string,"50 clock")== 0)// if input data read
{
UART_OutChar(LF); // new line
UART_OutString("Motor roates at 50% DC Clockwise");
// output data message
while(((UART0_FR_R&0x10) != 0)){
GPIO_PORTD_DATA_R = (0x01); //using pD.0 =1 for 5ms
SysLoad(400000); // wait 5ms
GPIO_PORTD_DATA_R = (0x00); //using pD.0 =0 for 5ms
SysLoad(400000); // wait 5ms
// keeping pin D.1 always as zero
}
}
else if(strcmp(string,"50 anticlock")== 0)
{
UART_OutChar(LF); // new line
UART_OutString("Motor roates at 50% DC Anti-clockkwise");
// output data message
while(((UART0_FR_R&0x10) != 0))
{
GPIO_PORTD_DATA_R = (0x02); //using pD.1 =1 for 5ms
SysLoad(400000); // wait 5ms
GPIO_PORTD_DATA_R = (0x00); //using pD.1 =0 for 5ms
SysLoad(400000); // wait 5ms
// keeping pin D.0 always as zero
}
}
else if( strcmp(string,"75 clock")== 0)
{
UART_OutChar(LF); // new line
UART_OutString("Motor roates at 75% DC Clockwise");
// output data message
while(((UART0_FR_R&0x10) != 0))
{
GPIO_PORTD_DATA_R = (0x01); //using pD.0 =1 for 7.5ms
SysLoad(600000); // wait 7.5ms
GPIO_PORTD_DATA_R = (0x00); //using pD.0 =0 for 2.5ms
SysLoad(200000); // wait 2.5ms
// keeping pin D.1 always as zero
}
}
else if( strcmp(string,"90 clock")== 0)
{
UART_OutChar(LF); // new line
UART_OutString("Motor roates at 90% DC Clockwise");
// output data message
while(((UART0_FR_R&0x10) != 0)){
GPIO_PORTD_DATA_R = (0x01); //using pD.0 =1 for 9ms
SysLoad(720000); // wait 9ms
GPIO_PORTD_DATA_R = (0x00); //using pD.0 =0 for 1ms
SysLoad(80000); // wait 1ms
// keeping pin D.1 always as zero
}
}
else if( strcmp(string,"90 anticlock")== 0)
{
UART_OutChar(LF); // new line
UART_OutString("Motor roates at 90% DC anti Clockwise");
// output data message
while(((UART0_FR_R&0x10) != 0)){
GPIO_PORTD_DATA_R = (0x02); //using pD.1 =1 for 9ms
SysLoad(720000); // wait 9ms
GPIO_PORTD_DATA_R = (0x00); //using pD.1 =1 for 1ms
SysLoad(80000); // wait 1ms
// keeping pin D.0 always as zero
}
}
else
{
GPIO_PORTD_DATA_R &= (0x00);//clearing
UART_OutChar(LF); // new line
UART_OutString("No operation");// output data message
}
UART_OutChar(LF); // new line
} //end
while } //end
main
Output:
(i) 50% Clockwise:
Results:
All programs have been run successfully and appropriate images are observed in stimulation as well as Nokia screen.