PIC16F877A Ultrasonic Sensor Interface: A Step-by-Step Guide

by Marwen Maghrebi

In this article, we explore how to interface an ultrasonic sensor with the PIC16F877A microcontroller for precise distance measurement.

Features of PIC16F877A Ultrasonic Sensor Interface project"

Things used in this project

Software apps and online services:

1- MPLAB

2- Proteus 8

Interfacing HC-SR04 Ultrasonic Sensor with PIC16F877A: Overview and Project Guide

In this project, we will explore how to interface an ultrasonic sensor with the PIC16F877A microcontroller to achieve accurate distance measurement, perfect for embedded systems requiring reliable proximity sensing.

 HC-SR04 Ultrasonic Sensor Overview

Ultrasonic ranging module HC-SR04 offers non-contact distance measurement from 2 cm to 400 cm with an accuracy of 3 mm. Featuring ultrasonic transmitters, receivers, and a control circuit, it calculates distances based on the time interval between the transmitted ultrasonic waves and their echoes. Operating at 5V DC, it is highly efficient, compact, and suitable for applications requiring precise and reliable distance sensing.
If you’d like to learn more about this sensor and explore additional projects using other microcontrollers, check out the article STM32 Ultrasonic Sensor.

Overview of HC-SR04 Ultrasonic Sensor

Project : Interfacing HC-SR04 Ultrasonic Sensor with PIC Microcontroller

This project demonstrates how to interface the HCSR04 ultrasonic sensor with the PIC16F877A microcontroller to measure distance. The setup uses UART communication to transmit the measured distance to a connected terminal. With its accurate ranging capability, the HC-SR04 is perfect for proximity sensing in embedded systems.

Configuration and Definitions

This section includes the configuration bits, pin definitions, constants, and function prototypes to set up the PIC16F877A microcontroller and ultrasonic sensor.

#include <xc.h>
#include <stdint.h>
#include <stdio.h>

// Configuration bits
#pragma config FOSC = HS        // High-Speed Crystal
#pragma config WDTE = OFF       // Watchdog Timer disabled
#pragma config PWRTE = ON       // Power-up Timer enabled
#pragma config BOREN = ON       // Brown-out Reset enabled
#pragma config LVP = OFF        // Low Voltage Programming disabled
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection disabled
#pragma config WRT = OFF        // Flash Program Memory Write disabled
#pragma config CP = OFF         // Flash Program Memory Code Protection disabled

#define _XTAL_FREQ 20000000     // 20 MHz oscillator frequency

// Pin Definitions
#define TRIG_PIN RB0            // Trigger pin connected to RB0
#define ECHO_PIN RB1            // Echo pin connected to RB1
#define TRIG_PIN_DIR TRISB0     // Direction register for TRIG_PIN
#define ECHO_PIN_DIR TRISB1     // Direction register for ECHO_PIN

// Constants
#define US_ROUNDTRIP_CM 145      // Microseconds for sound to travel 1 cm (adjust for calibration)

// Function Prototypes
void initialize_uart(void);
void uart_send_string(const char* str);
void uart_send_byte(uint8_t data);
void initialize_pins(void);
uint16_t measure_distance(void);

// UART Buffer
char uart_buffer[32];

UART Initialization and Communication

This section handles UART initialization and functions for sending data over UART.

void initialize_uart(void) {
    TRISC6 = 0;    // TX pin as output
    TRISC7 = 1;    // RX pin as input
    
    SPBRG = 129;   // Baud rate set for 9600 with 20MHz crystal
    BRGH = 1;      // High-speed baud rate
    SYNC = 0;      // Asynchronous mode
    SPEN = 1;      // Enable serial port
    TXEN = 1;      // Enable transmission
    CREN = 1;      // Enable reception
}

void uart_send_byte(uint8_t data) {
    while (!TXIF);  // Wait for transmit buffer to be empty
    TXREG = data;   // Send the byte
}

void uart_send_string(const char* str) {
    while (*str) {
        uart_send_byte(*str++);
    }
}

Ultrasonic Sensor Initialization and Main Logic

This section includes functions to initialize pins, measure distance, and the main logic for continuous distance measurement.

void initialize_pins(void) {
    TRIG_PIN_DIR = 0;   // Set TRIG_PIN as output
    ECHO_PIN_DIR = 1;   // Set ECHO_PIN as input
    TRIG_PIN = 0;       // Ensure trigger pin is low initially
}

uint16_t measure_distance(void) {
    uint16_t pulse_duration = 0;
    
    // Generate 10s trigger pulse
    TRIG_PIN = 1;
    __delay_us(10);
    TRIG_PIN = 0;
    
    // Wait for echo pin to go high
    while (!ECHO_PIN);  // Wait for rising edge
    
    // Start Timer1
    TMR1H = 0;
    TMR1L = 0;
    TMR1ON = 1;  // Start Timer1
    
    // Wait for echo pin to go low
    while (ECHO_PIN);  // Wait for falling edge
    
    // Stop Timer1
    TMR1ON = 0;
    
    // Calculate pulse duration
    pulse_duration = ((uint16_t)TMR1H << 8) | TMR1L;
    
    // Convert pulse duration to distance in cm
    return pulse_duration / US_ROUNDTRIP_CM;
}

void main(void) {
    uint16_t distance;
    
    // Initialize peripherals
    initialize_pins();
    initialize_uart();
    
    // Timer1 configuration
    T1CON = 0x10;  // Prescaler 1:2, internal clock (Fosc/4)
    
    while (1) {
        distance = measure_distance();
        
        // Send distance over UART
        sprintf(uart_buffer, "Distance: %ucm\r\n", distance);
        uart_send_string(uart_buffer);
        
        __delay_ms(500);  // Delay before next measurement
    }
}

Proteus Configuration :

  • Open Proteus & Create New Project and click next
  • Click on Pick Device
  • Search for PIC16F877A & SRF04
  • Click on Virtual Instruments Mode then choose VIRTUAL TERMINAL & OSCILLOSCOPE
  • Click on Terminal Mode then choose (DEFAULT & POWER & GROUND)
  • finally make the circuit below and start the simulation
Circuit design for PIC16F877A Ultrasonic Sensor Interface in Proteus simulation

That’s all!

If you have any questions or suggestions don’t hesitate to leave a comment below

You Might Also Like

Leave a Comment


Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?
-
00:00
00:00
Update Required Flash plugin
-
00:00
00:00