基于 STC89C51单片机超声波测距系统的设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于 STC89C51单片机超声波测距系统的设计
一、设计任务
1.1设计前景
超声波技术在日常生活中有着广泛的应用, 例如探伤技术、清洗技术、测距技术等等。
超声波测距多应用于汽车倒车雷达、建筑工地以及一些工业现场的位置监控如液位、井深的测量等场合。
国内的超声波测量主要集中在对0~10 m 固体和液体的测量,一般测量精度高,回波稳定。
由于高精度的超声波测距仪所采用的专业集成电路成本较高,以价格比较低廉的 STC89C51 单片机为核心设计一款具有低成本、高精度、具有动态显示等优点的超声波测距系统。
该系统测量距离0127~4100 m,测量精度为1cm。
同时给出了其硬件电路和软件设计方法。
实际使用表明该仪器工作稳定。
1.2超声波测距原理
超声波发生器内有一个共振板和两个压电晶片,当它的外加脉冲信号频率等于压电晶片的固有频率时,压电晶片会产生共振,并带动共振板一起振动,这样就产生了超声波。
在电路中,发射端输出的脉冲是一系列方波,其宽度称为发射超声波的时间间隔,被测物距离越大,其脉冲宽度就越大,输出脉冲个数与被测物距离成正比。
T mier寄存器对 P110口的高、低电平分别进行 12 L s的延时, 实现从 P110口输出周期为24 Ls的方波信号。
当单片机控制超声波发生器向某一方向发射超声波波束,在发射时刻的同时,单片机内部定时器开始计时。
在传播过程中,超声波遇障碍物(被测物)后反射回波,超声波接收器接收到第一个反射波后,定时器停止计时。
定时器所计的数据就是超声波所经历的时间,通过公式换算就可以得到传感器与障碍物之间的距离。
由于超声波的声速和温度有关,如果温度变化不是很大,认为声速基本不变。
如果测距精度要求很高,那么可以通过温度补偿的方法来加以校正。
不同温度下超声波在空气中的传播速度随温度变化关系:
v = 33114+0161T 其中, T为实际温度; v的单位为 m /s。
表 1 声速与温度的关系
测距的公式为: L= v×▽t,其中, L为测量的距离长度; v为超声波在空气
中的传播速度; ▽t为发射到接收所用时间的一半,由单片机的定时功能实现对超声波信号的准确计时。
二、元器件清单
三、设计过程
3.1硬件设计
超声波测距仪硬件部分主要由超声波信号接收电路、超声波发射电路、显示电路、单片机外围电等组成。
采用STC89C51 实现对CX20106A 红外接收芯片和 TCT40-10系列超声波转换模块的控制,同时加了MAX232芯片,它和外围电路组成了RS232-TTL电平转换电路, 它是串口 ISP下载电路,可以通过串口ISP在线下载程序。
图1超声波测距仪系统设计框图
3.2 STC89C51控制器单元
STC89C5控制器单元包括STC89C51、振荡电路、复位电路。
振荡电路使用12 MH z高精度晶振,振荡电容选择30 pF小瓷片电容;复位电路使用 RC电路,
使用普通的电解电容与金属膜电阻即可。
STC89C51可以代替AT89C 51,其功能更强、速度更快、寿命更长、价格更低,可以完成ISP在线编程功能,可以在程序中修改,断电不丢失,还增加了两级中断优先级。
3.3超声波发射电路
超声波在空气中传播功率及精度与频率成正
比,比较和分析几个常用超声波频率的特点,最
终选取频率为40 kH z。
为了便于超声波的发射
与接收, 超声波发射探头采用共振频率为40 kH z
的 TCT40-16探头,接收探头采用 RCT40-16。
超
声波发射电路主要由超声波换能器和反相74LS04 图2 超声波发射电路
构成,单片机P110端口输出40kH z间断方波,此时定时器开始计时,信号经两路反相器送到超声波换能器的两个电极,可以提高超声波的发射强度。
输出端采用两个反相器并联,可以提高驱动能力。
电阻 R1、R2可以增加超声波换能器的阻尼效果,这样可以缩短振荡时间,提高74LS04输出高电平的驱动能力。
3.4超声波接收电路
超声波接收电路采用SONY公司的CX20106A集成电路,对接收探头收到的信号进行放大、滤波。
它是一款红外线检波接收的专用芯片,有较强的抗干扰性和
灵敏度。
管脚1是超声波信号输
入端,其输入阻抗约为40kΩ;
管脚2的C2、R3决定接收换能
器的总增益,增大电阻R或者
减小C,将使放大倍数下降,负反
馈量增大,电容C的改变会影响
到频率特性,实际使用中一般不
改动,推荐选择参数R =4178, 图3 超声波接收电路
C= 313 LF;管脚3与GND之间连接检波电容,考虑到检波输出的脉冲宽度变动大,推荐参数313LF;管脚 5上的连接电阻R4用以设置带通滤波器的中心频率,阻值越大,中心频率越低,取R=200 k8时,中心频率约为42 kH z;管脚6与GND 之间接入一个积分电容,标准值为30 pF,如果该电容取得太大,会使探测距离变短;管
脚 7是遥控命令输出端,它是集电极开路的输出方式,因此该引脚必须接上一
个上拉电阻到电源端,该电阻推荐阻值为R5 =220 kΩ,没有接收信号时该端输出为高电平有信号时则会下降;管脚 8接电源正极,4.5~5 V。
3.5单片机外围电路
该系统单片机外围电路如图 4所示,有温度补偿电路、串口ISP下载电路。
采用3脚PR235封装的数字温度传感器 DS18B20对环境温度进行检测,从而对超声波的传播速度进行温度补偿,提高测量精度。
两个按键用于控制测量的开始与停止以及距离与温度显示的切换。
其特点如下:硬件接口简单,性能稳定,单线接口, 仅需一根接口线与 MCU 连接无需外围元件; 由总线提供电源; 测温范围为- 55~75 e;精度为015e;9位温度读数;A/D变换时间为200 ms。
图4 STC89C51及其外围电路
3.6显示电路
为了节约成本, 该系统用 4位数码管显示, 显示电路采用简单实用的 4
位共阳 LED 数码管来显示测距离, 采用单片机动态扫描显示。
段码用
74LS245驱动, 位码用 PNP三极管 VT1、 VT2、 VT3、 VT4驱动。
图5 显示电路
3.7软件设计
该系统采用模块化设计,由主程序、发射子程序、接收子程序、定时子程序、温度检测子程序、显示子程序等模块组成。
主程序完成初始化后调用发射子程序, 由 P110口发射脉冲,驱动超声波传感器发射超声波,并关外部中断,计数器T0开始计时。
为防止虚假回波的干扰,在延时一段时间后,开中断。
当有外部中断信号时,单片机就停止T0的计时,计算出渡越时间t并存储E2PROM中;然后调用测温子程序,采集超声波测距时的环境温度,并换算出准确的声速v,存储到E2PROM中,单片机再调用计算子程序,计算出传感器到目标物体之间的距离,最后把测量果存储并通过数码管电路显示出来,完成一次测量。
该系统的主程序采用键控循环工作方式,当按下测量键时,主程序开始调用发射子程序、查询接收子程序、定时子程序,并把测量结果用显示子程序在数码显示器上显示出来。
设计中,超声波发射探头和接收探头距离较近,当发射探头发射超声波后,有
部分超声波没经过障碍物反射就直接绕射到接收探头上,这部分信号是无用的,会引起系统误测。
设计中采用延时技术来解决这个问题,并设定延时时间为1 ms, 即在发射极发射超声波 1ms内,通过软件关闭所有中断,接收电路对此期间接收到的任何信号不予理睬, 1 ms后立即启动T0,这时接收到的信号才有效,并在接收到回波信号的同时,T0停。
此时T0所记录的CPU发送脉冲信号的前沿到回波脉冲信号之间的时间才是需要的,因此系统存在测量盲区。
图6主程序流程图
四、总结
通过设计的超声波测距系统具有结构简单、功耗低、易于操作、灵活性高、成本低的特点,还具有操作方便、运行可靠的优点,它有良好的人机界面,能方便地实时显示测距数据。
实际制作中加入 DSl8820温度检测集成电路会使测量更加精确。
采用CX20106A 芯片用于检波放大,减少了电路之间的互相干扰,减小了电噪声。
该系统可广泛应用于倒车雷达、机器人检测以及物位测量领域。
【参考文献】
[1] 胡萍.超声波测距仪的研制.计算机与现代化,2003.10
[2] 时德刚,刘哗.超声波测距的研究.计算机测量与控制,2002.10
[3] 华兵.MCS-51单片机原理应用.武汉华中科技大学出版社,2002.5
[4] 陈光东.单片机微型计算机原理与接口技术(第二版).华中理工大学出版社,1999.4
[5] 苏长赞.红外线与超声波遥控.人民邮电出版社,1993.7
[6] 胜全.D18B20数字温度计在微机温度采集系统中的序编制.南京大学出版社,1998. 3
附录:
程序清单
#INCLUDE <REG2051.H>
#DEFINE K1 P3_4
#DEFINE CSBOUT P3_5 //超声波发送
#DEFINE CSBINT P3_7 //超声波接收
#DEFINE CSBC=0.034 #DEFINE BG P3_3
UNSIGNED CHAR CSBDS,OPTO,DIGIT,BUFFER[3],XM1,XM2,XM0,KEY,JPJS;//显示标识UNSIGNED CHAR
CONVERT[10]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};//0~9 段码UNSIGNED INT S,T,I, XX,J,SJ1,SJ2,SJ3,MQS,SX1;
BIT CL;
VOID CSBCJ();
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;
CSBDS=0;
CSBINT=1;
CSBOUT=1;
CL=0;
ŌPTO=0XFF;
JPJS=0;
SJ1=45;
SJ2=200;
SJ3=400;
K4CL();
TR1=1;
WHILE(1)
{
KEYSCAN();
IF(JPJS<1)
{
CSBCJ();
IF(S>SJ3)
{
BUFFER[2]=0X76;
BUFFER[1]=0X76;
BUFFER[0]=0X76;
}
ELSE IF(S<SJ1)
{
BUFFER[2]=0X40;
BUFFER[1]=0X40;
BUFFER[0]=0X40;
}
ELSE TIMETOBUFFER();
}
ELSE TIMETOBUFFER(); //将值转换成LED 段码
OFFMSD();
SCANLED(); //显示函数
IF(S<SJ2)
BG=0;
BG=1;
}
}
VOID SCANLED() //显示功能模块
{
DIGIT=0X04;
FOR( I=0; I<3; I++) //3 位数显示
{
P3=~DIGIT&OPTO; //依次显示各位数
P1=~BUFFER; //显示数据送P1口
DELAY(20); //延时处理
P1=0XFF; //P1 口置高电平(关闭)
IF((P3&0X10)==0) //判断3 位是否显示完
KEY=0;
DIGIT>>=1; //循环右移1 位
}
}
VOID TIMETOBUFFER() //转换段码功能模块
{
XM0=S/100;
XM1=(S-100*XM0)/10;
XM2=S-100*XM0-10*XM1;
BUFFER[2]=CONVERT[XM2];
BUFFER[1]=CONVERT[XM1];
BUFFER[0]=CONVERT[XM0];
}
VOID DELAY(I)
{
WHILE(--I);
}
VOID TIMER1INT (VOID) INTERRUPT 3 USING 2 {
TH1=0X9E;
TL1=0X57;
CSBDS++;
IF(CSBDS>=40)
{
CSBDS=0; CL=1;
}
}
VOID CSBCJ()
{
IF(CL==1)
{
TR1=0;
TH0=0X00;
TL0=0X00;
I=10;
WHILE(I--)
{
CSBOUT=!CSBOUT;
}
TR0=1;
I=MQS; //盲区
WHILE(I--)
{
}
I=0;
WHILE(CSBINT)
{
I++;
IF(I>=2450) //上限值
CSBINT=0;
}
TR0=0;
TH1=0X9E;
TL1=0X57;
T=TH0;
T=T*256+TL0;
S=T*CSBC/2;
TR1=1; CL=0;
}
}
VOID KEYSCAN() //健盘处理函数{
XX=0;
IF(K1!=1) // 判断开关是否按下
{
DELAY(400); //延时去抖动
IF(K1!=1) // 判断开关是否按下
{
WHILE(!K1)
{
DELAY(30);
XX++;
}
IF(XX>2000)
{
JPJS++;
IF(JPJS>4)
JPJS=0;
}
XX=0;
SWITCH(JPJS)
{
CASE 1: K1CL();BREAK;
CASE 2: K2CL();BREAK;
CASE 3: K3CL();BREAK;
CASE 4: K4CL();BREAK;
}
}
}
}
VOID K1CL()
{
SJ1=SJ1+5;
IF(SJ1>100)
SJ1=30; S=SJ1;
}
VOID K2CL()
{
SJ2=SJ2+5;
IF(SJ2>500)
SJ2=40;
S=SJ2;
}
VOID K3CL()
{
SJ3=SJ3+10;
IF(SJ3>500)
SJ3=100;
S=SJ3;
}
VOID K4CL()
{
SX1=SJ1-1;
SX1=SX1/CSBC;
MQS=SX1/4.5;
}
VOID OFFMSD()
{
IF (BUFFER[0] == 0X3F)
BUFFER[0] = 0X00;
}。