在日常生产生活中,很多场合如汽车倒车、机器人避障、工业测井、水库液位测量等需要自动进行非接触测距。超声波是指频率大于20 kHz的在弹性介质中产生的机械震荡波,其具有指向性强、能量消耗缓慢、传播距离相对较远等特点,因此常被用于非接触测距。由于超声波对光线、色彩和电磁场不敏感,因此超声波测距对环境有较好的适应能力,此外超声波测量在实时、精度、价格也能得到很好的折衷。 本设计所控制距离为80cm,测得距离小于等于80cm就报警,距离远近可以自己在程序中更改!! 1 超声波测距原理 超声波传感器分机械方式和电气方式两类,它实际上是一种换能器,在发射端它把电能或机械能转换成声能,接收端则反之。本次设计超声波传感器采用电气方式中的压电式超声波换能器,它是利用压电晶体的谐振来工作的。它有两个压电晶片和一个共振板。当它的两极外加脉冲信号,其频率等于压电晶片的固有振荡频率时,压电晶片将会发生共振,并带动共振板振动,产生超声波。反之,如果两电极间未外加电压,当共振板接收到超声波时,将压迫压电晶片作振动,将机械能转换为电信号,就成为超声波接收器。在超声波电路中,发射端输出一系列脉冲方波,脉冲宽度越大,输出的个数越多,能量越大,所能测的距离也越远。超声波发射换能器与接收换能器其结构上稍有不同,使用时应分清器件上的标志。 超声波测距的方法有多种:如往返时间检测法、相位检测法、声波幅值检测法。本设计采用往返时间检测法测距。其原理是超声波传感器发射一定频率的超声波,借助空气媒质传播,到达测量目标或障碍物后反射回来,经反射后由超声波接收器接收脉冲,其所经历的时间即往返时间,往返时间与超声波传播的路程的远近有关。测试传输时间可以得出距离。 假定s为被测物体到测距仪之间的距离,测得的时间为t/s,超声波传播速度为v/m·s-1表示,则有关系式(1) s=vt/2 (1) 在精度要求较高的情况下,需要考虑温度对超声波传播速度的影响,按式(2)对超声波传播速度加以修正,以减小误差。 v=331.4+0.607T (2) 式中,T为实际温度单位为℃,v为超声波在介质中的传播速度单位为m/s。 2 系统总体设计方案 本系统由超声波发射、回波信号接收、显示和报警、等硬件电路部分以及相应的软件部分构成。整个系统由单片机AT89S52控制,超声波传感器采用收发分体式,分别是一支超声波发射换能器TCT40-16T和一支超声波接收换能器TCT40-16R。超声波信号通过超声波发射换能器发射至空气中,遇被测物反射后回波被超声波接收换能器接收。进行相关处理后,输入单片机的INT0脚产生中断,计算中间经历的时间,同时再根据具体的温度计算相应的声速,根据式(2)就可得出相应的距离用来显示,当然在一些场合也可根据需要,设置距离报警值。 3 硬件设计 3.1 超声波发射部分 超声波发射部分是为了让超声波发射换能器TCT40-16T能向外界发出40 kHz左右的方波脉冲信号。40 kHz左右的方波脉冲信号的产生通常有两种方法:采用硬件如由555振荡产生或软件如单片机软件编程输出,本系统采用后者。编程由单片机P1.0端口输出40 kHz左右的方波脉冲信号,由于单片机端口输出功率不够,40 kHz方波脉冲信号分成两路,送给一个由74HC04组成的推挽式电路进行功率放大以便使发射距离足够远,满足测量距离要求,最后送给超声波发射换能器TCT40-16T以声波形式发射到空气中。发射部分的电路,如图2所示。图中输出端上拉电阻R31,R32,一方面可以提高反向器74HC04输出高电平的驱动能力,另一方面可以增加超声换能器的阻尼效果,缩短其自由振荡的时间。 3.2 超声波接收部分 上述TCT40-16T发射的在空气中传播,遇到障碍物就会返回,超声波接收部分是为了将反射波(回波)顺利接收到超声波接收换能器TCT40-16R进行转换变成电信号,并对此电信号进行放大、滤波、整形等处理后,这里用索尼公司生产的集成芯片CX20106,得到一个负脉冲送给单片机的P3.2(INT0)引脚,以产生一个中断。接收部分的电路,如图3所示。
可以看到,集成芯片CX20106在接收部分电路中起了很大的作用。CX20106是一款应用广泛的红外线检波接收的专用芯片,其具有功能强、性能优越、外围接口简单、成本低等优点,由于红外遥控常用的载波频率38 kHz与测距的超声波频率40 kHz比较接近,而且CX20106内部设置的滤波器中心频率f0五可由其5脚外接电阻调节,阻值越大中心频率越低,范围为30~60 kHz。故本次设计用它来做接收电路。CX20106内部由前置放大器、限幅放大器、带通滤波器、检波器、积分器及整形电路构成。工作过程如下:接收的回波信号先经过前置放大器和限幅放大器,将信号调整到合适幅值的矩形脉冲,由滤波器进行频率选择,滤除干扰信号,再经整形,送给输出端7脚。当接收到与CX20106滤波器中心频率相符的回波信号时,其输出端7脚就输出低电平,而输出端7脚直接接到.AT89S52的INT0引脚上,以触发中断。若频率有一些误差,可调节芯片引脚5的外接电阻R42,将滤波器的中心频率设置在40 kHz,就可达到理想的效果。 3报警部分。 采用一个蜂鸣器,输出一定频率的信号,在连接到蜂鸣器之前,经过一个三极管9 012的放大。报警部分的连线,如图6所示。 4 软件 系统软件设计采用模块化设计,主要包括主程序设计、T1中断服务子程序、INT0外部中断服务子程序、距离计算子程序、显示子程序、延时子程序和报警子程序设计等。 系统软件编制时应考虑相关硬件的连线,同时还要进行存储空间、寄存器以及定时器和外部中断引脚的分配和使用。本设计中P1.0引脚连接到7 HC04推挽放大电路再连接到超声波发射传感器,P1.0引脚输出的将是软件方式产生的40 kHz方波,而P3.2(INT0)则被用来接收回波。定时器T1,T0均工作在工作方式1,为16位计数,T1定时器被用来开启一次测距过程以它的溢出为标志开始一个发射测量循环,T0定时器是用来计算脉冲往返时间,它们的初值均设为0。 此外,还有几点需要说明的是: 本设计中40 kHz方波的产生采用软件方式实现:控制P1.0口输出12μs的高电平,再输出13μs的低电平,这样得到一个周期的40 kHz的脉冲,再循环发送8次。 在CPU停止发送脉冲群后,由于电阻尼,换能器不能立即停止发送超声波,在一段时间内仍然会发送,故这段时间内不可立即开启INT0接收回波,要等待一段后以避免发送端的部分直射波未经被测物就直接绕射到接收端,这段被称为“虚假反射波”。从发射开始一直到“虚假反射波”结束这段时间,不开放INT0中断申请,可有效躲避干扰,但也会造成测试的“盲区”。本次设为1 ms,假定温度为20℃,则测量盲区为s=1×10-3×344/2≈17.2 cm。 (4)最大测试距离将取决于:两次脉冲群发送之间的最小时间间隔和脉冲的能量。一般来说,发射端脉冲个数越多,能量越大,所能测的距离也越远。但也不是无限制的,本次读取定时器T0的计数值,最大能测试的距离是T0尚没溢出,故在温度20℃下,最大测试距离为s=vt/2=65 535×344/(2×106)=11.272 m。在一些周期性发射超声波设备中,如果要测试的最大距离是10 m,则两次脉冲群之间的最小时间为t=2×s/v=2×10/344≈60:ms 。 部分程序 #include ***it k1=P3^4; ***it c***out=P1^0; //超声波发送 ***it c***int=P3^2; //超声波接收 ***it bg=P3^3; #define LED P0 ***it LED1=P2^4; //LED控制 ***it LED2=P2^5; //LED控制 ***it LED3=P2^6; //LED控制 ***it bj=P2^0;//报警 #define c***c 0.0347 unsigned char cl,mqzd,c***s,c***ds,buffer[3],xm1,xm2,xm0,jpjs;//显示标识 unsigned char convert[10]={0x18,0x7b,0x2c,0x29,0x4b,0x89,0x88,0x3b,0x08,0x09};//0~9段码 unsigned int s,t,i,xx,j,sj1,sj2,sj3,mqs,sx1; void c***cj(); void delay(j); //延时函数 void scanLED(); //显示函数 void timeToBuffer();//显示转换函数 void keyscan(); void k1cl(); void k2cl(); void k3cl(); void k4cl(); void offmsd(); void main() //主函数 { EA=1; //开中断 TMOD=0x11; //设定时器0为计数,设定时器1定时 ET0=1; //定时器0中断允许 ET1=1; //定时器1中断允许 TH0=0x00; TL0=0x00; TH1=0x9E; TL1=0x57; c***ds=0; c***out=1; cl=0; c***s=8; jpjs=0; sj1=50;/////////测试报警距离 sj2=200; sj3=580; k4cl(); TR1=1; while(1) { keyscan(); if(jpjs<1) { c***cj(); //调用超声波测距程序 if(s>sj3) //大于时显示“CCC” { buffer[2]=0xC6; buffer[1]=0xC6; buffer[0]=0xC6; } else if(s { buffer[2]=0xBF; buffer[1]=0xBF; buffer[0]=0xBF; } else timeToBuffer(); } else timeToBuffer(); //将值转换成LED段码 offmsd(); scanLED(); //显示函数 if(s bg=0; bg=1; } }
|