超声波工作原理
(1)采用 IO 触发测距,给至少 10us 的高电平信号;
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间;
(4)超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2;
接口定义
Vcc、 Trig(控制端)、 Echo(接收端)、 Gnd
注意事项
1:此模块不宜带电连接,如果要带电连接,则先让模块的 Gnd 端先连接。否则会影响
模块工作。
2:测距时,被测物体的面积不少于 0.5 平方米且要尽量平整。否则会影响测试结果。
3:超声波测距的测距能力,要保证第一次发射的超声波有足够的时间反射回来,得算出时差并通过声速计算出距离,然后才能发射第二次,假设量程为3.4M,则超声波从发射到接受需要20MS 为一个测量周期, 量程与发射间隔成正比,理论上是这样。为了取得更好效果,超声波测距仪间隔取50-100MS 。
#include"reg51.h"
#include <intrins.h>
sbit RX=P2^1;
sbit TX=P2^0;
unsigned int time=0;
unsigned int timer=0;
bit flag=0;
unsigned long S=0;
#define GPIO_DIG P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
unsigned char disbuff[4];
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=0;i<8;i++)
{
switch(i) //位选
{
case(0):
LSA=0;LSB=0;LSC=0; break;//0位
case(1):
LSA=1;LSB=0;LSC=0; break;//1
case(2):
LSA=0;LSB=1;LSC=0; break;//2
case(3):
LSA=1;LSB=1;LSC=0; break;//3
case(4):
LSA=0;LSB=0;LSC=1; break;//4
case(5):
LSA=1;LSB=0;LSC=1; break;//5
case(6):
LSA=0;LSB=1;LSC=1; break;//6
case(7):
LSA=1;LSB=1;LSC=1; break;//7
}
GPIO_DIG=disbuff[i];//发送段码
j=10; //扫描时间间隔
while(j--);
GPIO_DIG=0x00;//消隐
}
}
void Conut(void)
{
time=TH0*256+TL0;//读取当前数值
TH0=0;//赋初值为0
TL0=0;
S= (long)(time*0.17); //计算出来的距离位MM
if(S<=40||flag==1) //超出范围显示ERR0
{
flag=0;
disbuff[0]=0x3f; //0
disbuff[1]=0x50; //R
disbuff[2]=0x50; //R
disbuff[3]=0x79; //E
}
else//距离
{
disbuff[3]=DIG_CODE[S/1000];
disbuff[2]=DIG_CODE[S%1000/100];
disbuff[1]=DIG_CODE[S%100/10];
disbuff[0]=DIG_CODE[S%10/1];
}
}
void zd0() interrupt 1 //T0溢出标志
{
flag=1;
}
void zd3() interrupt 3 //80Ms启动一次模块
{
TH1=0xf8;
TL1=0x30;
DigDisplay();
timer++;
if(timer>=40)
{
timer=0;
TX=1; //80MS
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
void main( void )
{
TMOD=0x11; //配置T0T1
TH0=0;
TL0=0;
TH1=0xf8; //2MS定时
TL1=0x30;
ET0=1; //T0中断
ET1=1; //T1中断
TR1=1; //开启定时器1
EA=1; //总开关
while(1)
{
while(!RX); //当RX为0时等待
TR0=1; //开始计数
while(RX); //当RX为1时
TR0=0; //关闭定时器0
Conut(); //计算距离
}
}