超声波测距仪课程设计综述.docx
《超声波测距仪课程设计综述.docx》由会员分享,可在线阅读,更多相关《超声波测距仪课程设计综述.docx(22页珍藏版)》请在冰豆网上搜索。
![超声波测距仪课程设计综述.docx](https://file1.bdocx.com/fileroot1/2023-2/2/93f2756e-77ec-46e1-8c5e-74728621c3f8/93f2756e-77ec-46e1-8c5e-74728621c3f81.gif)
超声波测距仪课程设计综述
微机接口课程设计报告
题目名称:
超声波测距的设计
姓名:
戴芳洁
班级:
电信101班
学号:
201033285104
日期:
2013.7.5
一、设计题目
基于单片机超声波测距
二、设计目的及意义
日常生活应用发面:
人们生活水平的提高,城市发展建设加快,城市车辆逐
渐增多,因为停车不当而造成的交通事故也越来越多。
为了避免此类事故的发生
一个能够直观地测出汽车与障碍物之间的距离的装置就变得十分必要。
它可以及
时将车辆与障碍物之间的距离反映出来,给司机以更准确的信息和更多的反应时
间,减少事故的发生;军事应用方面:
超声波声纳已广泛应用于侦查探测等方面,
如何提高其测量精度已是正在着重研究的课题之一,相信在不久的将来,超声波
测距一定会在侦查反侦察方面起到更大的作用;工业应用方面:
超声波测距仪的
设计方便了管道的距离探测,消除了一些空间方面的限制,在其测量精度得到提
升后,对一些精密设备的测量也将起到良好的效果。
三、设计要求及主要技术指标
1、方案论证,确定总体电路原理方框图。
2、单元电路设计,元器件选择。
3、仿真调试及测量结果。
主要技术指标:
设计一超声波测距仪,任务:
1、了解超声波测距原理。
2、根据超声波测距原理,设计超声波测距器的硬件结构电路。
设计一超声波测距仪,要求:
1、设计出超声波测距仪的硬件结构电路。
2、对设计的电路进行分析能够产生超声波,实现超声波的发送与接收,从而实现
利用超声波方法测量物体间的距离。
3、对设计的电路进行分析。
4、以数字的形式显示测量距离。
一、方案论证与比较
1.1方案提出
方案一:
采用CPLD来控制的超声波测距仪
采用CPLD来控制的超声波测距仪,主要是在软件上运用VHDL编写程序使用MAX+plus II软件进行软硬件设计的仿真和调试,最终实现测距功能。
使用本方案的优点在于在超声波测距仪设计中采用的是MAX7000s系列中的EPM7128SLC84-15的CPLD器件,其最高频率可达175.4MHz,可用于组合逻辑电路、时序逻辑电路、算法、双端口RAM等的设计。
充分利用了其多达128个宏单元、68pin可编程I/O口,使该器件可以将分频功能、计数功能、显示编码功能、振荡功能全部集于一体。
又因其延时平均的特点,保证了测距结果精度高、响应速度快。
缺点是方案中需要一块FPGA,一块双口RAM,还需要一块用来存储波形数据的EEPROM,那么设计的成本较高。
同时在FPGA中还要用硬件描述语言(VHDL语言)编写程序来实现硬件电路功能。
由于EPM7128SLC84-15的算法复杂,所以在软件实现起来编程也复杂。
方案二:
采用51单片机控制的超声波测距系统
采用单片机来控制的超声波测距仪是先由单片机产生一个信号,经过信号线,把信号引入到与超声波发射器相连的信号引脚上,再由超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。
超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离(s)。
1.2设计方案的论证和选择
超声波测距的原理是利用超声波的发射和接受,由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量。
利用超声波检测距离,设计比较方便,计算处理也较简单。
实用的测距方法有两种,一种是在被测距离的两端,一端发射,另一端接收的直接波方式,适用于身高计;一种是发射波被物体反射回来后接收的反射波方式,适用于测距仪。
此次设计采用方案二的方式。
原理框图:
图1-1超声波的测距原理
二、系统的功能及设计框图
2.1系统的全部功能
1、本系统实现要求测量距离范围为0.1~3米,精度误差在1厘米以内,并且使用
LCD1602显示所测距离。
2、该系统硬件部分由发送模块、接收模块、显示模块组成。
发送模块部分主要由
超声波发射器组成;接收模块主要由超声波接收探头组成;显示模块则有液晶显示器LCD1602及其辅助电路组成。
3、以数字的形式显示测量距离。
(1)超声波测距的方法有多种:
如往返时间检测法、相位检测法、声波幅值检测法。
(2)本设计采用往返时间检测法测距。
其原理是超声波传感器发射一定频率的超声波,借助空气媒质传播,到达测量目标或障碍物后反射回来,经反射后由超声波接收器接收脉冲,其所经历的时间即往返时间,往返时间与超声波传播的路程的远近有关。
(3)假定s为被测物体到测距仪之间的距离,测得的时间为t,超声波传播速度为
v表示,则有关系式
s=vt/2
2.2确定设计框图(系统包含的单元电路及结构)和总体设计方案
本系统的超声波发射和接收电路采用HC-SR04系列超声波测距模块,此模块的特点是可提供1cm-300cm的非接触式距离感测功能,测距精度可高达3mm。
模块包括超声波发射器、接收器与控制电路。
系统的性能指标依据HC-SR04系列超声波测距模块的电气参数,系统可提供1cm-300cm的非接触式距离感测功能,超出测量范围液晶1602显示outofrange,测距精度可高达3mm,但是本系统最小的显示单位是1cm,所以测量的最小精度是1cm。
超声波测距系统的一般结构如下图1-1所示。
(本系统要求不是很精确,所以舍去了温度补偿电路)。
图2-2系统一般结构框图
2.3软件流程图:
图2-3主程序流程图
三、系统调试分析
3.1设计原理图
图3-1超声波测距原理图
四、结束语
在本次设计中,我们充分考虑了整个设计中的各个环节。
包括产生40KHz的方波,在接收电路中,对所接收方波进行滤波、放大、整形等步骤。
但由于条件和技术所限,对于很多以上所分析的在发射和接收过程中所产生的误差没有得到有效的校正。
比如温度误差、硬件电路误差等。
在我们为期五天的设计中,我们用到了以前学到的很多知识,比如电路、单片机、和汇编语言等。
这使我们意识到,任何一件产品的产生,都不是单一知识所能实现的。
而且在电路的设计和程序的编制过程中,出现了很多意想不到的错误,让我们措手不及,有些甚至是一些非常低级的错误,但是这些错误也同样让我们获益非浅,它使我们意识到,研究是一个非常严肃的过程,来不得半点马虎。
必须有一个严谨的态度,加上100%的努力才有可能获得成功的喜悦。
总之,在本课题的设计过程中尽管走了很多的弯路,但是还是学到了不少知识,从中受益匪浅。
了解了超声波传感器的原理、设计,也掌握了单片机的开发过程中所用到的开发方法和工具。
动手能力与自学能力得到了锻炼与提高,对待事物的态度也发生了变化。
理论总是离不开实践的,设计制作过程中,盲目地追寻理论知识根本不足以解决任何问题,一味的死研究课本是不会真正掌握单片机的。
只有真正动手去做才能发现问题,解决问题,提高能力。
五、参考文献
[1] 吴金戌.沈庆阳.郭庭.《8051单片机实践与应用》,清华大学出版社, 2003年4月版。
[2] 李建忠 .《单片机原理及应用》,西安电子科技大学出版社, 2005年版。
[3] 张金铎 .《传感器用其应用》,西安电子科技大学出版社, 2002年版。
[4] 求是科技 .《单片机典型外围器件及应用实例》,人民邮电出版社, 2006年版。
[5] 应崇福 .《超声学》,北京科学出版社1990年。
[6] 瓮嘉民.单片机应用开发技术—基于PROTEUS仿真和C语言编程,中国电力出版社,2009年版。
附录1:
设计中用到的元器件、芯片的外引脚图及引脚功能说明。
1、51系列单片机的功能特点
5l系列单片机中典型芯片(STC89C52)采用40引脚双列直插封装(DIP)形式,内部由CPU,8kB的ROM,256 B的RAM,2个16b的定时/计数器TO和T1,4个8 b的工/O端I:
IP0,P1,P2,P3,一个全双功串行通信口等组成。
特别是该系列单片机片内的Flash可编程、可擦除只读存储器(E~PROM),使其在实际中有着十分广泛的用途,在便携式、省电及特殊信息保存的仪器和系统中更为有用。
该系列单片机引脚与封装如图4-1所示。
图4-1
2、超声波发生器
如有图所示,如右图接线,VCC供5V电源,GND为地线,TRIG触发控制信号输入,ECHO回响信号输出等四个接口端。
基本工作原理:
(1)采用IO口TRIG触发测距,给至少10us的高电平信号。
(2)模块自动发射8个40khz的方波,并检测信号是否有返回。
(3)有信号返回,通过IO端口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到接收所用的时间。
测量距离=高电平持续时间*声速/2。
实物图如图4-2所示:
图4-2
3、LCD1602显示器
LCD1602可以显示2行16个字符,有8位数据总线D0~D7和RS,R/W,EN三个
控制端口,工作电压为5V,并且具有字符对比度调节和背光功能。
(1)引脚参数如下:
LCD1602可以显示2行16个字符,有8位数据总线D0~D7和RS,R/W,EN三
个控制端口,工作电压为5V,并且具有字符对比度调节和背光功能。
◆SMC1602A液晶显示模块的接口信号说明:
编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
DataI/O
2
VDD
电源正极
10
D3
DataI/O
3
VL
液晶显示偏压信号
11
D4
DataI/O
4
RS
数据/命令选择端(H/L)
12
D5
DataI/O
5
R/W
读写选择端(H/L)
13
D6
DataI/O
6
E
使能信号
14
D7
DataI/O
7
D0
DataI/O
15
BLA
背光源正极
8
D1
DataI/O
16
BLK
背光源负极
(2)1602型LCD的主要技术参数如下:
显示容量
16X2个字符
芯片工作电压
4.5~5.5V
工作电流
2.0mA(5.0V)
模块最佳工作电压
5.0V
字符尺寸
2.95X4.35(WXH)mm
(3)基本操作程序:
读状态:
输入:
RS=L,RW=H,E=H
输出:
D0~D7=状态字
读数据:
输入:
RS=H,RW=H,E=H
输出:
无
写指令:
输入:
RS=L,RW=L,D0~D7=指令码,E=高脉冲
输出:
D0~D7=数据
写数据:
输入:
RS=H,RW=L,D0~D7=数据,E=高脉冲
输出:
无
读操作时序:
写操作时序:
附录3:
源程序
#include//器件配置文件
#include
#include
sbitEcho=P3^6;
sbitTrig=P3^7;
sbitLCM_RW=P2^5;//定义LCD引脚
sbitLCM_RS=P2^4;
sbitLCM_E=P2^6;
#defineLCM_DataP0
#defineBusy0x80//用于检测LCM状态字中的Busy标识
voidLCMInit(void);//LCD初始化函数
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData);//LCD显示一个字符函数
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData);//LCD显示一个字符串函数
voidDelay5Ms(void);//延时5毫秒函数
voidDelay400Ms(void);//延时400毫秒函数
voidDecode(unsignedcharScanCode);
voidWriteDataLCM(unsignedcharWDLCM);//LCD1602写数据函数
voidWriteCommandLCM(unsignedcharWCLCM,BuysC);//LCD写命令函数
unsignedcharReadStatusLCM(void);
unsignedcharcodeASCII[13]="0123456789.-M";
unsignedcharcodetable[]="Distance:
000.0cm";
unsignedcharcodetable1[]="Outofrange!
!
!
";
//staticunsignedcharDisNum=0;//显示用指针
unsignedinttime=0;
unsignedlongS=0;
bitflag=0;
unsignedchardisbuff[4]={0,0,0,0,};
//写数据
voidWriteDataLCM(unsignedcharWDLCM)
{
ReadStatusLCM();//检测忙
LCM_Data=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E=0;//若晶振速度太高可以在这后加小的延时
LCM_E=0;//延时
LCM_E=1;
}
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测
{
if(BuysC)ReadStatusLCM();//根据需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_E=0;
LCM_E=0;
LCM_E=1;
}
//读状态
unsignedcharReadStatusLCM(void)
{
LCM_Data=0xFF;
LCM_RS=0;
LCM_RW=1;
LCM_E=0;
LCM_E=0;
LCM_E=1;
while(LCM_Data&Busy);//检测忙信号
return(LCM_Data);
}
voidLCMInit(void)//LCM初始化
{
LCM_Data=0;
WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1);//显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1);//关闭显示
WriteCommandLCM(0x01,1);//显示清屏
WriteCommandLCM(0x06,1);//显示光标移动设置
WriteCommandLCM(0x0c,1);//显示开及光标设置
}
//按指定位置显示一个字符
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)
{
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;//当要显示第二行时地址码+0x40;
X|=0x80;//算出指令码
WriteCommandLCM(X,1);//发命令字
WriteDataLCM(DData);//发数据
}
//按指定位置显示一串字符
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData)
{
unsignedcharListLength;
ListLength=0;
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
while(DData[ListLength]>0x19)//若到达字串尾则退出
{
if(X<=0xF)//X坐标应小于0xF
{
DisplayOneChar(X,Y,DData[ListLength]);//显示单个字符
ListLength++;
X++;
}
}
}
//5ms延时
voidDelay5Ms(void)
{
unsignedintTempCyc=5552;
while(TempCyc--);
}
//400ms延时
voidDelay400Ms(void)
{
unsignedcharTempCycA=5;
unsignedintTempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
/********************************************************/
voidConut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/10;//算出来是MM
if((S>=7000)||flag==1)//超出测量范围
{
flag=0;
DisplayListChar(0,0,table1);
}
else
{
disbuff[0]=S%10;
disbuff[1]=S/10%10;
disbuff[2]=S/100%10;
disbuff[3]=S/1000;
DisplayListChar(0,0,table);
DisplayOneChar(9,0,ASCII[disbuff[3]]);
DisplayOneChar(10,0,ASCII[disbuff[2]]);
DisplayOneChar(11,0,ASCII[disbuff[1]]);
DisplayOneChar(12,0,ASCII[10]);
DisplayOneChar(13,0,ASCII[disbuff[0]]);
}
}
/********************************************************/
voidzd0()interrupt1//T0中断用来计数器溢出,超过测距范围
{
flag=1;//中断溢出标志
Echo=0;
}
/********************************************************/
voidStartModule()//启动模块
{
Trig=1;//启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
Trig=0;
}
voidTimer_Count(void)
{
TR0=1;//开启计数
while(Echo);//当RX为1计数并等待
TR0=0;//关闭计数
Conut();//计算
}
/*********************************************************/
voidmain(void)
{
unsignedintvalA;
Delay400Ms();//启动等待,等LCM讲入工作状态
LCMInit();//LCM初始化
Delay5Ms();//延时片刻
TMOD=0x01;//设T0为方式1,GATE=1;
EA=1;
TH0=0;
TL0=0;
ET0=1;//允许T0中断
//开启总中断
while
(1)
{
Echo=1;
StartModule();
for(valA=7510;valA>0;valA--)
{
if(Echo==1)
{
Timer_Count();
}
}
}
}