Interfacing LCD with PIC16F877A: Displaying Sensor Data

In embedded systems, Liquid Crystal Displays (LCDs) are widely used for displaying information such as sensor data, real-time clock values, or simple text-based messages. One of the most common LCD modules used with microcontrollers like the PIC16F877A is the 16x2 LCD, which can display 16 characters per line and has 2 rows. This blog post will guide you through interfacing a 16x2 LCD with a PIC16F877A microcontroller to display sensor data, such as temperature from an analog temperature sensor.

Components Required:

  • PIC16F877A Microcontroller
  • 16x2 LCD Module
  • LM35 Temperature Sensor (or any analog sensor)
  • 10kΩ Potentiometer (for LCD contrast adjustment)
  • 10kΩ Resistor (for sensor pull-down)
  • Breadboard and Jumper Wires
  • Power Supply (5V)

Circuit Diagram

The LCD module needs to be connected to the PIC16F877A using 8-bit or 4-bit mode. Here, we will use 4-bit mode, which reduces the number of I/O pins required.

Interfacing LCD with PIC16F877A circuit diagram

  1. LCD Connections:

    • RS (Register Select): Connected to RB0.
    • EN (Enable): Connected to RB1.
    • D4 to D7: Connected to RB2, RB3, RB4, and RB5 respectively (for 4-bit data transmission).
    • VSS: Connected to Ground.
    • VDD: Connected to 5V.
    • VEE: Connected to the wiper of the 10kΩ potentiometer for contrast control.
    • RW: Connected to Ground (write mode).
  2. Temperature Sensor (LM35):

    • VCC: Connected to 5V.
    • GND: Connected to Ground.
    • OUT: Connected to AN0 (RA0) on the PIC16F877A (for ADC input).
  3. Potentiometer: Adjust the contrast of the LCD by connecting the potentiometer's middle pin to the VEE pin of the LCD.

Circuit Description:

In this setup, the LM35 temperature sensor is connected to AN0 (RA0) of the PIC16F877A. The sensor outputs an analog voltage corresponding to the ambient temperature, which is fed into the ADC of the microcontroller. The microcontroller converts the analog value to a digital value and then to a readable temperature in degrees Celsius. This temperature is displayed on the 16x2 LCD using the standard 4-bit interface. The potentiometer connected to the LCD adjusts the contrast of the characters displayed on the screen.

Code Overview

The code below initializes the LCD and ADC, reads analog sensor data from the LM35, converts it to temperature, and displays the temperature on the LCD.

Code:

#define _XTAL_FREQ 16000000 // Define operating frequency
#include <xc.h>
#include <stdio.h> // For sprintf()

// CONFIGURATION BITS
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

// LCD pin configuration
#define RS RB0
#define EN RB1
#define D4 RB2
#define D5 RB3
#define D6 RB4
#define D7 RB5
#define delay for(j=0;j<1000;j++)

int j;

void lcd_init();
void lcd_cmd(unsigned char cmd);
void lcd_data(unsigned char data);
void lcd_write_4bits(unsigned char data);
void show(unsigned char *s);
void adc_init();
unsigned int read_adc();
void display_temperature(unsigned int temp);

void main() {
unsigned int adc_value;
unsigned int temperature;

// Configure LCD pins
TRISB = 0x00; // Set PORTB as output for LCD control and data lines

lcd_init(); // Initialize the LCD
adc_init(); // Initialize ADC

lcd_cmd(0x80); // Set cursor at beginning of first line
print("Temperature:"); // Display label

while (1) {
adc_value = read_adc(); // Read ADC value from AN0 (LM35)
temperature = adc_value * 0.488; // Convert ADC value to temperature (LM35 gives 10mV/°C)
display_temperature(temperature); // Display the temperature on the LCD

__delay_ms(1000); // Delay 1 second before next reading
}
}

void lcd_init() {
lcd_cmd(0x33); // Initialization sequence for 4-bit mode
lcd_cmd(0x32); // Initialization sequence for 4-bit mode
lcd_cmd(0x28); // 4-bit mode, 2-line display, 5x7 font
lcd_cmd(0x0C); // Display on, cursor off
lcd_cmd(0x06); // Entry mode, increment cursor
lcd_cmd(0x01); // Clear display
}

void lcd_cmd(unsigned char cmd) {
RS = 0; // Command mode
lcd_write_4bits(cmd >> 4); // Send higher nibble
lcd_write_4bits(cmd & 0x0F); // Send lower nibble
}

void lcd_data(unsigned char data) {
RS = 1; // Data mode
lcd_write_4bits(data >> 4); // Send higher nibble
lcd_write_4bits(data & 0x0F); // Send lower nibble
}

void lcd_write_4bits(unsigned char data) {
D4 = (data >> 0) & 1;
D5 = (data >> 1) & 1;
D6 = (data >> 2) & 1;
D7 = (data >> 3) & 1;

EN = 1; // Enable pulse
delay;
EN = 0; // Disable pulse
}

void print(unsigned char *s) {
while (*s) {
lcd_data(*s++);
}
}

void adc_init() {
ADCON0 = 0x41; // ADCON0: ADON = 1 (ADC enabled), Channel 0 (AN0)
ADCON1 = 0x80; // ADCON1: Right Justified, A/D Port Configuration Bits
}

unsigned int read_adc() {
__delay_ms(2); // Acquisition time
GO_nDONE = 1; // Start conversion
while (GO_nDONE); // Wait for conversion to finish
return (ADRESH << 8) + ADRESL; // Combine 8-bit high and low registers
}

void display_temperature(unsigned int temp) {
lcd_cmd(0x8C); // Set cursor to position to display temperature
lcd_data((temp / 100) + 48); // Hundreds place
lcd_data(((temp / 10) % 10) + 48); // Tens place
lcd_data((temp % 10) + 48); // Units place
lcd_data(0xDF); // Degree symbol
lcd_data('C'); // 'C' for Celsius
}

Explanation:

  1. LCD Initialization: The Lcd_Init() function initializes the 16x2 LCD in 4-bit mode. It sets up the display to show two lines and hides the cursor.
  2. ADC Setup: The ADC_Init() function configures the ADC module on the PIC16F877A to read analog signals from the temperature sensor (LM35) connected to AN0 (RA0).
  3. ADC Conversion: The ADC_Read() function reads the analog value from the sensor, converts it to a digital value (10-bit resolution), and returns the result.
  4. Displaying Temperature: The temperature data is formatted using the sprintf() function and displayed on the LCD using Lcd_Write_String().

 Video Demonstration

The following video shows how to interface 16x2 LCD with the PIC16F877A microcontroller and how the temperature is read from LM35 temperature sensor and displayed on the LCD.
 


Conclusion:

Interfacing an LCD with the PIC16F877A to display sensor data is a simple yet powerful way to monitor environmental or system conditions in real-time. By reading the analog data from a sensor and converting it to a human-readable form, you can create interactive projects for various applications like temperature monitoring, voltage measurement, or other sensor-based systems.

With the versatility of the PIC16F877A and ease of using LCDs, this method is great for many beginner and intermediate electronics projects.

Further Reading:

Post a Comment

Previous Post Next Post