一、超声波测距的原理
超声波测距是一种常用的距离测量技术,它利用超声波的传播速度来确定物体与传感器之间的距离。其 原理基于声波的传播和回波时间的测量,通常包括以下步骤:
1. 发射超声波脉冲:传感器向目标物体发射一个超声波脉冲。这个脉冲是一种高频声波,通常在20 kHz到200 kHz的频率范围内。
2. 超声波传播:脉冲超声波在空气中以速度约343米/秒(在20摄氏度下)传播,朝着目标物体前进。
3. 回波检测:一旦超声波脉冲碰到目标物体,它会被目标物体反射回来。传感器会继续监测并记录回 波的时间。
4. 计算距离:通过测量超声波从发射到接收的时间间隔(也称为回波时间),可以根据声波的速度和 时间间隔来计算目标物体与传感器之间的距离。这通常使用以下速度-时间-距离公式完成: 距离 = (声速 × 回波时间)/2 其中,声速通常取343米/秒,回波时间是发射和接收超声波之间的时间,除以2是因为回波的时间 包括了超声波从传感器到目标物体再返回传感器的总时间。
二、超声波测距的常用场合
超声波测距在各种不同领域和应用中都有广泛的使用,包括以下一些常见的场合:
1. 工业自动化:超声波传感器常用于工业自动化中,用于测量物体的距离和位置,以监控生产线上的 物体或机器人的位置。它们可以用于控制机器人的运动、检测物体的存在或测量液位。
2. 障碍物检测:超声波传感器被广泛用于车辆和机器人中,以检测周围环境中的障碍物。这在自动驾 驶汽车、智能洗衣机、无人机和工业机器人等应用中非常重要。
3. 距离测量:用于测量物体与传感器之间的距离,例如在仓储管理、建筑测量和地质勘探中。
4. 液位测量:用于测量液体或粉体的液位,例如在油罐、水池、粮仓和药品制造中。
5. 游戏和娱乐:一些玩具、游戏和娱乐设备中使用超声波传感器来实现互动和距离测量功能。
6. 医疗设备:用于医疗设备中,例如超声波图像设备(如超声波扫描仪)用于医学成像和超声波测距 传感器用于监测患者的距离和位置。
7. 安防系统:超声波传感器可用于入侵检测、人员计数和监控系统,以提高安全性。 8. 非接触控制:超声波传感器还用于非接触控制,例如手势识别、触摸屏技术和自动门开关。
三、超声波测距模块的使用使用方法
模块上有一个发射端和接收端,并且模块上自带震荡电路,可以自己产生超 声波发射并接收然后计算时间差。
可以看到,超声波模块有4个引脚,分别为Vcc、Trig、Echo、GND,这四个引脚的功能分别如下
VCC:接 VCC 电源(直流 3V-5.5V)
Trig:接外部电路的 Trig 端,向此管脚输入一个 10uS 以上的高电平,可触发模块测距
Echo:接外部电路的 Echo 端,当测距结束时,此管脚会输出一个高电平,电平宽度为超 声波往返时间 之和
GND:接外部电路的地 单片机需要做的就是产生一个触发信号,然后检测输出回响信号的脉 冲宽度即可,脉冲宽度的检测可以使用定时器来实现。
我设计的功能有如下:
基础部分:
-
通过数码管实时显示当前的测试距离,显示单位默认为CM
-
每按一下K1按键,显示单位在CM和MM之间进行切换
-
最大测量距离为1米,超出后数码管显示错误代码“E00”
发挥部分:
-
测试距离小于10CM时,蜂鸣器发出“嘀嘀嘀提示声”
-
支持的最大测量距离为2米,并且数码管显示稳定,超出测试距离后显示“E00”
一、实验代码
1.硬件连接
触发信号和检测脉宽使用通用IO口即可, 超声波模块的TRIG引脚和51单片机的P21连接,ECHO引脚和 P20连接,VCC引脚和开发板的5V连接,GND引脚和开发板的GND引脚连接。
注意:TRIG和ECHO的作用是和超声波模块进行交互,也就是告诉超声波模块什么时候启动以及接 收超声波模块返回的信息。选择单片机引脚的时候,要查看原理图是否有引脚冲突。例如这个任务 中需要用到数码管,P22、P23、P24及P00-P07已经用来控制数码管显示了,所以连接超声波模 块的时候就要避开这些引脚。
2.代码编写
1.定义与超声波模块连接的引脚
sbit ECHO = P2^0;
sbit TRIG = P2^1;
2. 提供一个大于10us的脉冲信号给TRIG引脚,用来启动超声波模块开始测距,这里我们定义一个名 为SR04_Start()的函数,该函数的功能就是在TRIG引脚上发出一个大于10us的脉冲
void SR04_Start()
{
TRIG = 1; //输出高电平
Delay_us(10); //延时10us,也就是产生10us的高电平
TRIG = 0; //输出低电平
}
3. 设置定时工作模式,因为是为了计算脉冲长度,所以为了方便计算,TH0和TL0都设置为0即可。
TMOD|=0x01; //定时器工作在方式1
TH0=0;
TL0=0;
5. 测量超声波模块返回的脉冲宽度。测量流程如图2-6-5所示。
int SR04_GetDistance()
{
double time;
TH0 = 0;
TL0 = 0;//让下一次测距,时间为0开始
//启动测距
SR04_Start();
//由低电平跳转高电平,表示返回脉冲的开始
while(ECHO==0);
TR0 = 1; //启动定时器,开始计数
//由高电平跳转低电平,表示脉冲结束
while(ECHO==1);
TR0 = 0; //停止定时器
//计算出中间经过多少时间
time=(TH0*256+TL0)*1.085;
//距离等于时间*速度(340m/s)/2 =(34000cm/s)/2 = (34cm/ms)/2 =
(0.034cm/us)/2
return (time*0.017);
}
整体代码为:
#include "regx52.h"
#include "SMG.h"
#include "delay.h"
sbit KEY1 = P3^1;
sbit KEY2 = P3^0;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;
sbit ECHO = P2^0; //检测超声波返回脉宽
sbit TRIG = P2^1; //触发超声波开始测距
sbit BEEP = P2^5;
int unit = 0; //单位 0 表示cm 1 表示mm
void SR04_Start()
{
TRIG = 1; //输出高电平
Delay_us(10); //延时10us,也就是产生10us的高电平
TRIG = 0; //输出低电平
}
int SR04_GetDistance()
{
double time;
TH0 = 0;
TL0 = 0;//让下一次测距,时间为0开始
//启动测距
SR04_Start();
//由低电平跳转高电平,表示返回脉冲的开始
while(ECHO == 0);
TR0 = 1; //启动定时器,开始计数
//由高电平跳转低电平,表示脉冲结束
while(ECHO == 1);
TR0 = 0; //停止定时器
//计算出中间经过多少时间
time=(TH0*256+TL0)*1.085;
//距离等于时间*速度(340m/s)/2 =(34000cm/s)/2 = (34cm/ms)/2 =(0.034cm/us)/2
return (time*0.017);
}
unsigned char key_sacn()
{
static unsigned char key_press_state = 0;//表示按键按下状态 0 表示按键没有按下 1 表示按键被按下
//如果没有按键被按下
if(key_press_state == 0)
{
//如果KEY1-KEY4任何一个被按下
if(KEY1 == 0 || KEY2 == 0 ||KEY3 == 0 || KEY4 == 0)
{
//延时10ms
Delay_ms(10);
//逐个判断,确定具体是哪一个被按下
if(KEY1 == 0)
{
key_press_state = 1;
return 1;
}
if(KEY2 == 0)
{
key_press_state = 1;
return 2;
}
if(KEY3 == 0)
{
key_press_state = 1;
return 3;
}
if(KEY4 == 0)
{
key_press_state = 1;
return 4;
}
}
}
//KEY1-KEY4全部松开,才能恢复状态
if(KEY1 == 1 && KEY2==1 && KEY3 ==1 && KEY4 ==1)
{
key_press_state = 0;
}
return 0;
}
void Beep()
{
int i = 200;
while(i--)
{
BEEP =! BEEP;
Delay_us(50);
}
}
void main()
{
//初始化定时器
TMOD|=0x01; //定时器工作在方式1
TH0 = 0;
TL0 = 0;
TRIG = 0; //默认状态下,TRIG输出低电平
while(1)
{
int distance =0;
//1.检测哪个按键被按下
unsigned char key = key_sacn();
if(key == 1)
{
if(unit == 0)
unit = 1;
else
unit = 0;
}
distance = SR04_GetDistance(); //得到的单位是CM
if(distance < 10)
{
Beep();
}
if(distance > 120) //距离大于1.2m
{
//显示E00
Show_E00();
}
else //小于1.2m就正常显示
{
if(unit == 0) //如果显示单位是CM
Show_Num(distance);
else //显示单位是mm,乘以10后在显示
Show_Num(distance*10);
}
}
}