基于单片机控制的超声波测距报警系统设计
系 部: | 电子与信息工程系 |
专业班级: | |
学生姓名: | |
学 号: | |
小组成员: | |
指导教师: | |
时 间: |
完成时间 2010年 12月
1 绪论
随着科学技术的快速发展,超声波将在测距仪中的应用越来越广。例如,倒车雷达、交通测速、机器人障碍检测等。但就目前技术水平来说,人们可以具体利用的测距技术还十分有限,因此,这是一个正在蓬勃发展而又有无限前景的技术及产业领域。
展望未来,超声波测距仪作为一种新型的非常重要有用的工具在各方面都将有很大的发展空间,它将朝着更加高定位高精度的方向发展,以满足日益发展的社会需求,如声纳的发展趋势基本为:研制具有更高定位精度的被动测距声纳,以满足水中武器实施全隐蔽攻击的需要;继续发展采用低频线谱检测的潜艇拖曳线列阵声纳,实现超远程的被动探测和识别;研制更适合于浅海工作的潜艇声纳,特别是解决浅海水中目标识别问题;大力降低潜艇自噪声,改善潜艇声纳的工作环境。
无庸置疑,未来的超声波测距仪将与自动化智能化接轨,与其他的测距仪集成和融合,形成多测距仪。随着测距仪的技术进步,测距仪将从具有单纯判断功能发展到具有学习功能,最终发展到具有创造力。在新的世纪里,面貌一新的测距仪将发挥更大的作用。
本次设计是基于单片机控制的超声波测距报警系统设计,采用以STCC52单片机为核心的低成本、高精度、微型化数字显示超声波测距仪的硬件电路和软件设计方法。整个电路采用模块化设计,由主程序、预置子程序、发射子程序、接收子程序、显示子程序等模块组成。各探头的信号经单片机综合分析处理,实现超声波测距仪的各种功能。在此基础上设计了系统的总体方案,最后通过硬件和软件实现了各个功能模块。
2 总体设计方案
2.1 课程设计的任务与要求
2.1.1 课程设计的任务
利用所学数字电子技术、信号处理、控制等技术,设计、制作并调试完成一个单片机最小化系统,并在此基础上,将最小系统与综合实验开发平台上的超声波模块、显示模块进行正确的链接(如图2.1所示),使单片机可接收超声波模块输出的距离信号,并对其进行合理的处理后,在显示模块上实时显示超声波模块与障碍物的距离(单位:cm,精确到小数点后1位)。
图2.1 系统连接示意图
具体内容如下:
(1)设计最小化单片机系统;
(2)装焊、调试最小化单片机系统;
(3)设计并编程,以构成超声波测距信号发生回路;
(4)设计并编程,完成超声波信号处理,以实现测距功能;
(5)设计并编程,以实现超声波测距结果显示;
(6)设计并编程,以实现超声波测距报警功能;
(7)设计并完成系统启动/复位功能。
2.1.2 课程设计的要求
(1)实验开发平台上的数码管可实时显示障碍物与超声波模块的距离信息,单位为cm,精确到小数点后1位(如显示28.2表示28.2cm);
(2)当测试距离小于10cm或大于50cm时报警,且以上两种情况的报警方式需有明显区别(可采用蜂鸣器的蜂鸣时间长短加以区别,或在显示模块上显示不同的报警信息);
(3)系统应具备测距启动功能,或当系统报警后,可以复位系统,使其开始重新测距。
2.2 超声波测距原理
超声波测距原理是通过超声波发射传感器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就停止计时。常温下超声波在空气中的传播速度为 C=340m/s,根据计时器记录的时间 t,就可以计算出发射点距障碍物的距离S,如公式2.1所示:
S=C*t/2=C*t0 (2.1)
其中,t0就是所谓的渡越时间。
可以看出主要部分有:
(1)供应电能的脉冲发生器(发射电路);
(2)使接收和发射隔离的开关部分;
(3)转换电能为声能,且将声能透射到介质中的发射传感器;
(4)接收反射声能(回波)和转换声能为电信号的接收传感器;
(5)接收放大器,可以使微弱的回声放大到一定幅度,并使回声激发记录设备;
(6)记录/控制设备,通常控制发射到传感器中的电能,并控制声能脉冲发射到记录回波的时间,存储所要求的数据,并将时间间隔转换成距离。
距离测量系统常用的频率范围为 25KHz~300KHz 的脉冲压力波,发射和接收的传感器有时共用一个,或者两个是分开使用的。发射电路一般由振荡和功放两部分组成,负责向传感器输出一个有一定宽度的高压脉冲串,并由传感器转换成声能发射出去;接收放大器用于放大回声信号以便记录,同时为了使它能接收具有一定频带宽度的短脉冲信号,接收放大器要有足够的频带宽度[8]。
在超声波测量系统中,频率取得太低,外界的杂音干扰较多;频率取得太高,在传播的过程中衰减较大。故在超声波测量中,常使用 40KHz 的超声波。由于超声波发射与接收器件具有固有的频率特性,具有很高的抗干扰性能,目前超声波测量的距离一般为几米到几十米,是一种适合室内测量的方式。
2.3 超声波测距系统的总体方案
由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量。利用超声波检测距离,设计比较方便,计算处理也较简单,并且在测量精度方面也能达到农业生产等自动化的使用要求[9]。
超声波发生器可以分为两大类:一类是用电气方式产生超声波,一类是用机械方式产生超声波。电气方式包括压电型、电动型等;机械方式有加尔统笛、液哨和气流旋笛等。它们所产生的超声波的频率、功率、和声波特性各不相同,因而用途也各不相同。目前在近距离测量方面常用的是压电式超声波换能器。根据设计要求并综合各方面因素,本次设计采用STCC52单片机作为控制器,用动态扫描法实现LED数字显示,超声波驱动信号用单片机的定时器。
如图2.2所示,为超声波测距系统原理框图,系统的设计及器件的选择正是在这个基础上进行的。整个系统由STCC52芯片、超声波发射模块、超声波接收模块、LED数码管显示模块、报警模块以及稳压电源组成,最后通过硬件和软件来实现各个模块的功能。
图2.2 超声波测距系统原理框图
从STCC52芯片IN 脚输入40KH 的方波信号,也可从单片机的IO 口连续发出高低电平,产生方波,方波的个数一般为10 个左右,发出后用户启动定时器,开始计时,此时,超声波发射头开始发出超声波,当发出的超声波被前方的障碍物返射回来,返射回来的超声波被接收探头接收到,此时,模块的OUT 引脚会产生一个从高电平到低电平的跳变,此时要停止计时,通过计时的时间,根据公式2.2计算测量距离:
测量距离 = [时间 * 声速 ( 340m/s ) ] / 2 (2.2)
距离测量完毕后,将在LED数码管上显示目前的距离,当距离小于10cm
或大于50cm时,蜂鸣器就会报警,报警完毕后,系统复位,重新开始测距。
超声波模块测得的是被测物体与探头之间的垂直距离,测量时要保持探头正对被测物体。超声波测量会受环境风速、温度等的影响。由于超声波有测量盲区的固有特性,当测量位置发生变化而接收到的数据不变时,说明进入了测量盲区。
3 系统硬件电路设计
3.1 STCC52芯片介绍
STCC52系列单片机是新一代超强抗干扰、高速、低功耗的单片机,是MCS-51系列单片机的派生产品。它在指令系统、硬件系统和片内资源中与标准的8052单片机完全兼容,DIP-40封装系列与8051为pin-to-pin兼容,指令代码是与8051完全兼容的单片机[4]。
8 位的CPU,片内有振荡器和时钟电路,工作频率为0~24MHz;片内有256个字节的数据存储器RAM;片内还有8K字节的程序存储器ROM;4个8位的并行I/O口(P0、P1、P2、P3);1个全双工串行通讯口;3个16位的定时器/计数器(T0、T1、T2)可处理 6个中断源,两级中断优先级。
P0.0—P0.7:8位数据口和输出低8位地址复用口(复用时是双向口、不复用时也是准双向口);P1.0—P1.7: 通用I/O口(准双向口);P2.0—P2.7: 输出高8位地址(用于寻址时是输出口、不寻址时是准双向口);3.0—P3.7: 具有特定的第二功能(准双向口)[1]。注意:在不外扩ROM/RAM时,P0~P3均可作通用I/O口使用,而且都是准双向I/O口;并且P0口需外接上拉电阻,P1—P3可接也可不接,但用作输入时都需要先置“1”。
3.2 单片机最小系统
单片机最小系统主要由电源、复位、振荡电路以及扩展部分等部分组成。
对于一个完整的电子设计来讲,首要考虑的就是为整个系统提供电源的供电模块,电源模块的稳定可靠是系统平稳运行的前提和基础。最小系统中的电源供电模块的电源可以通过计算机的USB口供给,也可使用外部稳定的5V电源供电模块供给。
复位电路由按键复位和上电复位两部分组成。单片机的置位和复位,都是为了把电路初始化到一个确定的状态,一般来说,单片机复位电路作用是把一个例如状态机初始化到空状态,而在单片机内部,复位的时候单片机是把一些寄存器以及存储设备装入厂商预设的一个值。单片机复位电路原理是在单片机的复位引脚RST上外接电阻和电容,实现上电复位。当复位电平持续两个机器周期以上时复位有效。复位电平的持续时间必须大于单片机的两个机器周期。
最小系统里都有晶振,在单片机系统里晶振作用非常大,全称叫晶体振荡器,它结合单片机内部电路产生单片机所需的时钟频率,单片机晶振提供的时钟频率越高,那么单片机运行速度就越快,单片机接的一切指令的执行都是建立在单片机晶振提供的时钟频率上[6]。
如图3.1所示,为单片机最小系统电路图。
图3.1 单片机最小系统电路图
3.3 超声波模块
3.3.1 超声波发射模块
发射电路由脉冲产生电路和发射电路组成。脉冲产生电路的主要任务是产生40KHz 脉冲电压。它由与非门和电阻电容构成振荡电路,由STCC52芯片的P3.3口控制其是否工作。脉冲产生电路的输出电压经脉冲变压器升压后输出到超声波传感器[3]。其中,脉冲变压器对脉冲电压变换值的大小直接影响测距范围,应尽量提供脉冲变压器副边电压幅值。
如图3.2所示,为超声波发射电路。
图3.2 超声波发射电路
3.3.2 超声波接收模块
接收电路的主要任务是检测回波,并向STCC52芯片发出中断以停止计时,由STCC52芯片的P3.2口控制其是否工作。接收电路设计的好坏直接影响超声波在空气中传播时间的测量。
接收部分电路由检波电路、滤波放大电路和整形电路组成。检波电路拾取
回波中的正半波,以便后级电路放大;整形电路把回波信号整理为STCC52芯片能够接收的信号并向STCC52芯片申请中断以停止计时。接收电路的主体是滤波放大电路。由于超声回波信号十分微弱并含有噪声,S/N较小,所以接收电路设置了两级高Q值的滤波放大电路[2]。滤波放大电路采用二阶带通滤波放大器,一级和二级滤波放大电路采用相同的结构和参数。
如图3.3所示,为超声波接收电路。
图3.3 超声波接收电路
3.4 LED数码管显示模块
显示器是一个典型的输出设备,而且其应用是极为广泛的,几乎所有的电子产品都要使用显示器,其差别仅在于显示器的结构类型不同而已[7]。最简单的显示器可以使LED 发光二极管,给出一个简单的开关量信息,而复杂的较完整的显示器应该是 CRT监视器或者屏幕较大的 LCD 液晶屏。
综合课题的实际要求以及考虑单片机的接口资源,采用串行方式显示的 LED 驱动输出设备。由于测试所得的距离需要精确到小数点后1位,所以本设计采用 3 个 LED 数码管来表示距离的cm数值。
本设计采用共阳级数码管,我们将LED数码管显示模块上的J1上的8个端口与STC51芯片上的P0.0—P0.7相连接,作为段选;再将J2上的3个端口与STCC52芯片上的P2.1—P2.3相连接,作为位选。
如图3.4所示,为LED数码管显示电路。
图3.4 LED数码管显示电路
3.5 报警模块
系统报警电路由一个运算放大器、一个发光二极管和一个喇叭组成。R25的阻值为1K,R26的阻值为10K。对于二级运算放大,都采用F007芯片,两级放大电路均是负反馈接法,即反相比例运算电路。而反相比例运算电路中,输入信号从反相输入端输入,同相输入端接地。根据“虚短”和“虚断”的特点,即u-=u+,i-=i+=0。可得u+=0。而所谓“虚短”是由于理想集成运放Au0[10]。
如图3.5 所示,为报警电路。
图3.5 报警电路
4 系统软件设计
4.1 Keil uVision3软件介绍
Keil uVision3开发工具提供数个十分有用的特性可以帮助你快速地成功开发嵌入式应用,这些工具使用简单并保证达到你的设计目的。
Keil uVision3是一个基于Window的开发平台,包含一个高效的编辑器、一个项目管理器和一个MAKE工具。Keil uVision3支持所有的KEIL8051工具,包括C编译器宏汇编器连接/定位器目标代码到HEX的转换器。
Keil uVision3通过以下特性加速你的嵌入式系统的开发过程:
(1)全功能的源代码编辑器;
(2)器件库用来配置开发工具设置;
(3)项目管理器用来创建和维护你的项目;
(4)集成的MAKE工具可以汇编编译和连接你的嵌入式应用;
(5)所有开发工具的设置都是对话框形式;
(6)真正的源代码级的对CPU和外围器件的调试器;
(7)高级GDIAGDI接口用来在目标硬件上进行软件调试以及和Monitor-51进行通信;
(8)与开发工具手册和器件数据手册和用户指南有直接的链接。
4.2 软件流程图
超声波测距器的软件设计主要由主程序、超声波发生子程序、超声波接收中断程序及显示子程序组成。
软件主要分为两个部分:主程序和中断服务程序。如图4.1所示,为软件流程图,左图为主程序流程图,右图为中断服务程序流程图。主程序完成初始化工作、超声波发射和接收的控制等。中断服务程序主要完成时间值的读取、距离计算、结果的输出等工作。
图4.1 软件流程图
4.3 系统的软件调试
超声波测距仪的制作和调试都比较简单,其中超声波发射和接收采用Φ15的超声波换能器TCT40-10F1(T发射)和TCT40-10S1(R接收),中心频率为40kHz,安装时应保持两换能器中心轴线平行并相距4~8cm,其余元件无特殊要求。若能将超声波接收电路用金属壳屏蔽起来,则可提高抗干扰能力。根据测量范围要求不同,可适当调整与接收换能器并接的滤波电容C0的大小,以获得合适的接收灵敏度和抗干扰能力[5]。
硬件电路制作完成并调试后(硬件连接图见附录1),将编译好的软件程序下载到STCC52芯片中(软件的调试程序清单见附录2),然后与单片机实践平台连接:
(1)LED数码管段选P0.0—P0.7与实践平台显示模块上J1八个接口相连;
(2)LED数码管位选P2.1—P2.3与实践平台显示模块上J2三个接口相连;
(3)超声波模块上的信号输入接口与芯片上的P3.3相连;
(4)超声波模块上的信号输出接口与芯片上的P3.2相连;
(5)接地线与按键模块的J3相连。
初次调试结果没成功,LED数码管没有任何显示,小组成员的硬件也出现同样结果,经观察尝试下,问题出在接地线所接的按键模块的J3接口上,总共有两个接口,分为上下两个,我们原先插的是下面那个,换成上面那个接口,数码管有显示了。
再次调试,出现了新问题,只显示十位和百位,各位无法显示。当时的位选是芯片的P2.0—P2.2。多次尝试小组成员的硬件,结果一样,所以我们决定换位选端口,变为P2.1—P2.3。最后调试成功,数码管正常显示距离,保留一位小数,最大距离达到50cm左右,但警报功能无法实现。
如图4.2所示,为调试实物图,测得障碍物的距离为33.6厘米。
图4.2 调试实物图
5 设计总结
首先,我要感谢我们的指导老师在毕业设计中给予我的细心指导和严格要求。在这为期两周的毕业设计期间,各位老师给我提供了各种专业知识上的指导和日常生活上的关怀,没有您们这样的帮助和关怀,我不会这么顺利的完成毕业设计,借此机会,向您们表示由衷的感激。同时还要感谢系实验室在毕业设计期间提供给我们优越的实验条件。
接着,我要感谢和我一起完成毕业设计的小组成员。在毕业设计的短短两个星期里,你们给我提出很多宝贵的意见,给了我不少帮助还有工作上的支持,在此也真诚的谢谢你们。同时,我还要感谢我的寝室同学和身边的朋友,正是在这样一个团结友爱,相互促进的环境中,在和他们的相互帮助和启发中,才有我今天的小小收获。
基于单片机控制的超声波测距报警系统设计终于顺利完成,在整个设计过程中,出现过很多的难题,但都在老师的帮助以及小组成员全力合作下得到了顺利的解决,在不断的学习过程中我体会到要成功地完成一个设计,我们必须要把理论和实际结合起来,光学会理论是远远不够的,并且我们还要具备永不言败的精神。
总之,通过毕业设计,我刻体会到要做好一个完整的事情,需要有系统的思维方式和方法,对待要解决的问题,要耐心、要善于运用已有的资源来充实自己。同时我也深刻的认识到,在对待一个新事物时,一定要从整体考虑,完成一步之后再作下一步,这样才能更加有效。
参考文献
[1]徐瑞华.单片机原理与接口技术[M].北京:人民电邮出版社,1997.1
[2]苏长赞.红外线与超声波遥控[M].北京:人民电邮出版社,1993.7
[3]张谦琳.超声波检测原理和方法[M].北京:中国科技大学出版社,1993.10
[4]李华.51系列单片机实用接口技术[M].北京:北京航空航天大学出版社,1993.6
[5]陈莹.基于单片机的超声波测距系统[M].武汉: 武汉华中科技大学出版社,2004.4
[6]徐淑华.单片机微型机原理及应用[M].哈尔滨:哈尔滨工业大学出版社,1999.6
[7]陈光东.单片机微型计算机原理与接口技术[M].武汉:华中理工大学出版社,1994.4
[8]建兵.超声波精确测距的研究[M].南京:南京理工大学出版社,2004.2
[9]时德刚.超声波测距的研究[M].南京:南京理工大学出版社,2004.2
[10]华兵.51系列单片机原理应用[M].武汉:武汉华中科技大学出版社,2002.5
附录
附录1 硬件连接图
附录2 程序清单
//超声波模块显示程序
#include #define uchar unsigned char //定义一下方便使用 #define uint unsigned int #define ulong unsigned long sbit Tx = P3^3; //产生脉冲引脚 sbit Rx = P3^2; //回波引脚 uchar code SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管0-9 uint distance[4]; //测距接收缓冲区 uchar ge,shi,bai,temp,flag,outcomeH,outcomeL,i; //自定义寄存器 bit succeed_flag; //测量成功标志 //*************************************************************** //函数声明 void conversion(uint temp_data); void delay_20us(); void pai_xu(); //*************************************************************** // 主程序 void main(void) { uint distance_data,a,b; uchar CONT_1; i=0; flag=0; Tx=0; //首先拉低脉冲输入引脚 TMOD=0x11; //定时器0,定时器1,16位工作方式 TR0=1; //启动定时器0 IT0=0; //由高电平变低电平,触发外部中断 ET0=1; //打开定时器0中断 EX0=0; //关闭外部中断 EA=1; //打开总中断0 while(1) //程序循环 { EA=0; Tx=1; delay_20us(); Tx=0; //产生一个20us的脉冲,在Tx引脚 while(Rx==0); //等待Rx回波引脚变高电平 succeed_flag=0; //清测量成功标志 EX0=1; //打开外部中断 TH1=0; //定时器1清零 TL1=0; //定时器1清零 TF1=0; // TR1=1; //启动定时器1 EA=1; while(TH1 < 30); //等待测量的结果,周期65.535毫秒(可用中断实现) TR1=0; //关闭定时器1 EX0=0; //关闭外部中断 if(succeed_flag==1) { distance_data=outcomeH; //测量结果的高8位 distance_data<<=8; //放入16位的高8位 distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据 distance_data*=12; //因为定时器默认为12分频 distance_data/=58; //微秒的单位除以58等于厘米 } //为什么除以58等于厘米, Y米=(X秒*340)/2 // X秒=( 2*Y米)/340 ==》X秒=0.0058*Y米 ==》厘米=微秒/58 if(succeed_flag==0) { distance_data=0; //没有回波则清零 } distance[i]=distance_data; //将测量结果的数据放入缓冲区 i++; if(i==3) { distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4; pai_xu(); distance_data=distance[1]; a=distance_data; if(b==a) CONT_1=0; if(b!=a) CONT_1++; if(CONT_1>=3) { CONT_1=0; b=a; conversion(b); } i=0; } } } //*************************************************************** //外部中断0,用做判断回波电平 INTO_() interrupt 0 // 外部中断是0号 { outcomeH =TH1; //取出定时器的值 outcomeL =TL1; //取出定时器的值 succeed_flag=1; //至成功测量的标志 EX0=0; //关闭外部中断 } //**************************************************************** //定时器0中断,用做显示 timer0() interrupt 1 // 定时器0中断是1号 { TH0=0xfd; //写入定时器0初始值 TL0=0x77; switch(flag) {case 0x00:P0=ge; P2=0xfd;flag++;break; case 0x01:P0=shi;P2=0xfb;flag++;break; case 0x02:P0=bai;P2=0xf7;flag=0;break; } } //*************************************************************** //显示数据转换程序 void conversion(uint temp_data) { uchar ge_data,shi_data,bai_data ; bai_data=temp_data/100 ; temp_data=temp_data%100; //取余运算 shi_data=temp_data/10 ; temp_data=temp_data%10; //取余运算 ge_data=temp_data; bai_data=SEG7[bai_data]; shi_data=SEG7[shi_data]&0x7f; ge_data =SEG7[ge_data]; EA=0; bai = bai_data; shi = shi_data; ge = ge_data ; EA=1; } //****************************************************************** void delay_20us() { uchar bt ; for(bt=0;bt<60;bt++); } void pai_xu() { uint t; if (distance[0]>distance[1]) {t=distance[0];distance[0]=distance[1];distance[1]=t;} if(distance[0]>distance[2]) {t=distance[2];distance[2]=distance[0];distance[0]=t;} if(distance[1]>distance[2]) {t=distance[1];distance[1]=distance[2];distance[2]=t;} }下载本文