专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

一款超声波测距模块运用程序

作者:佚名   来源:本站原创   点击数:  更新时间:2013年11月13日   【字体:

      本模块性能稳定,使用方便,测度距离精确。能和国外的SRF05,SRF02等超声波测距模块相媲美,且价格实惠,是你采购超声波器件的理想选择。模块高精度,盲区(2cm)超近,稳定的测距是此产品成功走向市场的有力根据!测量范围在2cm~500cm,测量精度3mm,测量时与被测物体无直接接触,能够清晰稳定地显示测量结果。由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物位测量仪等都可以通过超声波来实现。
        超声波测距器,可以应用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用于液位、井深、管道长度的测量,用于机器人控制、小车躲避障碍等场合中。小车上安装此模块配合舵机使用能控制得更方便。利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的要求。因此在移动机器人的研制上也得到了广泛的应用。
模块性能
1:使用电压:DC5V;
2:静态电流:小于2mA;
3:输出信号:电平信号,高电平5V,低电平为0V;
4:感应角度:不大于15度;
5:探测距离:2cm-500cm
6: 高精度:可达0.3cm
超声波测距模块工作原理:
(1)采用单片机IO触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
  (3)有信号返回,通过echo输出一高电平,高电平持续的时间就是超声波从发射到返回的时间。
用户通过从trig脚输入40kHz的方波信号,即用户从单片机的IO口连续发出高低电平,产生方波,方波的个数一般为10个左右;然后就可以在接收端等待高电平输出,一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,高电平的时间就是此次测距的时间,根据以下公式计算测量距离:
测试距离=(高电平时间*声速(340m/s))/2;
注意事项
1、超声波发射头向外发射60度角的超声束,因此,在探头与被测物体之间不能有其他障碍物。
2、超声波模块测得的是被测物体与探头之间的垂直距离,测量时要保持探头正对被测物体。
3、超声波测量会受环境风速、温度等的影响。
4、模块应先插好在电路板上再通电,避免产生高电平的误动作,如果产生了,重新通电方可解决。
可能出现的问题
1、由于超声波会受到被测物体不平整、反射角度、环境风速温度以及多次反射的影响,可能会带来测量数据误差增大。
2、由于超声波有测量盲区的固有特性,因此,如果近距离测量时,当测量位置发生变化而接收到的数据不变时,说明进入了测量盲区。
3、模块在测量远处物体时,如果没有测量数据返回,可能是超出测量范围,或是测量角度不对。可以适当调整测量角度。
***********************************************************************************/
/*模块高精度,盲区2cm,测量范围在2cm~500cm,测量精度3mm*/
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
unsigned char code WE0[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80};//0x40-不带点
//unsigned char code WE1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xf0,0xef,0x80}; //0-9 带点
unsigned char temp[3];
sbit RX=P3^4; //接受端,ECHO
sbit TX=P3^5; //控制端,TRIG
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
bit flag=0;
uint time=0;
uint s=0;
void delay(int xms)//延时大概x毫秒
{
int i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void start() //给至少10us的高电平,启动模块
{
TX=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
uchar count()
{
time=TH0*256+TL0;
TH0=0;
TL0=0; //清零
s=(time*1.7)/100;//厘米
return s;
}
void dispros()//数据分割
{
temp[0]=s%1000/100;//百位
temp[1]=s%1000%100/10; //十位
temp[2]=s%100%100%10; //个位
}
void display() //显示函数
{
uchar i;
if(s>=500||s<=2||flag==1) //进入盲区,溢出
{
flag=0;
s=0;
TH0=0;
TL0=0; //清零
for(i=0;i<3;i++) //显示-
{
P0=0x40;
switch(i)
{
case 0:LSA=0; LSB=0; LSC=0; break;
case 1:LSA=1; LSB=0; LSC=0; break;
case 2:LSA=0; LSB=1; LSC=0; break;
}
delay(2);
}
}
else //正常显示
{
LSA=0;LSB=0;LSC=0;
P0= WE0[temp[0]]; delay(3);
LSA=1;LSB=0; LSC=0;
P0= WE0[temp[1]]; delay(2);
LSA=0;LSB=1;LSC=0;
P0= WE0[temp[2]]; delay(1);
}
}
void main()
{
TMOD=0X01; //定时器工作方式0
TH0=0;
TL0=0;
EA=1; //开总中断
ET0=1;//开定时器中断
while(1)
{
start();//启动模块
while(!RX); //当RX为零时等待
TR0=1; //启动计数
while(RX); //当RX为1时计数并等待
TR0=0; //关闭计数器
count(); //计数
dispros(); //处理,分割数据
display(); //显示
delay(1);
}
}
void t0() interrupt 0
{

flag=1; //溢出标志
}

关闭窗口

相关文章