A universal asynchronous receiver-transmitter is a hardware module for asynchronous serial communication in which the data format and transmission speeds are configurable. Serial communication using a Microcontroller is one of the easiest operations to learn on a microcontroller and it comes into use in almost every application. In this tutorial, we learn to Enable the inbuilt hardware module for UART in PIC16F877A Microcontroller and how to communicate with your Computer using the UART protocol.
This can be achieved using a DB9 connector. If your PC doesn’t have a DB9 port, you might want to use an RS232 to USB converter. Also, you may directly use a TTL to USB converter.
TTL – RS232 or TTL USB converter modules can be easily purchased. But if you want to build your own, use the below circuits.
TTL – USB converter circuit
This tutorial will focus on receiving a character typed on PC and then transmitting that back to PC to display on the screen. we will use the serial terminal, ‘RealTerm’ for transmitting and receiving data from the computer side.
Learn more about RealTerm here.
Make sure you chose the right port and Baud rate in Realterm. We will be configuring our UART to work on a Baud rate of 9600. So the same value should be set in RealTerm.
Before moving on to program lets understand the registers associated with PIC16F877A UART.
See the table below.
Here, TXSTA and RCSTA are the control registers. So now, let’s see how these registers can be configured.
- CSRC: Clock Source Select bit
- Asynchronous mode: Don’t care.
- TX9: 9-bit Transmit Enable bit
- 1 = Selects 9-bit transmission
- 0 = Selects 8-bit transmission
- TXEN: Transmit Enable bit
- 1 = Transmit enabled
- 0 = Transmit disabled
- SYNC: USART Mode Select bit
- 1 = Synchronous mode
- 0 = Asynchronous mode
- BRGH: High Baud Rate Select bit
- 1 = High speed
- 0 = Low speed
- TRMT: Transmit Shift Register Status bit
- 1 = TSR empty
- 0 = TSR full
- TX9D: 9th bit of Transmit Data, can be Parity bit
- SPEN: Serial Port Enable bit
- 1 = Serial port enabled (configures RC7/RX/DT and RC6/TX/CK pins as serial port pins)
- 0 = Serial port disabled
- RX9: 9-bit Receive Enable bit
- 1 = Selects 9-bit reception
- 0 = Selects 8-bit reception
- SREN: Single Receive Enable bit
- Asynchronous mode: Don’t care.
- CREN: Continuous Receive Enable bit
- Asynchronous mode:
- 1 = Enables continuous receive
- 0 = Disables continuous receive
- ADDEN: Address Detect Enable bit
- Asynchronous mode 9-bit (RX9 = 1):
- 1 = Enables address detection, enables interrupt and load of the receive buffer when RSR is set
- 0 = Disables address detection, all bytes are received and the ninth bit can be used as a parity bit
- FERR: Framing Error bit
- 1 = Framing error (can be updated by reading RCREG register and receive next valid byte)
- 0 = No framing error
- OERR: Overrun Error bit
- 1 = Overrun error (can be cleared by clearing bit CREN)
- 0 = No overrun error
- RX9D: 9th bit of Received Data (can be parity bit but must be calculated by user firmware)
Baud Rate Calculation
The main criterion for UART communication is its baud rate. Both the devices Rx/Tx should be set to the same baud rate for successful communication.
This can be achieved by SPBRG register. SPBRG is an 8-bit register that controls the baud rate generation.
Given the desired baud rate and FOSC, the nearest integer value for the SPBRG register can be calculated using the below formula.
- BRGH = 1 High Speed
- SPBRG = (Fosc / (16 * BaudRate)) – 1
- BRGH = 0 Low Speed
- SPBRG = (Fosc / (64 * Baud rate)) – 1
Program to receive and transmit a character using UART
First, the xc.h header should be used to access compiler and device-specific features. I have also included the file containing the configuration bits; ‘Config.h’. You can get detailed instructions on setting up configuration bits here.
In the main function, we will do all the required configuration for the UART module.
- The Tx pin must be set as output and Rx will be input. For this TRISC is given the value 0x80.
- To Enable transmission and to work in Asynchronous 8 bit mode TXSTA is given the value 0x24
- To enable the Serial ports and Continues receiving RCSTA will take the value 0x90
- value for SPBRG is calculated for Baudrate of 9600 using the formula.
- Inside the while loop, The character returned from receive function is stored to variable ‘a’ and then it is transmitted back to the computer to display using the transmit function.
TRISC = 0X80;
TXSTA = 0X24;
RCSTA = 0X90;
SPBRG = (20000000UL / (long)(16UL * 9600)) - 1;
a = rec(a[i]);
To transmit the character, first, the character should be loaded into the TXREG register. After this, we will wait till the TXIF bit is set to ensure the transaction is complete.
Before leaving the function, TXIF is made 0 again.
void trans(char a)
To ensure the data is completely received, we will wait till RCIF bit is set. After that, the data is taken from the RCREG register.
After complete reception, RCIF should also be made to 0.
void rec(char a)
Program to transmit a string to PC using UART
Now let’s see an example to send a complete string to the PC using UART.
Advantages of UART
- Requires only two wires for full-duplex data transmission.
- No need for a clock or any other timing signal.
- The parity bit ensures basic error checking is integrated into the data packet frame.
Disadvantages of UART
- The size of the data in the frame is limited.
- Speed for data transfer is less compared to parallel communication.
- Transmitter and receiver must agree to the rules of transmission and the appropriate baud rate must be selected.