Introduction

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.

Watch the Video Tutorial


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 all microcontrollers have an internal UART at a specific pins of the microcontrollers but this feature can also be implemented at any pin with a software in most of the compilers.
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.

Serial Communication Between 2 devices

Figure 2: Serial Communication Between 2 device

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 practise 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 2 illustrates how the MAX232 IC can be connected to the UART of a microcontroller (TX and RX pins) and a personal computer with DB9 connector.

SThe use of MAX232 IC to convert TTL levels from microcontroller to RS232 level

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

                    mikroC Pro for PIC UART Library Functions 

Most of microcontrollers on the market nowdays have at least one UART module.
The mikroC PRO for PIC UART Library provides comfortable work with the Asynchronous (full duplex) mode.
Below is a quick descriptions of some UART functions For more information, please visit online the mikroC pro for PIC UART Library page.

Notes: Some Microcontrollers have multiple UART modules, in order to select the desired UART module, simply change the letter x in the routine prototype for a number from 1 to 2.
You can also use the UART_Set_Active function (UART modules have to be previously initialized) to switch between the UART modules in the UART library.
Please, read your datasheet to find out how many UART modules your microcontroller have before utilizing this library.

These are the UART library fucntions:
–> UARTx_Init
–> UARTx_Data_Ready
–> UARTx_Tx_Idle
–> UARTx_Read
–> UARTx_Read_Text
–> UARTx_Write
–> UARTx_Write_Text
–> UART_Set_Active

All you need to do here is to change the letter x in the routine prototype for a number from 1 to 2 depending on your microcontroller:
–> UART1_Init                       //Initialize UART 1
–> UART2_Data_Ready      // UART 2 data ready

UARTx_Init  

Prototype: void UARTx_Init(const unsigned long baud_rate);

This function initializes the desired hardware UART module with the desired baud rate. You can refer to the microcontroller datasheet for baud rates allowed for specific oscillator frequency, if you put an unsupported baud rate, the compiler will report an error.

This routine should always be called before using any other functions of UART Library and make sure the microcontroller you are using has a hardware UART module.

Parameters: baud_rate: This is the required baud rate, please refer to the device datasheet for baud rates allowed for specific oscillator frequency.

Note: Calculation of the UART baud rate value is carried out by the compiler, as it would produce a relatively large code if performed on the library level. Therefore, compiler needs to know the value of the parameter in the compile time. That is why this parameter needs to be a constant, and not a variable.

Example:

UARTx_Data_Ready

This function tests if data in receive buffer is ready for reading, it returns 1 if data is ready for reading or 0 if there is no data in the receive register. Before using this function, the UART must be configured first using the UARTx_Init fuction.

Example:

UARTx_Tx_Idle

This function tests if the transmit shift register is empty or not, it returns 1 if the data has been transmitted or 0 if not. Before using this function, the UART must be configured first using the UARTx_Init fuction.

Example:

UARTx_Read

This function receives a byte via UART. It always good to use the function UARTx_Data_Ready to test if data is ready first before reading it. It returns the recieved byte. Before using this function, the UART must be configured first using the UARTx_Init fuction.

Example:

UARTx_Read_Text 

Prototype: void UARTx_Read_Text(char *Output, char *Delimiter, char Attempts);

This function keeps on reading characters received via UART until the delimiter sequence is detected. The read sequence is stored in the parameter output; delimiter sequence is stored in the parameter delimiter.

Parameters: Output: received text

Delimiter: sequence of characters that identifies the end of a received string

Attempts: defines number of received characters in which Delimiter sequence is expected.

If Attempts is set to 255, this routine will continuously try to detect the Delimiter sequence. Before using this function, the UART must be configured first using the UARTx_Init fuction.

Example: This example reads text until the sequence “END” is received, and send back what’s been received:

UARTx_Write

Prototype: void UARTx_Write(char data);

This function transmits a byte via the UART module.

Parameters: data: This is the data to be sent.

Before using this function, the UART must be configured first using the UARTx_Init fuction.

Example:

UARTx_Write_Text 

Prototype: void UARTx_Write_Text(char * UART_text);

This function Sends text via UART. Text should be zero terminated.

Parameters: UART_text: is the text to be sent

Before using this function, the UART must be configured first using the UARTx_Init fuction.

Example: This example reads text until the sequence “END” is received, and send back what’s been received:

UART_Set_Active

Prototype: void UART_Set_Active(char (*read_ptr)(), void (*write_ptr)(unsigned char data_), char (*ready_ptr)(), char (*tx_idle_ptr)())

This function sets active UART module which will be used by the UART library routines.

After selecting the active UART module, there is no more need to specify module 1 or 2, for example if module 1 has been selected then you can read like this: UART_Read(); in stead of UART1_Read();

Parameters: read_ptr: UARTx_Read handler

write_ptr: UARTx_Write handler

ready_ptr: UARTx_Data_Ready handler

tx_idle_ptr: UARTx_Tx_Idle handler

This routine is available only for microcontroller with two UART modules and before using this function, the UART must be configured first using the UARTx_Init fuction.

Example: 

 Example

Let us create a simple project as shown on figure 1, it consists of a PIC18F26K20 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.

You can test this example using the mikroC PRO for PIC terminal, by clicking on Tools menu then USART Terminal or any other Serial Terminal. You can also use our serial terminal we created with C#.

Remember to set correctly the PORT settings and select the correct PORT.

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 mikroC Project: mikroC_USART

Download Proteus Schematic:USART_Proteus