UART in PIC16F877A pic microcontroller with Proteus simulation

Before going to this tutorial you are recommended to see
1) GPIO Configuration in PIC16F877A
2) PIC16F877A Interrupt configuration

UART in PIC16F877A PIC microcontroller

Asynchronous communication can be configured in PIC16F877A with TXSTA(TRANSMIT STATUS AND CONTROL REGISTER) and RECEIVE STATUS AND CONTROL REGISTER(RCSTA). RC6 is a transmission pin and RC7 is a receive pin. in PIC16F877A. This RX needs to be connected to the receiver TX and viceversa for receiver.


We are going to configure Transmission as 8bit transmission(also no parity) (TX9 = 0). Enable transmission (TXEN = 0). Asynchronous transmission (SYNC = 0). Low speed mode (BRGH = 0).


Configure the receive control register as Enable Serial port (SPEN = 1). Enable continuous receive ( CREN = 1). 

UART Baudrate generation
Microcontroller is going to operate on 20MHz oscillator frequency, UART is configured in Low frequency mode. So that to achieve a common Baudrate of 9600 SPBRG value is given as 31.
Below is the other baudrate values.

UART Transmission working in PIC16F877A

UART Receiving Opearation in PIC16F877A
More detailed explanation for this block diagram is given in the datasheet

UART Transmit Diagram

UART Receive Diagram

Embedded C Program

#include <xc.h>
#include <pic16f877a.h>

void interrupt ISR()
    //If the received interrupt is because of
    //data received in UART
    if(PIR1bits.RCIF == 1)
        //Clear the interrupt
        PIR1bits.RCIF = 0;
        TXREG = (RCREG + 1);
        while(TXSTAbits.TRMT == 0);

void UART_Init()
    //Select 8bit transmission
    TXSTAbits.TX9 = 0;
    //Enable Transmit
    TXSTAbits.TXEN = 1;
    //Async mode select
    TXSTAbits.SYNC = 0;
    //Operate in Low Speed
    TXSTAbits.BRGH = 0;
    //Enable Serial Port
    RCSTAbits.SPEN = 1;
    //Enable continuous receive
    RCSTAbits.CREN = 1;
    //Baudrate 9600
    SPBRG = 31;
    //Enable global interrupt
    INTCONbits.GIE = 1;
    //Enable Peripheral interrupt
    INTCONbits.PEIE = 1;
    //Enable receive interrupt
    PIE1bits.RCIE = 1;
    //Clear the receive interrupt flag
    PIR1bits.RCIF = 0;

void main(void) {
    //Initialize UART
    //Loop forever

Here the UART is initialized first as a 8bit transmission with 9600(approx) baudrate, both transmit and receive is enabled. To receive the interrupt on every data received through RC7 receive pin, global interrupt, peripheral interrupt needs to be enabled. RCIE bit enables the actual uart rx(receive) interrupt.

In the Interrupt service routine RCIF flag bit is used to check, the interrupt is occured by receive interrupt. If so, clear the flag RCIF. RCREG register holds the received 8bit data.

For example, We are going to transmit the next ASCII value of the received value. TRMT bit is used to stop until the transmit completion. So that If the received data is 'A' Transmit data will be 'B' and so on.

Proteus Hardware Simulation Circuit

Virtual Terminal in Proteus is as below
Virtual Terminal Configuration

Proteus Simulation Output

What if Baudrate mismatch ?

When baudrate mismatch communication will not be proper as shown below.


Video tutorial

Addon - What is loopback Test ?

No comments:

Post a comment