
Project: Digital Counter using PIC16F877A and 16×2 LCD
1. Introduction
This project demonstrates how to interface a 16×2 LCD with a PIC16F877A microcontroller and implement a simple digital counter controlled by a push button. When the button is pressed, the count increments and is displayed on the LCD.
Real-world Applications:
- Digital tally counters
- Event counting in industrial applications
- Simple user input interface for embedded systems
2. Learning Objectives
By completing this project, you will learn:
- How to interface a 16×2 LCD with a PIC microcontroller
- How to configure GPIO pins as digital inputs and outputs
- How to implement button debouncing in firmware
- How to program in MikroC for PIC
3. Components Required
- PIC16F877A microcontroller
- 16×2 LCD Display
- Push button switch
- 10kΩ Potentiometer (for LCD contrast control)
- 4.7kΩ Pull-down resistor (for push button)
- Crystal Oscillator 20MHz
- 2x 22pF Capacitors
- Power supply (5V DC)
- Breadboard & Jumper wires
4. Circuit Diagram Description
- The 16×2 LCD is connected to the PORTD of the PIC16F877A (D4-D7 for data, RS and E for control signals).
- The push button is connected to PORTB.0 with a pull-down resistor to ensure a stable LOW state when not pressed.
- A 10kΩ potentiometer is connected to the VEE pin of the LCD to control contrast.
- A 20MHz crystal oscillator is connected to OSC1 and OSC2 with 22pF capacitors for stable clock operation.
5. Code Implementation (MikroC for PIC)
#include <built_in.h>
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
unsigned int count = 0; // Counter variable
void main() {
TRISB0_bit = 1; // Set RB0 as input (button)
TRISD = 0x00; // Set PORTD as output (LCD)
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD screen
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn off cursor
Lcd_Out(1, 1, "Counter:");
while (1) {
if (RB0_bit == 1) { // If button is pressed
Delay_ms(200); // Debouncing delay
if (RB0_bit == 1) {
count++; // Increment counter
Lcd_Out(2, 1, " "); // Clear previous count
Lcd_Out(2, 1, IntToStr(count)); // Display new count
while(RB0_bit == 1); // Wait until button is released
}
}
}
}
6. Troubleshooting Tips
Common Issues & Solutions
- LCD displays garbage characters
- Possible Cause: Incorrect contrast setting
- Solution: Adjust 10kΩ potentiometer
- LCD is blank
- Possible Cause: Improper LCD connections
- Solution: Check VCC, GND, and control lines
- Counter not incrementing
- Possible Cause: Button bouncing issue
- Solution: Increase debounce delay
- Microcontroller not working
- Possible Cause: Clock not oscillating
- Solution: Check crystal and capacitors
- Unexpected resets
- Possible Cause: Power fluctuations
- Solution: Use capacitor (100nF) across VCC and GND
7. Extensions & Further Improvements
- Add a reset button to reset the count
- Implement EEPROM storage to save count even after power loss
- Add a buzzer for audio feedback when the button is pressed
- Interface with a seven-segment display instead of LCD
- Use an interrupt instead of polling for button press
This project provides a solid foundation for working with PIC microcontrollers, LCD interfacing, and push-button inputs. Keep experimenting and improving your design!