蝙蝠和某些海洋动物都能够利用高频率的声音进行回声定位或信息交流。它们能通过口腔或鼻腔把从喉部产生的超声波发射出去,利用折回的声波来定向,并判定附近物体的位置、大小以及是否在移动。超声波是一种频率高于20000赫兹的声波,它的方向性好,穿透能力强,易于获得较集中的声能,在水中传播距离远,可用于测距、测速、清洗、焊接、碎石、杀菌消毒等。在医学、军事、工业、农业上有很多的应用。超声波因其频率下限大于人的听觉上限而得名。科学家们将每秒钟振动的次数称为声音的频率,它的单位是赫兹(Hz)。我们人类耳朵能听到的声波频率为20Hz-20000Hz。因此,我们把频率高于20000赫兹的声波称为“超声波”。通常用于医学诊断的超声波频率为1兆赫兹-30兆赫兹。理论研究表明,在振幅相同的条件下,一个物体振动的能量与振动频率成正比,超声波在介质中传播时,介质质点振动的频率很高,因而能量很大.在中国北方干燥的冬季,如果把超声波通入水罐中,剧烈的振动会使罐中的水破碎成许多小雾滴,再用小风扇把雾滴吹入室内,就可以增加室内空气湿度,这就是超声波加湿器的原理。如咽喉炎、气管炎等疾病,很难利用血流使药物到达患病的部位,利用加湿器的原理,把药液雾化,让病人吸入,能够提高疗效。利用超声波巨大的能量还可以使人体内的结石做剧烈的受迫振动而破碎,从而减缓病痛,达到治愈的目的。超声波在医学方面应用非常广泛,可以对物品进行杀菌消毒。
在超声波实验中常用的超声波模块是4针的SR04,也有5针的超声波模块
主要技术参数
1:使用电压:DC—5V
2:静态电流:小于2mA
3:电平输出:高 5V
4:电平输出:底 0V
5:感应角度:不大于15度
6:探测距离:2cm - 450cm
7: 高精度 可达0.2cm
8: 接线方式(上图从左到右):VCC、Trig(控制端)、Echo(接收端)、 GND
超声波传感器与单片机系统进行接口构成距离检测的硬件系统,在系统软件的控制下,单片机向位差超声波传感器发送的一个触发脉冲,位差超声波传感器被此脉冲触发后会产生一道短40 kHz的脉冲电信号,此40 kHz的脉冲电信号通过激励换能器处理以后,将转换成机械振动的能量,其振动频率约在20 kHz以上,由此形成了超声波,该信号经锥形"辐射口"处将超声波信号在空气中以每秒约1 130英尺的速度向外发射出去。
当发射出去的超声波信号遇到障碍物以后,立即被反射回来。接收器接收到反射回来的超声波信号后,通过其内部转换,将超声波变成微弱的电振荡,并将信号进行放大,就可得到所需的脉冲信号,此脉冲信号再返回给单片机,表示回波被探测,这个脉冲宽度就是对应于爆裂回声返回到传感器所需时间,其时序如图所示。
HC-SR04超声波测距模块具有测距距离精确,能和SRF05,SRF02等超声波测距相媲美,测量距离 2cm ~ 450cm (实测:6cm ~ 330cm)。
工作原理
1)采用IO触发测距,给至少10us的高电平信号。
2)模块自动发送8个40KHz的方波,自动检测是否有信号返回。
3)有信号返回,通过模块IO输出高电平,高电平持续时间就是超声波从发射到返回的时间。只需要提供一个10uS以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。
公式:
1、此模块不宜带电连接,若要带电连接,则先让模块的GND端先连接,否则会影响模块的正常工作。
2、测距时,被测物体的面积不少于05平方米且平面尽量要求平整,否则影响测量的结果。
按照超声波时序图,发送10us触发触发信号,并记录回响信号的时间间隔
unsigned int RunOnce()
{
unsigned int time;
//10us高电平发送触发信号
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
//等待高电平信号接收
while(!Echo);
//T0清0重新计数(高电平持续时间)
TH0 = 0;
TL0 = 0;
TR0 = 1;
//等待高电平信号接收结束
while(Echo);
//关闭T0计数
TR0 = 0;
//高电平时间赋值,单位us
time = TH0*256 + TL0; // TH0<<8 | TL0
TH0 = 0;
TL0 = 0;
return time;
}
10us的延时用定时器0来完成(定时器0配置详情见定时器中断)
// 延时10us
void Delay10us()
{
TMOD |= 0x01; //16位定时器/计数器,TH0、TH1全用
TH0 = 0xFF;
TL0 = 0xF6;
TR0 = 1; //TR0为1时允许T0开始计数
while(!TF0); //当T0溢出时退出while
TF0 = 0; //TF0置0
}
将超声波回响信号时间间隔转换成距离
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017; //cm
return distance;
}
在main函数中做函数调用,完整demo如下
#include
#include
sbit Trig = P0^0;
sbit Echo = P0^1;
//毫秒延时函数
void delay_ms(unsigned int t)
{
unsigned char i, j, z;
for(z = t;z>0;z--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
// 延时10us
void Delay10us()
{
TMOD |= 0x01; //16位定时器/计数器,TH0、TH1全用
TH0 = 0xFF;
TL0 = 0xF6;
TR0 = 1; //TR0为1时允许T0开始计数
while(!TF0); //当T0溢出时退出while
TF0 = 0; //TF0置0
}
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017; //cm
return distance;
}
unsigned int RunOnce()
{
unsigned int time;
//10us高电平发送触发信号
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
//等待高电平信号接收
while(!Echo);
//T0清0重新计数(高电平持续时间)
TH0 = 0;
TL0 = 0;
TR0 = 1;
//等待高电平信号接收结束
while(Echo);
//关闭T0计数
TR0 = 0;
//高电平时间赋值,单位us
time = TH0*256 + TL0; // TH0<<8 | TL0
TH0 = 0;
TL0 = 0;
return time;
}
void main()
{
unsigned int time = 0;
float distance;
while(1)
{
time = RunOnce(); //计算超声波测距时 传感器接收到高电平的时间
distance = GetDistance(time);
}
}
用流水灯点亮个数来“显示”超声波距离
#include
#include
sbit Trig = P0^0;
sbit Echo = P0^1;
//毫秒延时函数
void delay_ms(unsigned int t)
{
unsigned char i, j, z;
for(z = t;z>0;z--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
// 延时10us
void Delay10us()
{
TMOD |= 0x01; //16位定时器/计数器,TH0、TH1全用
TH0 = 0xFF;
TL0 = 0xF6;
TR0 = 1; //TR0为1时允许T0开始计数
while(!TF0); //当T0溢出时退出while
TF0 = 0; //TF0置0
}
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017;
return distance;
}
unsigned int RunOnce()
{
unsigned int time;
//10us高电平发送触发信号
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
//等待高电平信号接收
while(!Echo);
//T0清0重新计数(高电平持续时间)
TH0 = 0;
TL0 = 0;
TR0 = 1;
//等待高电平信号接收结束
while(Echo);
//关闭T0计数
TR0 = 0;
//高电平时间赋值,单位us
time = TH0*256 + TL0; // TH0<<8 | TL0
TH0 = 0;
TL0 = 0;
return time;
}
void RunLED(unsigned int LEDnum)
{
unsigned int RunNum = LEDnum;
switch(RunNum){
case 0:
P1 = 0x00;
delay_ms(20);
P1 = 0xff;
delay_ms(20);
break;
case 1: P1 = 0xfe;
break;
case 2: P1 = 0xfc;
break;
case 3: P1 = 0xf8;
break;
case 4: P1 = 0xf0;
break;
case 5: P1 = 0xe0;
break;
case 6: P1 = 0xc0;
break;
case 7: P1 = 0x80;
break;
case 8: P1 = 0x00;
break;
default:
P1 = 0x00;
break;
}
}
void main()
{
unsigned int time = 0;
float distance;
while(1)
{
time = RunOnce();
distance = GetDistance(time);
RunLED((int)(distance/10));
}
}
按超声波不同间隔使蜂鸣器叫出不同频率
#include
#include
#define ON 0
#define OFF 1
sbit Trig = P0^0;
sbit Echo = P0^1;
//毫秒延时函数
void delay_ms(unsigned int t)
{
unsigned char i, j, z;
for(z = t;z>0;z--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
// 延时10us
void Delay10us()
{
TMOD |= 0x01; //16位定时器/计数器,TH0、TH1全用
TH0 = 0xFF;
TL0 = 0xF6;
TR0 = 1; //TR0为1时允许T0开始计数
while(!TF0); //当T0溢出时退出while
TF0 = 0; //TF0置0
}
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017;
return distance;
}
unsigned int RunOnce()
{
unsigned int time;
//10us高电平发送触发信号
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
//等待高电平信号接收
while(!Echo);
//T0清0重新计数(高电平持续时间)
TH0 = 0;
TL0 = 0;
TR0 = 1;
//等待高电平信号接收结束
while(Echo);
//关闭T0计数
TR0 = 0;
//高电平时间赋值,单位us
time = TH0*256 + TL0; // TH0<<8 | TL0
TH0 = 0;
TL0 = 0;
return time;
}
void main()
{
unsigned int time = 0;
float distance;
while(1)
{
time = RunOnce();
distance = GetDistance(time);
if(distance <= 10.0){
BUZZER = ON;
delay_ms(50);
BUZZER = OFF;
delay_ms(50);
}
else if((10.0 < distance) && (distance <= 20.0)){
BUZZER = ON;
delay_ms(100);
BUZZER = OFF;
delay_ms(100);
}
else if((20.0 < distance) && (distance <= 50.0)){
BUZZER = ON;
delay_ms(160);
BUZZER = OFF;
delay_ms(160);
}
}
}