HC-SR04 Distance Measurement using 8051 Timer Gate Mode

Simulating ultrasonic ranging in Proteus with an 80C52 microcontroller requires precise timing to capture the ECHO pulse duration. This implementation utilizes a crystal frequency of 11.0592 MHz and leverages the hardware GATE control feature of the 8051 timers to measure the high-level duration of the pulse without CPU-intensive polling.

Measurement Principle

The HC-SR04 sensor triggers a measurement when a pulse of at least 10 microseconds is applied too the TRIG pin. Following this, the sensor emits eight 40 kHz ultrasonic bursts. The ECHO pin transitions to a high state at the start of the transmission and returns to low once the reflected signal is detected. The duration of this high signal represents the total travel time of the sound wave.

Efficient Pulse Capture with Hardware Gating

Instead of busy-waiting for the ECHO pin to toggle, which wastes CPU cycles, the 8051 Timer 0 can be configured in GATE mode. When the GATE bit (TMOD.3) is set, Timer 0 only increments if the TR0 bit is high AND the INT0 (P3.2) pin is high. By connecting the ECHO signal to P3.2 and configuring an external interrupt for the falling edge, we can accurately capture the pulse duration in hardware.

Hardware Logic Implementation

The following code demonstrates how to initialize the measurement and process the timing results using interrupts.

#include <reg52.h>
#include <intrins.h>

sbit HC_TRIG = P2^7;
sbit HC_ECHO = P3^2; // Connected to INT0

unsigned int capture_ticks = 0;
bit measure_ready = 0;
bit pulse_active = 0;

// External Interrupt 0 handles the end of the ECHO pulse
void echo_falling_edge_isr() interrupt 0 {
    TR0 = 0; // Stop Timer 0
    capture_ticks = (TH0 << 8) | TL0;
    measure_ready = 1;
    EX0 = 0; // Disable interrupt until next trigger
}

// Timer 2 controls the polling interval (approx. 200ms)
void refresh_timer_isr() interrupt 5 {
    static unsigned char tick_count = 0;
    TF2 = 0;
    if (++tick_count >= 20) {
        tick_count = 0;
        pulse_active = 0; 
        TR2 = 0;
    }
}

void trigger_ultrasonic() {
    if (pulse_active) return;

    // Reset Timer 0 state
    TR0 = 0;
    TMOD &= 0xF0; 
    TMOD |= 0x09; // Mode 1 (16-bit), GATE enabled
    TH0 = 0; 
    TL0 = 0;

    // Prepare External Interrupt 0 for falling edge
    IT0 = 1;
    IE0 = 0;
    EX0 = 1;

    // Start interval timer (Timer 2)
    T2CON = 0;
    RCAP2H = 0xDC; RCAP2L = 0x00; // 10ms at 11.0592MHz
    TH2 = 0xDC; TL2 = 0x00;
    ET2 = 1;
    TR2 = 1;

    // Fire Trigger Pulse
    HC_TRIG = 1;
    _nop_(); _nop_(); _nop_(); _nop_(); // Minimal delay
    HC_TRIG = 0;

    TR0 = 1; // Timer 0 starts when ECHO goes high via GATE
    pulse_active = 1;
    measure_ready = 0;
}

void main() {
    unsigned int raw_val;
    float cm_dist;
    
    // UART and Global Interrupt setup
    EA = 1;

    while(1) {
        trigger_ultrasonic();
        
        if (measure_ready) {
            // Distance calculation logic:
            // Each tick = 12 / 11059200 Hz ≈ 1.085 us
            // Speed of sound factor ≈ 58 us/cm
            cm_dist = ((float)capture_ticks * 1.085f) / 58.0f;
            measure_ready = 0;
            // Result can now be sent to display or UART
        }
    }
}

Calculation and Scaling

With a crystal frequency of 11.0592 MHz, one machine cycle takes approximately 1.085 microseconds. To convert the timer ticks into centimeters, the formula applied is (ticks * 1.085) / 58. The constant 58 is derived from the speed of sound at standard temperature (approx. 340m/s), where 1 centimeter of distance requires a round-trip time of 58 microseconds. This hardware-gated approach ensures high accuracy while minimizing the impact on other system tasks during the measurement window.

Tags: 8051 microcontroller HC-SR04 proteus Embedded Systems

Posted on Fri, 16 Oct 2026 16:00:45 +0000 by BittenApple