In embedded systems, communication between microcontrollers and external devices is crucial. One of the most common protocols used for this is UART (Universal Asynchronous Receiver/Transmitter). It allows the PIC16F877A microcontroller to communicate with computers, sensors, and other microcontrollers via serial communication.
Here we will walk you through setting up the UART module of PIC16F877A, including sending and receiving data over serial communication. We'll also provide example code to help you get started.
What is UART?
UART is a simple protocol for serial communication where data is transmitted and received asynchronously. This means data is sent one bit at a time, and there’s no need for a shared clock signal between the transmitting and receiving devices. UART uses:
- TX (Transmit) Pin for sending data
- RX (Receive) Pin for receiving data
For PIC16F877A, RC6 is the TX pin and RC7 is the RX pin.
Step-by-Step Guide to Using UART with PIC16F877A
1. Setting Up the Hardware
Before configuring the UART, ensure your PIC16F877A is connected to your PC or another device via a USB-to-serial converter. Here’s how the connections should look:
- TX (RC6) -> RX of USB-to-serial converter.
- RX (RC7) -> TX of USB-to-serial converter.
- GND should be connected between the microcontroller and the converter.
2. Configuring UART in PIC16F877A
The PIC16F877A has a built-in UART module called USART (Universal Synchronous/Asynchronous Receiver/Transmitter). To use it in asynchronous mode (UART), you need to initialize the module with the following steps:
- Set the baud rate (data transfer rate).
- Enable the serial port and configure TX and RX pins.
- Enable transmission and reception.
Here’s a breakdown of how to set this up in code:
UART Initialization Code for PIC16F877A
#define _XTAL_FREQ 16000000 // Define the clock frequency (16 MHz)
void UART_Init() {
SPBRG = 24; // Baud rate generator value for 9600 baud with 16 MHz clock
TXSTAbits.BRGH = 0; // Low-speed baud rate
TXSTAbits.SYNC = 0; // Asynchronous mode
TXSTAbits.TXEN = 1; // Enable transmission
RCSTAbits.SPEN = 1; // Enable the serial port (TX and RX pins)
RCSTAbits.CREN = 1; // Enable continuous reception
}
Sending Data Using UART
Once UART is initialized, you can send data to a connected device (e.g., your computer) using the TX pin. The following function sends a single character over UART:
void UART_SendChar(char data) {
while (!TXIF); // Wait until the transmit buffer is empty
TXREG = data; // Load the data into the transmit register
}
To send a string, you can loop through each character:
void UART_SendString(const char *str) {
while (*str) {
UART_SendChar(*str++);
}
}
Example usage to send a string:
UART_SendString("Hello, UART!");
Receiving Data Using UART
To receive data sent from a connected device, you’ll use the RX pin (RC7). Here’s how you can read a single character:
char UART_ReceiveChar() {
while (!RCIF); // Wait until data is received
return RCREG; // Return the received byte
}
To receive a string:
void UART_ReceiveString(char *buffer, int maxLength) {
int i = 0;
char received;
while (i < maxLength - 1) {
received = UART_ReceiveChar(); // Receive a character
if (received == '\r') { // Stop if end of line character is received
break;
}
buffer[i++] = received; // Store received character in buffer
}
buffer[i] = '\0'; // Null-terminate the string
}
Complete Example: Echo Data Using UART
Here’s a complete example where the PIC16F877A reads data from the serial terminal and echoes it back:
#define _XTAL_FREQ 16000000 // Define the clock frequency (16 MHz)
#include <xc.h>
void UART_Init() {
SPBRG = 24; // Baud rate generator value for 9600 baud with 16 MHz clock
TXSTAbits.BRGH = 0; // Low-speed baud rate
TXSTAbits.SYNC = 0; // Asynchronous mode
TXSTAbits.TXEN = 1; // Enable transmission
RCSTAbits.SPEN = 1; // Enable the serial port
RCSTAbits.CREN = 1; // Enable continuous reception
}
void UART_SendChar(char data) {
while (!TXIF); // Wait until the transmit buffer is empty
TXREG = data; // Send the data
}
char UART_ReceiveChar() {
while (!RCIF); // Wait until data is received
return RCREG; // Return the received byte
}
void main() {
UART_Init(); // Initialize UART
char receivedChar;
while (1) {
receivedChar = UART_ReceiveChar(); // Read data from RX pin
UART_SendChar(receivedChar); // Echo the received data back to the TX pin
}
}