Hi guys… In our previous tutorial, we have seen ADC0808 interfacing with 8051. Today we are going to see Ultrasonic Sensor Interfacing with 8051.
Table of Contents
Ultrasonic Sensor Interfacing with 8051
Suggestion to read
Before we will start I would suggest you to read these topics. Then you can understand this strongly. If you already know, please go ahead.
Hardware Required
We have our own EmbeTronicX store called ChipTronicX. You can purchase the hardware from there.
- 8051 Microcontroller
- Ultrasonic Sensor [HC-SR04]
- LCD Module (To print the Distance)
Measuring Echo Pulse
The measurement of Echo pulse can be done with the help of external Interrupt and Timer modules of 8051 Microcontroller. In capture mode when the external pulse is fed to the interrupt the timer starts counting and will stop only after the state of the pulse is changed. Steps to follow to program controller as a capture device.
- Initialize Timer0 module as a 16-bit timer with Gate bit as 1.
- Making Gate bit as 1 will transfer the control of timer to external interrupt pin INT0.
- When there is an interrupt pulse timer 0 starts counting and stops as soon as the interrupt disappears.
- The value in Timer 0 (TH0 and TL0) gives the time period or length of the pulse.
Operation
- Connect the Trigger pin of the HC-SR04 module to any I/O pins of the 8051 controllers.
- Connect the Echo pin of the module to interrupt pin INT0 of the Microcontroller.
- Send a pulse of minimal timer period 10us, this will make the Ultrasonic module to send a burst of data.
- The reflected waves will be sensed by the module and it exhibits the output in Echo pin logic high or 1 to INT0 pin of Microcontroller.
- This creates an interrupt and Timer 0 will start counting.
- When the pulse from the echo pin alters its state to logic 0 or low the timer 0 stops counting
- The length of the pulse from the echo pin is proportional to the distance at which the object is located.
- The value in the Timer 0 gives the distance of course with some simple calculations.
CALCULATION
According to the datasheet the distance can be given by the formula :
Distance in cm = Timer 0/59
Distance in inch = Timer 0/148
Connection
LCD:
- RS – P0.0
- RW – P0.1
- EN – P0.2
- Data Lines – P2
Ultrasonic Sensor:
- Trigger – P3.5
- Echo – P3.2
Code
Sending Trigger Pulse
void send_pulse(void)
{
TH0=0x00;TL0=0x00;
trig=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
trig=0;
}
Here I’m making the timer value to zero. Then we are giving high to trigger pin (1). We have to wait for 10u Seconds. So I’m using the _nop_() function. Each -nop_() function will generate 1us. For that, we need to use intrins.h header file. Then make the trigger pin to low (0).
Distance Calculating
unsigned char ultrasonic()
{
unsigned char get;
send_pulse();
while(!echo);
while(echo);
DPH=TH0;
DPL=TL0;
TH0=TL0=0xff;
if(DPTR<38000)
get=DPTR/59;
else
get=0;
return get;
}
This is the full function to calculate the distance.
- First, I’m sending a trigger pulse.
- Then waiting until that echo pin goes high (1). In this stage, the timer would start.
- Again I’m waiting until that echo goes low (0). If it goes to zero, the timer will OFF.
- Then I’m taking value from the timer register. Here I’m using DPTR Register. Because in 8051 DPTR Register size is 16bits. so I’m using that.
- Then using the formula, I can calculate the Distance.
Full Code
#include<reg51.h>
#include<intrins.h>
#define lcd_data P2
sfr16 DPTR=0x82;
sbit trig=P3^5;
sbit echo=P3^2;
unsigned int range=0;
sbit rs=P0^0;
sbit rw=P0^1;
sbit en=P0^2;
void lcd_init();
void cmd(unsigned char a);
void dat(unsigned char b);
void show(unsigned char *s);
void lcd_delay();
void lcd_init()
{
cmd(0x38);
cmd(0x0e);
cmd(0x06);
cmd(0x0c);
cmd(0x80);
}
void cmd(unsigned char a)
{
lcd_data=a;
rs=0;
rw=0;
en=1;
lcd_delay();
en=0;
}
void dat(unsigned char b)
{
lcd_data=b;
rs=1;
rw=0;
en=1;
lcd_delay();
en=0;
}
void show(unsigned char *s)
{
while(*s) {
dat(*s++);
}
}
void lcd_delay()
{
unsigned int i;
for(i=0;i<=1000;i++);
}
void send_pulse(void)
{
TH0=0x00;TL0=0x00;
trig=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
trig=0;
}
unsigned char ultrasonic()
{
unsigned char get;
send_pulse();
while(!echo);
while(echo);
DPH=TH0;
DPL=TL0;
TH0=TL0=0xff;
if(DPTR<38000)
get=DPTR/59;
else
get=0;
return get;
}
void main()
{
TMOD=0x09;
TH0=TL0=0;
TR0=1;
lcd_init();
show("DIS");
P3|=(1<<2);
while(1) {
cmd(0x84);
range=ultrasonic();
dat((range/100)+48);
dat(((range/10)%10)+48);
dat((range%10)+48);
}
}
So this code will print the distance in the LCD module. You can use this module for any robot project.
In our next tutorial, we will interface the GSM module with 8051.
You can also read the below tutorials.

Embedded Software | Firmware | Linux Devic Driver | RTOS
Hi, I am a tech blogger and an Embedded Engineer. I am always eager to learn and explore tech-related concepts. And also, I wanted to share my knowledge with everyone in a more straightforward way with easy practical examples. I strongly believe that learning by doing is more powerful than just learning by reading. I love to do experiments. If you want to help or support me on my journey, consider sharing my articles, or Buy me a Coffee! Thank you for reading my blog! Happy learning!
Discover more from EmbeTronicX
Subscribe to get the latest posts sent to your email.


Hi. with which compiler did you compile this software? Keil or what?
The code doesnt work in proteus is the code correct does it show the distance
Hi,
We have not told that this code will work in proteus. This is for real hardware.
on simulating in proteus,the lcd shows only DIS.no value is shown. why it is so? please
Hi Sanitha,
I think the proteus variant of the Ultrasonic is not available. This code has been tested with the real hardware.
In interfacing diagram you use timer 0 but in program you use timer 1
is it correct?
Hi Kavita,
Thanks for commenting. In program, we did not use Timer 1. If you see there, we used TH0, TL0, TR0. So it is respected to Timer 0. And FYI we are using this P3.5 as GPIO.
why have you added 48 could you please explain the last three lines of the code.
dat((range/100)+48);
dat(((range/10)%10)+48);
dat((range%10)+48);
Hi Aparna,
Here I will explain those 3 lines. We will go one by one. Let’s assume range = 123. So we need to show 123 in Display.
Line 1:
range/100
123/100 = 1.23 = 1 (because only whole number)
If we want to print 1 then we have to convert this 1 to ASCII value. We can convert any value to ASCII value by using below method.
any value + (0x30 or 48) 48 is the decimal of 0x30. You can refer ASCII table for further information.1 + (48 or 0x30) = 49 or 0x32. (This will print as 1 in the display)
Line 2:
range/10
(123/10) = 12
(12 % 10) = 2
Conversion to ASCII (2 + 48) = 50. (This will print 2 in the display)
Line 3:
range%10
123%10 = 3
Conversion to ASCII (3 + 48) = 51. (This will print 3 in the display)
So Finally, We can show 123 in the display.
echo pin goes high (1).rt this stage timer would be start.
how you are starting the timer?? , where is the code for that ??
by interrupt ??
Hi Yashwant Rao,
When we are initializing the timer, we are setting that Gate0 bit in TMOD register (TMOD=0x09). That means timer will be controlled by hardware. In timer0, INT0 will be the control pin. When this pin goes high, timer will start. We have connected the echo pin to that INT0 (P3.2). So timer will start when that echo pin goes high. please refer timer tutorial if you have doubt. https://embetronicx.com/tutorials/microcontrollers/8051/8051-timer-counter-tutorial/