基于收发一体超声波探头的超声波测距方案
超声波测距的原理就是:单片机发出40Khz信号驱动升压中周,中周将驱动信号传送给一体式超声波探头,一体式超声波探头发出超声波信号,同时一体式超声波探头接收返回的超声波信号,该信号经过滤波、整形放大电路回51单片机,MCU根据发送40Khz信号与接收到返回信号之间的时间差 t 来计算物体距离超声波探头的距离 d,则 d 的计算公式如下:d = (t/2)*340。
基于收发一体超声波探头的超声波测距方案采用89R52单片机作收发处理器,超声波头采用收发一体的防水、防潮、防尘型高灵敏度超声波传感器,精度高、性能稳定。探头如下图:
工作电源:AC6V供电;测量范围:40cm~200cm(盲区值40cm),测量结果由三位数码管直接显示出来,当测量超过上限值199cm收不到回波时显示“C C C”, 测量低于盲区值时显示“- - -”。模块上设有一输出端口,用于输出报警信号,当测量结果小于设定的报警值时继电器吸合。报警值可通过板上的两个按键开关K1、K2设定,设定值范围为测量范围内的任意值(与测上限值相配)。以下是原理图:
完整工程原理图下载链接 链接: 基于收发一体超声波探头的_原理图.
以下是我的51代码,这里限于篇幅就贴出来部分,完整的可以去连接下载:
链接: 基于收发一体超声波探头的超声波测距内部源程序.
// An highlighted block
#include <REGX52.H>
#include <stdio.h>
#include <intrins.h>
typedef unsigned char INT8U;
typedef unsigned int INT16U;
//INT8U eeprom_address;
//INT8U read_eeprom;
INT8U ec,cs,mqs,k,n,mq,mq1,xm0,xm1,xm2,sec20,sec,sec1,buffer[3],BitCounter,Number[8]={1,2,3,4,5,6,7,8},DIS[6]={0,0,0,0,0,0};
INT8U convert[10]={0x48,0x7B,0xC2,0x52,0x71,0x54,0x44,0x7A,0x40,0x50};//0~9段码
INT16U cls,temp1,zzz,dz,zzbl,i,jsz,yzsj,kk,s,s1,ss,s,xl,xs;
static char bdata ke,kw; //可位寻址的状态寄存器
float csbc,wdz;
sbit LED1 = P2^2; //数码管位驱动
sbit LED2 = P2^1; //数码管位驱动
sbit LED3 = P2^0; //数码管位驱动
#define k1 P2_3 //k1功能键
#define k2 P2_4 //k2减键
#define sx P1_2 //报警值输出?
#define csbout P3_6 //超声波发送
#define csbint P1_3 //超声波接收
void delay(i); //延时函数
void scanLED(); //显示函数
void timeToBuffer(); //显示转换函数
void time(); //程序中没用到,这里是为以后扩长程序留下的,在这里可以册除
void csbcj(); //超声波测距函数
void bgcl(); //报警处理函数
void jpzcx(); //按键处理子函数
void mqjs(); //盲区处理
void csbfs(); //发送超声波
void offmsd(); //显示转换
void jpcl(); //键盘处理
void bgcl(); //报警处理
void mqjs(); //盲区值设定
void csbsc(); //超声波声速
void clcs();
sbit k11=ke^0; //按键标志位
sbit k12=ke^1; //按键标志位
sbit k22=ke^2; //按键标志位
sbit k21=ke^3; //按键标志位
sbit b=ke^4; //程序用到的一些标志位
sbit c=ke^5; //程序用到的一些标志位
sbit d=ke^6; //程序用到的一些标志位
sbit e=ke^7; //程序用到的一些标志位
/*
sfr IAP_DATA = 0xe2;
sfr IAP_ADDRH = 0xe3;
sfr IAP_ADDRL = 0xe4;
sfr IAP_CMD = 0xe5;
sfr IAP_TRIG = 0xe6;
sfr IAP_CONTR = 0xe7;
*/
#define ENABLE_ISP 0x81 //系统工作时钟<6MHz 时,对IAP_CONTR 寄存器设置此值
// #define DATA_FLASH_START_ADDRESS 0x2000 //STC89C51,STC89C52 系列 EEPROM 测试起始地址
INT8U Byte_Read(INT16U add); //读一字节,调用前需打开IAP 功能
void Byte_Program(INT16U add, INT8U ch); //字节编程,调用前需打开IAP 功能
void Sector_Erase(INT16U add); //擦除扇区
void IAP_Disable(); //关闭IAP 功能
void delayms(INT16U z);
void EEPROM_Init();
void EEPROM_Init();
void main(void)
{
EA=1;
SCON = 0x50;
TMOD = 0x21;
TCON = 0x40; //定时器1开始计数
TI = 1;
TR1=0;
zzz=299;
dz=50;
temp1=20;
cls=2;
csbsc();
mq=36;
mq1=mq+3;
mqjs();
clcs();
k12=1;
k1=1;
k2=1;
k22=1;
TR1=1;
while(1)
{
csbcj();
DIS[0]=jsz%10; //存放个位数据
DIS[1]=(jsz/10)%10; //存放十位数据
DIS[2]=(jsz/100)%10;//存放百位数据
if (jsz>299) //499
{
DIS[0]=19; //存放个位数据
DIS[1]=19; //存放十位数据
DIS[2]=19;//存放百位数据
}
timeToBuffer(); //调用转换段码功能模块
offmsd();
i=cs;
if (jsz<dz)
{
sx=0;
}
else sx=1;
while(i)
{
scanLED(); //调用显示函数
i--;
}
jpcl();
}
}
void csbcj()
{
TR1=0;
TH0=0x00;
TL0=0x00;
csbint=1;
csbfs();
csbout=0;
TR0=1;
i=yzsj; //盲区值(延时躲过超声波发送头的余波)
while(i--)
{
}
i=0;
while(csbint) //判断接收回路是否收到超声波的回波
{
i++;
if(i>=700)
csbint=0;
}
TR0=0;
s=TH0;
s=s*256+TL0+30;
csbint=1;
jsz=s*csbc; //计算测量结果
TR1=1;
}
void mqjs()
{
yzsj=110;
}
void delay(i) //延时子程序
{
while(--i);
}
void scanLED() //显示功能模块
{
P0=buffer[2];
LED1=0;
delay(1);
LED1=1;
delay(50);
P0=buffer[1];
LED2=0;
delay(1);
LED2=1;
delay(50);
P0=buffer[0];
LED3=0;
delay(1);
LED3=1;
delay(50);
}
void timeToBuffer() //转换段码功能模块
{
if (jsz>zzz)
{
buffer[2]=0xCC;
buffer[1]=0xCC;
buffer[0]=0xCC;
}
else if (jsz<36)
{
buffer[2]=0xF7;
buffer[1]=0xF7;
buffer[0]=0xF7;
}
else
{
xm0=jsz/100;
xm1=(jsz-xm0*100)/10;
xm2=jsz-xm0*100-xm1*10;
buffer[0]=convert[xm2];
buffer[1]=convert[xm1];
buffer[2]=convert[xm0];
if (buffer[2]==0x48)
{
buffer[2]=0xFF;
}
}
}
void offmsd() //百位为数0判断模块
{
if (buffer[2]==0x48) //如果值为零时百位不显示
buffer[2] = 0xff;
}
void jpcl()
{
k11=k1;
if (!k12&&k11)
{
b=1;
}
k12=k11;
k11=k1;
k21=k2;
if (b==1)
{
while(b)
{
buffer[0]=0x60;
buffer[1]=0x60;
buffer[2]=0x60;
i=500;
while(i)
{
i--;
scanLED();
}
jsz=dz;
timeToBuffer();
jpzcx();
dz=kk;
if (dz>299)
dz=299;
if (dz<35)
dz=35;
mq1=ss;
jsz=zzbl;
}
mqjs();
csbsc();
clcs();
}
}