51单片机学习笔记7 -- 超声波测距

发布者:CreativeDreamer最新更新时间:2022-07-08 来源: csdn关键字:51单片机  超声波测距 手机看文章 扫描二维码
随时随地手机看文章

1.超声波

蝙蝠和某些海洋动物都能够利用高频率的声音进行回声定位或信息交流。它们能通过口腔或鼻腔把从喉部产生的超声波发射出去,利用折回的声波来定向,并判定附近物体的位置、大小以及是否在移动。超声波是一种频率高于20000赫兹的声波,它的方向性好,穿透能力强,易于获得较集中的声能,在水中传播距离远,可用于测距、测速、清洗、焊接、碎石、杀菌消毒等。在医学、军事、工业、农业上有很多的应用。超声波因其频率下限大于人的听觉上限而得名。科学家们将每秒钟振动的次数称为声音的频率,它的单位是赫兹(Hz)。我们人类耳朵能听到的声波频率为20Hz-20000Hz。因此,我们把频率高于20000赫兹的声波称为“超声波”。通常用于医学诊断的超声波频率为1兆赫兹-30兆赫兹。理论研究表明,在振幅相同的条件下,一个物体振动的能量与振动频率成正比,超声波在介质中传播时,介质质点振动的频率很高,因而能量很大.在中国北方干燥的冬季,如果把超声波通入水罐中,剧烈的振动会使罐中的水破碎成许多小雾滴,再用小风扇把雾滴吹入室内,就可以增加室内空气湿度,这就是超声波加湿器的原理。如咽喉炎、气管炎等疾病,很难利用血流使药物到达患病的部位,利用加湿器的原理,把药液雾化,让病人吸入,能够提高疗效。利用超声波巨大的能量还可以使人体内的结石做剧烈的受迫振动而破碎,从而减缓病痛,达到治愈的目的。超声波在医学方面应用非常广泛,可以对物品进行杀菌消毒。

在这里插入图片描述

2.超声波模块

2.1 模块参数

在超声波实验中常用的超声波模块是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


2.2 模块原理图


2.3 超声波位差测距

超声波传感器与单片机系统进行接口构成距离检测的硬件系统,在系统软件的控制下,单片机向位差超声波传感器发送的一个触发脉冲,位差超声波传感器被此脉冲触发后会产生一道短40 kHz的脉冲电信号,此40 kHz的脉冲电信号通过激励换能器处理以后,将转换成机械振动的能量,其振动频率约在20 kHz以上,由此形成了超声波,该信号经锥形"辐射口"处将超声波信号在空气中以每秒约1 130英尺的速度向外发射出去。

当发射出去的超声波信号遇到障碍物以后,立即被反射回来。接收器接收到反射回来的超声波信号后,通过其内部转换,将超声波变成微弱的电振荡,并将信号进行放大,就可得到所需的脉冲信号,此脉冲信号再返回给单片机,表示回波被探测,这个脉冲宽度就是对应于爆裂回声返回到传感器所需时间,其时序如图所示。

2.4 模块特征

HC-SR04超声波测距模块具有测距距离精确,能和SRF05,SRF02等超声波测距相媲美,测量距离 2cm ~ 450cm (实测:6cm ~ 330cm)。


工作原理

1)采用IO触发测距,给至少10us的高电平信号。

2)模块自动发送8个40KHz的方波,自动检测是否有信号返回。

3)有信号返回,通过模块IO输出高电平,高电平持续时间就是超声波从发射到返回的时间。只需要提供一个10uS以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。

公式:


uS/58=厘米

或 uS/148=英寸

或 距离=高电平时间*声速(340M/S) /2


建议测量周期为60ms以上,以防止发射信号对回响信号的影响。

1、此模块不宜带电连接,若要带电连接,则先让模块的GND端先连接,否则会影响模块的正常工作。

2、测距时,被测物体的面积不少于05平方米且平面尽量要求平整,否则影响测量的结果。


3.超声波测距编程

按照超声波时序图,发送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);


}

}


3.1 超声波+流水灯

用流水灯点亮个数来“显示”超声波距离


#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));

}

}


3.2 超声波+蜂鸣器

按超声波不同间隔使蜂鸣器叫出不同频率


#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);

}

}

}

关键字:51单片机  超声波测距 引用地址:51单片机学习笔记7 -- 超声波测距

上一篇:51单片机学习笔记6 -- 定时器中断
下一篇:51单片机学习笔记8 -- OLED显示(SPI)

推荐阅读最新更新时间:2024-11-09 18:19

51单片机~DS1302时钟,SPI总线原理
(一)说明: (二)SPI总线原理: (三)日历时钟寄存器: 慢充电: BCD码: temp.h #ifndef __TEMP_H_ #define __TEMP_H_ #include reg52.h //---重定义关键词---// #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif //--定义使用的IO口--// sbit DSPORT=P3^7; //--声明全局函数--// void Delay1ms(uin
[单片机]
<font color='red'>51单片机</font>~DS1302时钟,SPI总线原理
51单片机--设置数码管的闪烁位置,便于输入数字
/* 有四个独立按键为 K1~K4,有四个数码管,可显示 0000~9999。 初始时都显示 0。 四个数码管中,有一个处于闪烁状态。闪烁的频率为 1Hz。 利用 K3、K4 可以使得闪烁的位置左右移动。 只有不停闪烁的位,才可以用 K1、K2 使其数值递增或递减。 数值的范围是 0~9。 题目连接: http://zhidao.baidu.com/question/455550887523150405.html 做而论道编写程序如下: */ #include reg52.h #include intrins.h sbit k_a = P3^1; sbit k_s = P3^3; sbit
[单片机]
<font color='red'>51单片机</font>--设置数码管的闪烁位置,便于输入数字
51单片机-带返回值的函数
1.返回值 之前我们封装的函数都是void类型无返回值的函数。随着学习的深入,我们需要把C语言的精髓学到家。 前面几讲在“function.c”中没有提及过按键的函数封装,大家也知道我们在第五章用到的按键功能函数都需要定义全局变量,这种过多的使用全局变量是编程的大忌。随着我们使用按键越来越灵活,就不是简单的让一两个变量加加减减而已了,所以现在我们要更加的去贴合嵌入式编程的方式,那么按键的使用如果用函数封装的话,需要用到函数返回值的相关知识。 2.举例 首先我们定义一个不带参数且返回值为unsigned char型的函数,函数名为“KEY4_Scan()”,里面的内容跟以前的不支持连按函数都差不多,只是我们把执行功能
[单片机]
C51单片机学习笔记(三)——按键对灯、蜂鸣器等器件的控制
1.独立按键的原理 一般的独立按键有四个脚,无论按键是否被按下,1和2总是相通的,3和4也是相通的。当按键按下时,1、2脚与3、4脚接通,按住不放则保持接通状态 按键通断过程的抖动:当按键按下时(释放时)输出的理想波形是标准的矩形波,但是,由于机械触点的弹性作用,闭合时电路不会马上稳定的接通,这中间会出现一连串的抖动,如图所示,抖动时间一般为5~10ms 按键的消抖:按键的抖动会造成一次按下被误认为多次按下,所以要进行消抖处理,一般分为硬件消抖和软件消抖,这里讨论软件消抖,方法是当单片机检测到按键闭合时,采用延时程序产生5~10ms的延时,等抖动消失后,再判断是否处于闭合状态,同理释放的时候,也要给延时。 按键给单片机
[单片机]
C<font color='red'>51单片机</font>学习笔记(三)——按键对灯、蜂鸣器等器件的控制
51单片机学习:动态数码管实验
实验名称:动态数码管实验 接线说明: 实验现象:下载程序后“数码管模块”显示01234567 注意事项: ***************************************************************************************/ #include reg52.h typedef unsigned int u16; //对系统默认数据类型进行重定义 typedef unsigned char u8; #define SMG_A_DP_PORT P0 //使用宏定义数码管段码口 //定义数码管位选信号控制脚 sbit LSA=P2^2; sbit LSB=P2^3; sbit L
[单片机]
蜂鸣器播放音乐+普中51单片机+江科大自化协
1 现象 利用蜂鸣器实现音乐播放功能,播放《天空之城》。 2 原理 (1)天空之城的乐谱 3 参考程序 3.1 主程序 #include REGX52.H #include delayms.h #include timer0.h //蜂鸣器端口定义 sbit buzzer = P2^5; //播放速度,值为四分音符的时长 #define SPEED 500 //音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号# #define P 0 #define L1 1 #define L1_ 2 #define L2 3 #define L2_ 4 #define L3 5
[单片机]
蜂鸣器播放音乐+普中<font color='red'>51单片机</font>+江科大自化协
C51单片机对共阳极数码管的控制设计
这是共阳极数码管的电路图,其中JP3接到P0口,JP3的8-1对应数码管的a-dp引脚。 共阳极数码管的编码表如下,注意a---最低位,dp---最高位: 【0---3】0xco,0xf9,0xa4,0xb0, 【4---7】0x99,0x92,0x82,0xf8, 【8---B】0x80,0x90,0x88,0x83, 【C---F】0xc6,0xa1,0x86,0x8e。 C51程序显示数字0-9: #include #define uchar unsigned char void delay(); uchar smg[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
[单片机]
C<font color='red'>51单片机</font>对共阳极数码管的控制设计
基于8051单片机的电机转速测量控制程序
以单片机8031为核心, 利用8279芯片实现按键输入和利用数码管显示所测转速,利用ADC0809将输入电压模拟量转化为数字量(实验箱内部已接好相关接口)控制电机转速的目的。然后利用DA0832将电机上的传感器配合DA0832的CKMOT接口将脉冲信号接到8031的INT0,利用外中断实现速度的测量,一次外中断会使速度计数器自动加一,利用定时器产生一秒的计时,得出一秒内速度计数器的值就可以得到电机的转速。另定时计数器每250MS产生一次定时器中断,利用中断来检测是否有新的控制信号输入,以达到实时控制转速的目的。 ORG 0000h ajmp main ORG 0003h ;外部中断0 AJMP ZS ORG 000BH
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved