PIC16F877A consists of a USART(Universal Synchronous Asynchronous Reciever Transmitter) module which can be used for serial communication between PIC and computer as well as with other peripherals. USART in PIC16F877A can be made to operate in either Synchronous mode or Asynchronous mode unlike 8051 where only asynchronous communication is possible.

USART in PIC16F877A when configured in Asynchronous mode, allows full-duplex communication i.e transmission and reception can take place simultaneously.
In synchronous mode, communication is half-duplex. Data is sent and received through RC6/TX/DT pin and RC7/RX/CK pin outputs the clock pulses for synchronization. In synchronous mode, Master device is responsible for transmitting clock pulses on RC7/RX/CK line.

There are 3 registers associated with the USART module.


SPBRG(Baud Rate Generator Register)


USART module in PIC16F877a consists of a separate 8-bit dedicated timer(baud rate generator BRG) which is responsible for generating the required baud rate in Asynchronous mode as well as in Synchronous mode(only for master). The Period of BRG is controlled by the 8-bit SPBRG register.

  • In Asynchronous mode(When BRGH bit in TXSTA register is 0 – Low SPEED), the formula for Baud rate is given by:
    Baud rate = Fosc/64(X+1) where X is an 8-bit value written SPBRG register
  • In Asynchronous mode(When BRGH bit in TXSTA register is 1 – High SPEED) the formula for baud rate is given by:
    Baud rate = Fosc/16(X+1) where X is an 8-bit value written SPBRG register
  • In Synchronous mode bit, BRGH bit is disabled and the formula for BAUD rate is given by Fosc/4(X+1).

    role of BRGH bit: USART in PIC16F877A

    BRGH bit in TSXTA register

  • For example, consider we’re using a 4MHz crystal and require a Baud rate of 9600Bits/sec. On setting BRGH=1 in TXSTA register the formula becomes:
    9600 = 4Mhz/16(X+1)
    X = (4Mhz/(9600*16)) – 1
    X = 25.04
    Therefore the value to be loaded in the SPBRG register for obtaining a baud rate of 9600 is 25.


TXSTA(Transmit status and control register)

  • CSRC(CLock source select bit):
    This bit is used in synchronous mode. Setting it to 1 indicates master mode and the required clock is generated from BRG. CSRC when set to 0, indicates slave mode.
  • TX9(9th bit transmit enable):
    1- Enables 9-bit transmission
    0- Disables 9-bit transmission
  • TXEN(Transmit enable bit):
    Transmission is enabled when TXEN is set. It is disabled when TXEN is cleared.
  • SYNC(USART Mode select bit):
    1- Synchronous mode
    0- Asynchronous mode
  • BRGH(High Baud rate select bit):
    It is used for obtaining high baud rates. In asynchronous mode, high speed is obtained by setting this bit to 1. In synchronous mode, this bit has no effect(in other words, it will be 0).
  • TMRT(Transmit shift register status bit):
    For transmission, the user needs to write data to the TXREG register. The data from TXREG is then transferred to TSR(Transmit shift register) from where the data is actually transmitted. TMRT flag shows the status of TSR. It is set when TSR is empty.
  • TX9D:
    When 9-bit transmission is enabled, the 9th bit is to be written in TX9D. Bit TX9D needs to be written before you load data into TXREG register. TX9D is generally used for error checking.


RCSTA(Receive status and control register)

  • SPEN(Serial port enable):
    This bit configures the RC6/TX/DT pin and RC7/RX/CK pin for serial communication.
  • RX9(9- bit receive enabled bit):
    On setting it to 1, 9-bit reception will be enabled. 0 indicates 8-bit reception.
  • SREN(Single receive enable bit):
    SREN bit has no significance in Asynchronous mode. It is used in synchronous Master mode to enable single receive. SREN is automatically cleared after reception is complete.
  • CREN(Continuous receive enable bit):
    This bit is used in both synchronous and asynchronous mode. It enables continuous receive when set. Disables continuous receive when cleared.
  • ADDEN(Address detect enable bit):
    It is used in asynchronous mode when RX9 is set. When this bit is set, only data that has the ninth data bit set will be received and interrupt will occur on such instances when enabled.
  • RX9D:
    When 9-bit receive enable bit is set, the 9th received bit will be stored in RX9D. It is important to read this bit before reading the receive buffer RCREG. 
Error Bits
  •  FERR(Framing error bit) and OERR(Overrun error bit)
    During reception, the data is received in the Receive shift register(RSR) from where it is transferred to the receive buffer register(RCREG). The programmer needs to read the RCREG register. RCREG is a double buffered register i.e. it can store 2 bytes of received data in FIFO manner, and a third byte can begin being shifted into the Receive shift register(RSR). In the RSR register on detection of the third byte if RCREG is full(i.e. not read by the programmer), the Overrun error bit will be set and RSR contents will be lost. Existing data of RCREG can still be read. Overrun bit OERR needs to be cleared in software by resetting the receive logic(Clear and re-set CREN).
    Framing error bit is set when a stop bit is detected as clear. This bit is automatically updated on every byte received to indicate whether a framing error has been detected or not. Once you read the RCREG, RX9D and Framing bit of the next byte are updated in RCSTA. It is therefore important to read the status of this bit in RCSTA register before reading the content of RCREG.


Code for USART in PIC16F877A for communication between PC and PIC
// In the program below microcontroller will take input from the keyboard and will again trasmit it to the computer to be displayed on hyperterminal all through RS232 protocol.

#include <pic.h>
void transmit(unsigned char ch1);
unsigned char recieve();
void init_usart();
unsigned char ch;

void main()
data = recieve(); 

void init_usart
TXSTA = 0x24;     // Setting BRGH to 1 and Enabling TXEN
SPBRG = 25;       // Value to obtain a baud rate of 9600 in high speed mode
RCSTA = 0x90;     // Enabling Serial port SPEN and setting CREN for continuous receive

void transmit(unsigned char ch1)
while(TXIF == 0); //Wait till TXREG is empty
TXREG = ch1;      

unsigned char receive()
while(RCIF == 0); // Wait till data is received in RCREG


Electronics engineer graduated from M.H. Saboo Siddik college of engineering. Currently working as Jr. Innovative engineer. Skilled in 8051, PIC and ARM microcontrollers. Circuit analyzation and Debugging. Constantly looking to acquire more skills which would help myself to become more proficient in embedded domain. Founder and blogger at techetrx.com LinkedIn profile: https://www.linkedin.com/in/moiz-shaikh-305294137


Leave a Reply

Your email address will not be published. Required fields are marked *