北邮小学期pic单片机超声波测距仪实验报告附代码.docx
《北邮小学期pic单片机超声波测距仪实验报告附代码.docx》由会员分享,可在线阅读,更多相关《北邮小学期pic单片机超声波测距仪实验报告附代码.docx(43页珍藏版)》请在冰豆网上搜索。
![北邮小学期pic单片机超声波测距仪实验报告附代码.docx](https://file1.bdocx.com/fileroot1/2023-2/11/bcf4b789-8f01-4fe6-9e38-e3e003ceff35/bcf4b789-8f01-4fe6-9e38-e3e003ceff351.gif)
北邮小学期pic单片机超声波测距仪实验报告附代码
2014年小学期单片机设计实验报告
题目:
超声波测距仪
实验摘要
目前常用测量距离都采用波在介质中的传播速度和时间关系进行测量。
常用的技术有激光测距、微博测距和超声波测距三种。
前两种测量精度很高,电路复杂,价格昂贵。
而超声波具有指向性强、能量消耗缓慢且在介质中传播的距离较远的优点,经常用于距离的测量。
超声波测距主要应用于建筑工地,以及一些工业现场和移动机器人的研制上,可在超市高温,多尘等恶劣环境下工作。
可用于测量液位、厚度、管道长度等场合。
相比于其他定位技术而言,超声波定位技术成本低、精度高、操作简单、工作稳定可靠,非常适合于短距离测量定位。
PIC单片机为许多控制提供了高度灵活和低成本的解决方案,充分利用PIC单片机的片内资源,加上极少量的外围电路就可以组成一个完整的超声波测距系统。
我们设计了以PIC16F877单片机为核心的低成本的超声波测距系统。
使用74HC04设计超声波发射驱动电路,提高输出功率;使用运算放大器和比较器构成超声波接受电路,使得超声波能够正确地被识别出来;使用LCD1602液晶显示屏显示测出的距离。
而单片机负责产生超声波信号、记录超声波传播的时间并计算距离。
Abstract
Nowcommonlyusedtomeasuredistanceusingwavepropagationvelocityinthemediumandtherelationshipbetweentimemeasurement.Commonlyusedtechnologyoflaserranging,microwaverangingandultrasonicranging.Thefirsttwomeasurementprecisionishigh,circuitiscomplex,expensive.Andultrasoundhasstrongdirectivity,energyconsumptionslowandtheadvantagesofdistanceinthemediumtospread,oftenusedfordistancemeasurement.Ultrasonicrangingismainlyusedinconstructionsites,aswellassomeindustrialfieldandthedevelopmentofthemobilerobotcanheatinthesupermarket,dustyworkunderthebadenvironment,etc.Canbeusedtomeasuretheliquidlevel,thickness,pipelength,etc.Comparedtootherpositioningtechnology,ultrasonicpositioningtechnologyoflowcost,highprecision,simpleoperation,stableandreliablework,isverysuitableforshortdistancemeasurement.PICmicrocontrollerformanycontrolprovidesahighlyflexibleandlowcostsolution,makefulluseofthePICmicrocontrollerchipresources,plusasmallamountofperipheralcircuitcouldformacompleteultrasonicrangingsystem.
WehavedesignedwithPIC16F877single-chipmicrocomputerasthecoreoflow-costultrasonicrangingsystem.Using74hc04ultrasoniclaunchdrivercircuitdesign,improvetheoutputpower;Usingoperationalamplifierandacomparatorultrasonicreceivingcircuit,makestheultrasonicwerecorrectlyidentified;UseLCD1602LCDdisplaytomeasurethedistance.Andultrasonicsignal,generatedbythemicrocontrollerisresponsiblefortherecordsofultrasonictransmissiontimeandcalculatethedistance.
关键字
单片机——microcontroller
芯片——CMOSchip
超声波探测——infrareddetector
一.实验论证与比较
1.超声波发射电路
超声波发射电路主要由超声波发射传感器和超声波功率放大驱动电路构成,电路如下图。
在图中,由单片机输出的方波信号分成两路,一路经过U2D和U2E并联后的一级反向后加到超声波传感器的一个电极上;另一路先经过U2A一级反向送到U2B和U2C并联后的反向加到超声波传感器的另一个电极上。
采用U2B、U2C以及U2D、U2E的并联电路以目增加输出功率,提高测量距离。
电容C1和C2起信号的耦合作用,同时也起到隔离直流作用。
电阻R1和R2在此处用于提高超声波传感器的阻尼效果,以缩短阻尼振荡的时间,同时也提高输出驱动能力。
示波器中观测到的输出波形(输入波形是峰峰值为5V的方波):
2.超声波接收电路
设计的超声波接收电路如下图所示。
由超声波传感器RECV将接收到的返回波信号转换成电信号由电容C1耦合到U1集成运算放大器的反向输入端,,并由U1A和U1B运算放大器构成的两级信号的同相放大,两级总的放大倍数为440左右。
放大后的返回波信号由U1B输出,经电压比较器后输出形成方波,当检测到第一个有效的返回波时,就触发单片机中断进行处理。
由于一般返回的超声波信号比较弱,特别是在测量距离比较远的时候,返回的超声波就更弱,要能够检测到有效的返回超声波信号,必须将返回波信号进行足够的放大,图中采用了两级放大。
第一级放大倍数由R5和R3决定,放大倍数约为1+39/1=40。
第二级放大倍数由R6和R4决定,放大倍数约为1+10/1=11。
从而总的放大倍数约为440
理论上来讲,放大倍数越大,测量距离越远,超声波测距仪性能越好。
但实际搭建电路后我们发现,在放大倍数比较大时(如600),接收电路会产生自激现象,无法使单片机正确地进入中断,这一点在后面有详细说明。
由multisim仿真结果可知:
输出是峰峰值为5V的方波,从而可以使单片机产生中断。
实际波形和仿真结果相似,波形更好,但当时忘记拍图。
3.单片机最小系统与显示电路
上图为单片机的最小系统与显示电路图。
二.系统总体设计
1.硬件总体框图
电路开始工作后,由单片机产生信号并开始计时,经过功率放大电路后将超声波发射出去,超声波遇到障碍物后反弹回到超声波接收器,经过信号调理电路后触发单片机中断并停止计时。
由单片机算出距离后送LCD显示距离。
2.软件流程图
主程序流程图如下图。
首先进行变量的初始化,单片机每隔1s产生8个周期的信号。
先判断1s定时是否到了,如果到了则系统发射8个连续的超声波脉冲,然后进行约0.8ms的短延时并开启INT中断;否则继续等待。
使用短延时是为了消除余波的影响。
发送出超声波之后判断接收时间是否超过2s,如果超过两秒,说明没有接收到回波,此时返回1s定时;如果2s内接收到回波,则关闭中断并取时间,计算距离然后送显,再回到1s定时处。
中断服务程序流程图如下图
进入中断程序后,首先判断是否为INT产生的中断,如果是说明接收到有效的回波,此时清楚INT终端标志位;否则直接去判断是否为TMR0产生的中断。
如果是TMR0溢出产生的中断,则接下来要判断1s定时是否结束,如果1s定时结束,则清楚计数标志并继续判断2s超时计时是否到了,如果1s定时未结束,则只需将相应计数变量加1。
如果超时计时结束,则清除相应标志,否则只需将相应计数变量加1。
三.硬件连接
1.接收电路部分
2.总电路
3.焊接后的发射和接收电路
四.调试过程
电路部分
我主要负责的部分是电路的设计和调试,以及最终的焊接工作。
电路的设计主要包括两个模块:
超声波发射电路、超声波接收电路;设计原理以及电路图都在前文中有详细描述,在此不再赘述。
但是电路的搭建和调试过程却遇到了很多问题:
1.超声波发射电路:
我们采用的是型号为74HC04N的芯片,此芯片的作用是用于放大单片机产生的超声波信号的功率。
一开始使用multisim做仿真,但是搭建好电路之后仿真出错,始终找不到解决方法,所以直接进行实测,幸运的是实测结果还比较满意。
2.超声波接收电路:
1在用multisim仿真第一级放大电路的过程中,一开始将信号从放大芯片TL082CM的同相输入端输入,但是始终没有波形输出,多次查找资料后发现是电路设计的错误,信号需要从放大器的反向输入端输入,从而将问题解决。
2设计放大倍数上,初始设定为
倍,但是经过仿真发现第一级放大倍数始终达不到101,于是我就去上网查找芯片的参数,后来我从芯片的使用资料中发现单级放大倍数达不到101,但是为了满足上千倍的放大倍数要求,经过多次仿真及测试,我们将放大倍数定为
倍。
3在面包板上将电路搭建好之后,发现第二级放大电路不起作用,多番检查电路也没有找到原因,但是在multisim仿真中是有作用的;在老师的帮助下,发现没有对第二个芯片进行供电。
因为芯片TL082CM内部有两个放大器,而我在电路中却用了两个TL082CM,每一个只用其中一个放大器,但是在multisim中仿真却用了一个芯片中的两个放大器,所以在原理图中可以发现第二级放大电路的芯片没有进行直流供电。
我对着multisim中的电路直接在面包上进行搭建,所以导致没有对第二个芯片进行供电。
4进行两级放大之后需要将正弦波形整形成方波,我一开始的设想是用两个二极管和一个三极管构成对检波电路,但是在实测中发现整形效果很差,不能认定为方波,所以将其放弃了;并使用一个型号为LM393的芯片设计了一个电压比较器电路(理论输出高电平为
,低电平为
),实际输出波形非常完美(比仿真结果要好很多),误差为
左右,在误差允许范围内。
5在我们编写完程序并调试完成后,我们开始整机调试,发现输出结果总是
!
我们尝试了很多方法都没有检测出原因所在,后来在老师的帮助下,发现是接收电路出现了自激现象。
出现的原因是放大倍数太大(一开始设计为1200倍左右,实测为900倍左右)。
为了解决自激问题,我们尝试了以下办法:
Ⅰ.将放大倍数缩小,从一开始的1200倍一直往下降,并不断地测试是否产生自激,虽然降到100左右的时候自激现象消失了,但是如此小的放大倍数并不足以满足电路的实际要求,经过计算,我们认为放大倍数需要400倍左右才能满足电路的设计要求,于是我们将电路的放大倍数改为440倍左右。
Ⅱ.设计了最简单的电容滤波,将一个电容直接接地,发现所有信号都被过滤了;后来我们从示波器中发现,自激信号的频率为170kHz的倍频信号,而超声波信号为40kHz,于是我就尝试设计了一个二阶低通滤波器并将截止频率设为70kHz,理论上可行,在multisim上仿真时效果一般,但是实测效果更差,自激现象仍然存在,于是我们就放弃了这个方法。
Ⅲ.我们又发现,自激信号的最小值为
左右,所以我们就用了另一种办法,将电压比较器的比较电压降低,从而使得自激信号经过电压比较器之后编程高电平,这样就不会有上升沿使得单片机产生中断。
经过计算,我将比较电压设置为
左右(由原理图可以计算),从而解决了自激的问题。
程序部分:
1.计算路程的优化算法
我们选择计算距离的方法是用乘除法进行计算(
),但是汇编语言中并不能直接调用乘除法,于是我们不得不自己编写乘除法的程序,由于涉及数值较大,所以我们需要实现
的乘法算法,即将每一个数分高8位低8位分别存在两个寄存器中,然后进行操作,具体实现过程不再赘述。
除法也是类似的原理,只不过我们的除法是实现的整数除法,将余数直接舍弃了,虽然损失了最终结果的精度,但极大地简化了程序设计过程,而且只要对最终结果修正,那么最终结果的误差也是可以接受的。
编写好乘除法程序之后,我就对其进行调试,乘法程序没有问题,但是除法程序对于一些数的计算总是出错,在调试过程中发现是寄存器的溢出问题:
由于程序实现的是对有符号数进行乘法运算,就意味着有寄存中的最高位成为符号位,但是从乘法运算的结果存在4个寄存器中,符号位存在高16位寄存器的最高位,而我只需要低16位就足以满足我们计算要求,所以没有遇到问题。
但是在除法中,除法运算的结果只保存在2个寄存器中,而对于有符号数,就意味着最大数值只能为32767(65536的一半),为了满足这个要求,同时为了减小精度的损失,我们经过计算,决定对路程的计算过程进行改动。
首先将单片机TIMER1计算的时间进行除以100,然后乘以声速
(原因稍后解释),然后除以10,得到的结果单位就为
了。
经我们计算发现,这种办法既可以避免在乘以191之后的数值超过32767,从而使得除以10调用除法程序的时候寄存器产生溢出的情况,也可以最大限度地减小计算误差,经过计算,这种算法最大误差为
,如果直接对时间T除以1000再乘以声速
,最大误差可能打到
!
这个误差使我们不能接受的,而我们的方法极大地减小了误差!
将声速定为
的原因:
室温下声速为
,我们将其折半为
,这样就免去了对时间T进行折半,减小了调用除法程序带来的误差,同时为了修正最终的结果(路程),我们将声速定为
,这样最终的结果误差就在可以接受范围内了。
2.单片机的中断
1由于之前一直学习的都是高级语言的程序设计,在学习单片机之前我并没有接触过中断这个概念,所以第一次使用这个功能的时候还是出现了很多的问题。
我们的程序原本设定的时候是使用三个中断,一是用TIMER1计时溢出时产生的中断,我们将TIMER1用于超声波发出到接收所花的时间;二是当单片机接收到外来超声波的上升沿时产生的外部中断(INT0);三是用TIMER0产生的中断。
相对来说,外部中断和TIMER0产生的中断我们的处理方式都没有问题,但是TIMER1产生的中断着实让我们无法理解。
我们在调试程序过程中发现,TIMER1中断不受控制,总是在不该进入中断的时候却进入中断请求程序,这就意味着我们无法准确地进行路程的计算。
我们尝试了多种解决办法,并和老师进行了长达一个多小时的探讨,发现都无法解决这个问题。
然后我们又一次通过计算解决了这个问题!
我们发现,TIMER1计时溢出意味着用时达到
,也就是路程达到了
,但实际上,我们远远达不到这个距离,也就是说,我们需要的时间远远达不到
,即TIMER1不会产生溢出中断!
于是我们决定将TIMER1的中断服务程序去掉,以免造成不可控制的误差。
2进入中断恢复现场的问题:
一开始的时候,我们调试发现,程序进入中断之后再次跳出时我们的计时器便不能重新开始计时,有时候又可以。
经过单步调试发现,由于个别中断程序的出口没有对计数器器进行恢复,导致计数器工作异常。
在修改程序之后这个问题得到了解决。
3.定时器
从流程图中可以看出,我们的程序有两个地方需要定时器,一是每次发超声波之前需要等待
;二是每次超声波发出之后,程序会有一个
的等待时间,若超出这个时间则认为此次超声波接收超时,准备下一次超声波的发射。
为了降低程序设计的难度,我们用TIMER0产生一个
的定时器,然后用两个变量控制TIMER0产生
的次数。
例如:
当一个变量的值打到128时,我们就认为时间到了
;同理,当另一个变量达到256时,我们就认为时间到了
。
虽然不太准确,但这不影响程序的结果,但是降低了难度,因为判断是否到了128或者256时,我们只需要判断bit7或者进位标志位,避免了对两个数进行直接比较的情况,极大地减小了代码的复杂程度。
同时,这样一种设计思路,也实现了计数器的高效率使用,避免了使用两个计数器实现两个定时器的代码重复现象,同时降低程序设计的难度,减小了程序出错的可能性,便于调试。
我们认为这是一种很便捷的设计思路,值得大家去借鉴。
4.在线调试时发现计数器的值与理论指令执行时间不一致
在不接单片机进行调试时,我们用STOPWATCH窗口查看程序运行的时间,观察发现每条指令的执行时间为
或
,与老师提供的学习资料中的介绍一致。
但接了单片机之后,我们在线单步调试时却发现跳转指令执行后计数器(未分频)的值有大幅跳变,与不接单片机调试时的情况不同!
让我们一度以为程序出了bug,经过和老师的探讨以及老师耐心地解释,我们得知是编译器本身的问题,与程序本身无关。
5.最小量程
正如前面所说,当出现自激时液晶屏的显示结果总是
,我们一度以为是超声波接收和发射探头的最小反应时间,但是我们经过对代码的仔细推敲之后发现,这并不是硬件的限制,是我们的代码决定了这个理论测量的最小值!
原因如下:
在我们的程序中,发射超声波的程序结束之后设计了一个约
的延时,目的是减少回波造成的影响,但也正因这个延时,导致了我们所测量的距离有最小值。
这个最小值应该为
,也正是我们一直出现的最小值
!
(因为误差修正是在整个程序无误之后才进行的,所以在我们调试过程中我们的声速都是设置为
)
我们发现问题之后,我的队友就将延时降低到了
,从而减小了最小量程。
6.实验误差
前面提到,我们将计算路程的算法优化之后理论误差最大为
,但实际测量发现,误差较大,这是由于不仅仅有计算误差,还有单片机本身的计时误差(振荡频率不是4MHz),以及声速的误差等等。
经过我们反复测量不同的距离,发现测量值与实际距离相差约0.113倍,我们将1.1乘以声速
得到
,用该值作为修正值参与运算,结果却是当实际距离小于
时误差不超过
,这也说明我们的分析是没错的!
7.接收到的信号较弱
前面提到,为了解决自激现象,我们降低了放大倍数,导致接收到的信号难以有效放大,从而导致整套装置的反应时间较长,经常出现无法测量的情况。
正当我们愁眉苦展之时,我发现实验室有一个金属盒子(其实就是路由器),我尝试将其当作障碍物(之前都是拿书本当障碍物),效果非常明显!
我们用这个装置发现测距的最大距离达到
!
五.实验心得和体会
六.参考文献
PIC单片机实用教程——基础篇(五号宋体)
李学海
北京航空航天大学出版社
PIC单片机实用教程——提高篇
李学海
北京航空航天大学出版社
1.孙安青.PIC系列单片机开发实例精解[M].中国电力出版社:
孙安青,2011.380-399
附上代码:
LISTp=16f877
INCLUDE"p16f877.inc"
;;;;;;;;;;;;;;VARIABLEDEFINITION;;;;;;;;;;;;;;;;
TIMER1HIGHCOUNTEREQU20H
SECONDOKFLAGEQU21H
SECONDCOUNTEREQU22H
RECEIVEOKFLAGEQU23H
TIMERINTERVALEQU24H
TIMERENABLEEQU25H
WTEMPEQU26H
STATUSTEMPEQU27H
COUNT1EQU28H;产生40KHZ时所用的计数器
DINGSHIEQU29H;1MS延时程序定时器
ACCALOEQU30;存放乘数低8位
ACCAHIEQU31;存放乘数高8位
ACCBLOEQU33;存放被乘数低8位和乘积第16-23位
ACCBHIEQU34;存放被乘数高8位和乘积第24-31位
ACCCLOEQU36;存放乘积低8位
ACCCHIEQU37;存放乘积高8位
ACCDLOEQU38;临时寄存器
ACCDHIEQU39;临时寄存器
TEMPEQU3A;临时寄存器
SIGNEQU3B;存放乘积符号
;*************************************
BCCALOEQU40
BCCAHIEQU41
BCCBLOEQU42
BCCBHIEQU43
BCCCLOEQU44
BCCCHIEQU45
BCCDLOEQU46
BCCDHIEQU47
TEMP_BEQU48
SIGN_BEQU49
YCCBLOEQU50H
YCCBHIEQU51H
YCCCLOEQU52H
YCCCHIEQU53H
YCCDLOEQU54H
YCCDHIEQU55H
TEMP1EQU56H
SIGN1EQU57H
COUNT2EQU58H
BCD_LEQU59H
BCD_HEQU5AH
ASCII_HEQU5BH
ASCII_LEQU5CH
TAB_TEMEQU5DH
BCDEQU5EH
FINAL1_HEQU5FH
FINAL1_LEQU60H
FINAL2_HEQU61H
FINAL2_LEQU62H
FINAL3_HEQU63H
FINAL3_LEQU64H
delMequ65h;定义两个延时变量寄存器
delNequ66h
delKequ67h;定义一个内层循环延时常数
ORG0X0000
STARTGOTOMAIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;INTERRUPTPROGRAM;;;;;;;;;;;;;;;;;;
ORG0X004
ZHONGDUAN
NOP
MOVWFWTEMP;protecttheoriginalcondition
MOVFSTATUS,0
MOVWFSTATUSTEMP
;;;;最外层3个if;;;
;;;;;;;;;;;;;;;CHECKTIMER1;检查if(1==PIR1bits.TMR1IF)
;;;;;;;;;;;;;;;BTFSCPIR1,0;if(1==PIR1bits.TMR1IF)
;;;;;;;;;;;;;;;GOTOTIMER1IF;1==PIR1bits.TMR1IF时进入TIMER1IF,否则继续检查if(1==INTCONbits.INT0IF)
CHECKINT0;检查if(1==INTCONbits.INT0IF)
BTFSCINTCON,1;if(1==INTCONbits.INT0IF)
GOTOINT0IF;1==INTCONbits.INT0IF时进入INT0IF,否则继续检查i