In this project we will interface uart with PIC16F877A microcontroller and communicate with the microcontroller from a computer. If you are new to PIC microcontroller programming we suggest you to execute the basic led blinking project here before trying this project.
The setup requirement for this project is as given below:
Learn to develop embedded systems, interfacing electronic peripherals through real time projects and get required practical skills for software jobs
The required hardware and software for this project is as below:
Make sure that development board housing PIC16F877A microcontroller is NOT powered on. You should connect the GND pin, pin 26(Rx) pin, pin 25(Tx) to the Tx pin, Rx pin, GND pin of TTL to USB converter module. Connect other end of the TTL to USB converter module to one of the USB port port in your computer. Go to windows start -> device manager and check that the converter module is recongnized. If it is not recognized, right click on the device and follow the direction to get the driver for the module from internet. Once all the three connections are made between Microcontroller and TTL - USB converter module, you power on the development board and develop the uart program as explained in the next section.
Lets discuss about the registers in PIC16F877A PIC microcontroller and its programming. The USART is one of the two serial I/O modules in PIC16F877A.
PIC16F877A USART has both synchronous and asynchronous features. The USART can be configured as a full-duplex asynchronous system that can communicate with peripheral devices, such as CRT terminals and personal computers, or it can be configured as a half-duplex synchronous system that can communicate with peripheral devices, such as A/D or D/A integrated circuits, serial EEPROMs, etc.There are 6 registers that are associated with UART in PIC16F877A microcontroller.
|1||SPBRG(Serial Port baud rate generator)|
|4||TXSTA(Transmit control and status register)|
|5||RXSTA(Receive control and status register)|
|6||PIR1(Peripheripheral interrupt request register 1)|
Some of the baud rates generated out of the computer are 1200,2400,4800,9600,19200,38400,57600,115200. PIC16F877A transfers and receives data serially at many different baud rates. The baud rate in PIC16F877A is programmable. This is done with the help of the SPBRG register. For a give crystal frequency the value loaded into the SPREG register decides the baud rate. In asynchronous mode BRGH in TXSTA bit 2 also controls the baud rate.
Given the desired baud rate and FOSC, the nearest integer value for the SPBRG register can be calculated using the formula in figure shown below. From this, the error in baud rate can be determined.
Example: With a crystal frequency of 10MHz the instruction cycle time frequency is 2.5MHz. PICs UART circuitry divides the instruction cycle frequency by 16 once more before it is used by an internal timer to set the baud rate. So 2.5GHz is divided by 16 gives 156250Hz. So for getting a baud rate of 9600 the value of SPBRG is set to: (156250/9600)-1 which is 15 in decimal or F in hexadecimal. The default value of 16 can be reduced to get higher baud rate with the same crystal by which UART's internal circuitry divides can be changed using BRGH value to 1. When BRGH is set to 0 it does not do any increase in baud rate. But when it is set to 1 it increases the baud rate by 4 i.e. division by 4 happens instead of 16.
Example: Baud Rate(9600) = (11.0592*1000000)/(16 * (71 + 1)) with BRGH =1 in TXSTA register. So SPBRG = 71 i.e. in hex SPBRG = 0x47.
TXREG Register is another 8-bit register used for serial communication in the PIC16F877A. For a byte of data to be transferred via the TX pin it must be placed in the TXREG register. TXREG is a special function register and can be accessed like any other register in the PIC16F877A.
Once a byte is written into the TXREG, it is fetched into a register called TSR(Transmit shift register). The TSR frames the 8-bit data with the start and stop bits and the 10-bit data is serially transferred serially via the TX pin. While TXREG is accessible by the programmer, TSR is not accessible and strictly for internal purpose.
When bits are received internally serially via the RX pin, the PIC16F877A deframes them by eliminating the stop and start bits, making a byte out of the data received and then placing it in the RCREG register.
The TXSTA register is an 8-bit register used to select the synchronous /asynchronous modes and data framing size, among the other things. We use the asynchronous mode with data size of 8-bits. The BRGH bit is used to select a higher speed of transmission. The default is lower baud rate transmission. D6 bit determines the framing of data by specifying the number of bits per character. We use 8-bit data size. There are some applications where nineth bit is used as an address.
The D1 bit checks the status of the TSR register which cannot be accessed.Once a byte is written into the TXREG, it is fetched into a register called TSR(Transmit shift register). The TSR frames the 8-bit data with the start and stop bits and the 10-bit data is serially transferred serially via the TX pin. While TXREG is accessible by the programmer, TSR is not accessible and strictly for internal purpose. When the last bit which is the stop bit is transmitted the TRMT flag is raised to indicate that it is empty and ready for next byte. When TSR fetches the data from TXREG, it clears the TRMT flag to indicate it is full. When TSR is empty it gets its data from TXREG register and clears the TXREG register immediately, so it does not send the same data twice.
The Transmit status and control register is shown in figure below.
The RXREG register is an 8-bit register used to enable the serial port to receive data. The Receive status and control register is shown in figure below.
Two bits of the PIR1 register are used for UART. They are TXIF(Transmit Interrupt Flag) and RCIF(Receive Interrupt Flag). We monitor the TXIF flag bit and RCIF flag bit to make sure that all the bits of the last byte are transmitted before we write another byte into the TXREG. By the same logic, we monitor the RCIF flag to see if a byte of data has come in yet.