Watch the Video Tutorial


Figure 1: PIC18F26K20 Connected to PC via MAX232

A serial port interface can be used for serial communication of data (send and receive) where data is sent or received one bit at a time between a personal computer (PC) and various devices supporting this type of protocol like PIC microcontrollers, GPS, GSM modem etc. While other interfaces like Ethernet, FireWire, and USB all send data as a serial stream, the term “serial port” usually identifies hardware more or less compliant to the RS-232 standard, intended to interface with a modem or with a similar communication device. RS232 Serial communication is still widely used in industrial application and with many electronic devices like modems but it is being replaced by the USB in portable devices.

The Universal Asynchronous Receiver/Transmitter (UART) controller is the key component of the serial communications between a device and a PC or between devices.
UART is also a common integrated feature in most microcontrollers today which is useful for communicating serial data (text, numbers, etc.) to your PC.
Most PIC microcontrollers have an internal UART at a specific pins of the microcontrollers but this feature can also be implemented with any pin with Software in most of the compilers like MPLAB XC8.
The device changes incoming parallel information (within the microcontroller/PC) to serial data which can be sent on a communication line.
At the destination, a second UART re-assembles the bits into complete bytes. Serial transmission of digital information (bits) through a single wire or other medium is much more cost effective than parallel transmission which requires multiple wires. Communication can be “full duplex” (both send and receive at the same time) or “half duplex” (devices take turns transmitting and receiving).

The UART Protocol

Asynchronous transmission allows data to be transmitted without the sender having to send a clock signal to the receiver. In this case, the sender and receiver must agree on timing parameters (Baud Rate) prior transmission and special bits are added to each word to synchronize the sending and receiving units.
In asynchronous transmission, the sender sends a Start bit, 5 to 8 data bits (Least Significant Bit first), an optional Parity bit, and then 1, 1.5 or 2 Stop bits. If the sender and receiver are not configured the same (these timing parameters), communication will not be done effectively.

The Start bit informs the receiver that a word of data is about to be sent, this is to tell the receiver to synchronise its clock with the transmitter’s clock. The frequency is very important here as well, that is why the transmitter and the receiver must have identical baud rate.
After the Start bit, now each individual bits of data are sent starting the Least Significant Bit (LSB).
When the entire data word has been sent, the transmitter may add a Parity Bit that the transmitter generates. The Parity Bit may be used by the receiver to perform simple error checking.
Then at last one Stop Bit is sent by the transmitter to indicate the end of transmission.
When the receiver has received all of the bits in the data word, it may check for the Parity Bits (both sender and receiver must agree on whether a Parity Bit is to be used), and then the receiver searches for a Stop Bit.
If the Stop Bit does not appear when it is supposed to, the UART considers the entire word to be garbled and will report a Framing Error to the host processor when the data word is read. Common reason for the occurrence of Framing Error is that the sender and receiver clocks were not running at the same speed, or that the signal was interrupted.
The typical format for serial ports used with PC connected to modems is 1 Start bit, 8 data bits, no Parity and 1 Stop bit. The typical format for serial ports used with PC connected to modems is 1 Start bit, 8 data bits, no Parity and 1 Stop bit.

This is basically in brief the software protocol of the UART. How about the physical layer standards that actually defines the level of voltages and so on?
There are quite a number of different standards that utilizes similar protocol. For instances, TTL level UART, RS-232, RS-422, RS-485 and etc.

                                       The TTL UART

Most microcontrollers with UART uses TTL (Transistor-transistor Logic) level UART. It is the simplest form of UART.
Logic 1 is represented by 5V and logic 0 by 0V.
Logic                                               Voltage 
Low                                                     0V
High                                                    5V

Voltage level for TTL level UART

The TTL level UART is commonly used in the communications between microcontrollers and ICs. Only 2 wires are required for the full duplex communications as illustrated in the picture below on figure 1.

Figure 2: Serial Communication Between 2 devices

The RS-232

The RS-232 is a standard for serial binary data signals connecting between a Data Terminal Equipment (DTE) and a Data Communication Equipment (DCE).
One of the significant differences between TTL level UART and RS-232 is the voltage level. Valid signals in RS-232 are ±3 to – ±15V, and signals near 0V is not a valid RS-232 level.
 Logic                                             Voltage 
Low                                                   +3 to +15V
High                                                  -3 to -15V

Voltage level for RS-232

Besides voltage level, the RS-232 also has a few extra pins specifically designed for the communication between PC and modem. The pinouts of the DB-9 and their functions are shown below in table 1.

Pin Signal abreviation Signal Name DTE (PC)
1 DCD Data Carrier Detect In
2 RXD Receive Data In
3 TXD Transmit Data Out
4 DTR Data Terminal Ready out
5 GND Signal Ground
6 DSR Data Set Ready in
7 RTS Request to Send out
8 CTS Clear to Send In
9 RI Ring Indicator In

Table 1: Pinout and diagram of DE9 connector (DB9 connector), commonly used for serial ports (RS-232).

The DTE (PC) has the male connector (shown below), and the DCE (peripheral) has the female.
The maximum cable length for RS-232 is about 15m (50ft), but in practice depends on baud rate, cable specific capacitance and ambient noise. The table below contains some rules-of-thumb for recommended distances.

Baud Rate Maximum cable length
56000 2.6m (8.5ft)
38400 3.7m (12ft)
19200 7.6m (25ft)
9600 15m (50ft)
4800 30m (98ft)
2400 60m (196ft)

Table 2: Recommended distances
 Interfacing between TTL level UART and RS-232

From the above discussions, we know that microcontrollers use TTL level UART (5V for logic 1 and 0V for logic 0) while the PC serial port uses RS-232. Since both standards uses similar software protocol, both of them are able to communicate via UART. However, because of the differences in voltage level and polarity, we will need a level shifter to interface the TTL level UART with the RS-232. Nowadays, this can be easily done with the commonly available IC such as the MAX2322 from Maxim.
The diagram below on figure 3 illustrates how the MAX232 IC can be connected to the UART of a microcontroller (TX of PIC connected to T1IN of MAX232 and RX pin to R1OUT of MAX232) and a personal computer with DB9 connector.

Figure 3: The use of MAX232 IC to convert TTL levels from microcontroller to RS232 level

                  EUSART Configuration with MPLAB Code Configurator

MPLAB is phasing out the PIC18F Peripheral Library which is no longer included in XC8 v1.35. In this version, you have to download and install them separately into your compiler and they are now called Legacy Peripheral Libraries.

The MPLAB® Code Configurator (MCC) is a user friendly Graphical User Interface (GUI) plug-in tool for MPLAB® X IDE which generates easy to understand C code that is inserted into an MPLAB® X project, based on the settings peripherals configurations and selections made in the Graphical User Interface (GUI).  The advantage of  MCC , it can generate codes not only for PIC18F but for a wide range of PICs including PIC16F and PIC24 series.

To learn more, read the article:

 MPLAB® Code Configurator

Below is the configuration of EUSART module for the  example as above (circuit diagram on figure 1). In this example we are using a newer PIC model, the PIC18F26K20. The E of the EUSART stands for Enhanced USART, its basically the same with the USART but with some extra features like Sleep/ Wake up on receive. In this example the PIC18F26K20 is connected to a PC via MAX232 voltage converter. Three LEDs are connected to PORTB, Red LED on RB0, Yellow LED on RB1 and Green LED on RB2. If 1 received from the PC, the PIC switches ON the Red LED, if 2 the Yellow LED is switched ON and if 3 switches ON the Green LED.

Watch the Video Tutorial

Below is the Main.c file:

USART Functions with PIC18F Peripheral Library

XC8 compiler versions v1.34 and below supplies a PIC18F Peripheral Library Help Document found inside the compiler installation directory in:  ..Program Files (x86)/ Microchip/ xc8/ v1.34/ docs/ MPLAB_XC8_Peripheral_Libraries.pdf   (assuming you installed your compiler in the Program Files (x86) directory. v1.34 is the version of your compiler, it might be different if you are using a different compiler).
Search for the PIC you are going to use, click on: “CLICK HERE for the Peripheral Library Support Details for this Device” For a 18F2620 family, the USART functions are from page 1251 in the pdf ). in XC8 v1.35. In this version, you have to download and install them separately into your compiler and they are now called Legacy Peripheral Libraries.
Table 3 below shows a summary of USART functions. In microcontrollers with more than one USART a number is added to the end of these functions to identify the USART module used.
Notes: For PIC Microcontrollers which don’t have a USART module or if any input/output either than the default hardware pins are required, the Software USART functions can be used and some PIC Microcontrollers have more than 1 USART modules, in this case, you have to specify the USART you are referencing to ( openUSART or open2USART) 

Table 3: USART Functions

This function configures the USART. Two arguments are required: a configuration argument called config and an integer called spbrg, which specifies the value to be written to the baud rate generator register to determine the baud rate. 
Interrupt on transmission: USART_TX_INT_ON: Transmit interrupt ON 
                                      USART_TX_INT_OFF: Transmit interrupt OFF
Interrupt on reception:      USART_RX_INT_ON: Receive interrupt ON 
                                       USART_RX_INT_OFF: Receive interrupt OFF 
USART mode:                   USART_ASYNCH_MODE: Asynchronous mode 
                                       USART_SYNCH_MODE: Synchronous mode 
Transmission width:`          USART_EIGHT_BIT: 8-bit transmit/receive 
                                       USART_NINE_BIT: 9-bit transmit/receive
Slave/Master select:           USART_SYNC_SLAVE: Synchronous slave mode
                                        USART_SYNCH_MASTER: Synchronous master mode
Reception mode:               USART_SINGLE_RX: Single reception 
                                        USART_CONT_RX: Continuous reception 
Baud rate:                         USART_BRGH_HIGH: High baud rate 
                                        USART_BRGH_LOW: Low baud rate
Address Detect Enable:      USART_ADDEN_ON: Enables address detection
                                        USART_ADDEN_OFF: Disables address detection
spbrg: This is the value that is written to the baud rate generator register which determines the baud rate at which the usart operates.

The formulas for baud rate are:  
For High Speed (USART_BRGH_HIGH), Baud = FOSC/[16 * (spbrg + 1)] or spbrg = FOSC/(16 * baud) – 1 and 
For Low Speed (USART_BRGH_LOW), Baud = FOSC/[16 * (spbrg + 1)] or spbrg = FOSC/(64 * baud) -1, where FOSC is the microcontroller clock frequency.

frequency is 8MHz, using high speed, asynchronous mode is used with 9600 baud and 8 data bits.
spbrg = FOSC/(16 * baud) – 1 = 8000000/(16 × 9600) – 1 = 51 OpenUSART function becomes:


This function returns a “1” if the USART transmitter is busy transmitting a character.
This function should be checked before sending a new byte to the USART.
The function returns a “0” if the USART transmitter is idle.

This function disables the USART.

This function returns a “1” if data is available in the USART read buffer and a “0” indicates that data is not available in the read buffer.

This function reads a byte (one character) from the USART buffer.
Example: unsigned char data;
data = getcUSART( );

This function reads a string of characters from the USART.
This function waits and reads a specified number of characters. There is no timeout and the program will wait forever if the specified number of characters are not received.
Example: char buffer[20];
getsUSART(buffer, 10);    // Wait to receive 10 characters

putcUSART = WriteUSART
This function sends a byte (one character) to USART.

This function sends a string of characters to USART from the data memory.
Example: putsUSART(“Hello World…”);

This function sends a string of characters to USART from the program memory.

This function sets the baud rate configuration bits for enhanced USART operation.
The valid arguments can be formed from bitwise AND of the following definitions:
Clock idle state: BAUD_IDLE_CLK_HIGH Clock idle state is high level
BAUD_IDLE_CLK_LOW Clock idle state is low level
Baud rate generation: BAUD_16_BIT_RATE 16-bit baud rate generation
BAUD_8_BIT_RATE 8-bit baud rate generation
RX pin monitoring: BAUD_WAKEUP_ON RX pin monitored
BAUD_WAKEUP_OFF RX pin not monitored
Baud rate measurement: BAUD_AUTO_ON Autobaud rate measurement enabled
BAUD_AUTO_OFF Autobaud rate measurement disabled

Let us create a simple project as shown on figure 3, it consists of a PIC18F2620 connected to a PC via MAX232 voltage converter. 3 LEDs are connected to PORTB, Red LED on RB0, Yellow LED on RB1 and Green LED on RB2. If 1 received from the PC, the PIC switches ON the Red LED, 2 the Yellow LED is switched ON and 3 switches ON the Green LED.

* File: main.c
* Author:
* Created on 26 June 2015, 10:57 PM

#include <stdio.h>
#include <stdlib.h>
#include <plib/usart.h>

#include "config.c" //configuration bits


void main(void) {
OSCCON=0x76; //Configure OSCON Register to use
//internal oscillator. Please check datasheet
char data;
unsigned char Txdata1[] = "Welcome to rn";
for (int x=0; x<=10; x++) __delay_ms(50); //Generate 500ms delay
unsigned char Txdata2[] = "Press 1 for Red LED, 2 for Yellow LED and 3 for Green LED rn";
// configure USART frequency is 8MHz, using high speed, asynchronous mode is used with 9600 baud and 8 data bits.
//Fosc / (16 * (spbrg + 1 ))
// spbrg = FOSC/(16 * baud) - 1
// = 8000000/(16 × 9600) - 1 = 52

while(BusyUSART()); //Check if Usart is busy or not
putsUSART(Txdata1); //transmit the string1
for (int x=0; x<=20; x++) __delay_ms(50); //Generate 500ms delay
while(BusyUSART()); //Check if Usart is busy or not
putsUSART(Txdata2); //transmit the string2

for (int x=0; x<=20; x++) __delay_ms(50); //Generate 500ms delay

data = ReadUSART();
case '1':LATBbits.LB0 = 1;
LATBbits.LB1 = 0;
LATBbits.LB2 = 0;


case '2':LATBbits.LB0 = 0;
LATBbits.LB1 = 1;
LATBbits.LB2 = 0;

case '3':LATBbits.LB0 = 0;
LATBbits.LB1 = 0;
LATBbits.LB2 = 1;

default:LATBbits.LB0 = 0;
LATBbits.LB1 = 0;
LATBbits.LB2 = 0;


You can download the full project files (MPLAB XC8 source code and Proteus Schematic design) below here. All the files are zipped, you will need to unzip them (Download a free version of the Winzip utility to unzip files).

Download Mplab Project with PIC18F Library: USART MPLAB XC8 Project

Download Proteus Schematic with PIC18F2620: USART Proteus Schematic Project

Download MPLAB Project with Code Configurator: EUSART-MPLAB-XC8-Project-MCC

Download Proteus Schematic with PIC18F26K20: EUSART Proteus Schematic Project