Ⅰ 谁能给我一篇超声波测距的程序的谢谢了
相关资料,请参考
超声波测距仪设计及其应用分析
[摘要] 本文利用超声波传输中距离与时间的关系,采用AT89C51单片机进行控制及数据处理,设计出了能精确测量两点间距离的超声波测距仪。该测距仪主要由超声波发射器电路、超声波接收器电路、单片机控制电路、环境温度检测电路及显示电路构成。利用所设计出的超声波测距仪,对不同距离进行了测试,并进行了详尽的误差分析。
[关键词] 超声波测距 单片机 温度传感器
随着社会的发展,人们对距离或长度测量的要求越来越高。超声波测距由于其能进行非接触测量和相对较高的精度,越来越被人们所重视。本设计的超声波测距仪,可以对不同距离进行测试,并可以进行详尽的误差分析。
一、设计原理
超声测距仪是根据超声波遇到障碍物反射回来的特性进行测量的。超声波发射器向某一方向发射超声波,在发射同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即中断停止计时。 通过不断检测产生波发射后遇到障碍物所反射的回波,从而测出发射超声波和接收到回波的时间差T,然后求出距离L。基本的测距公式为:L=(△t/2)*C
式中 L——要测的距离
T——发射波和反射波之间的时间间隔
C——超声波在空气中的声速,常温下取为340m/s
声速确定后,只要测出超声波往返的时间,即可求得L。
二、超声波测距仪设计目标
测量距离: 5米的范围之内;通过LED能够正确显示出两点间的距离;误差小于5%。
三、数据测量和分析
1.数据测量与分析
由于实际测量工作的局限性,最后在测量中选取了一米以下的30cm、50cm、70cm、80cm、90cm、100cm 六个距离进行测量,每个距离连续测量七次,得出测量数据(温度:29℃),如表所示。从表中的数据可以看出,测量值一般都比实际值要大几厘米,但对于连续测量的准确性还是比较高的。
对所测的每组数据去掉一个最大值和最小值,再求其平均值,用来作为最终的测量数据,最后进行比较分析。这样处理数据也具有一定的科学性和合理性。从表中的数据来看,虽然对超声波进行了温度补偿,但在比较近的距离的测量中其相对误差也比较大。特别是对30cm和50cm的距离测量上,相对误差分别达到了5%和4.8%。但从全部测量结果看,本设计的绝对误差都比较小,也比较稳定。本设计盲区在22.6cm左右,基本满足设计要求。
2.误差分析
测距误差主要来源于以下几个方面:
(1)超声波发射与接收探头与被测点存在一定的角度,这个角度直接影响到测量距离的精确值;(2)超声波回波声强与待测距离的远近有直接关系,所以实际测量时,不一定是第一个回波的过零点触发;(3)由于工具简陋,实际测量距离也有误差。影响测量误差的因素很多,还包括现场环境干扰、时基脉冲频率等等。
四、应用分析
采用超声波测量大气中的地面距离,是近代电子技术发展才获得正式应用的技术,由于超声测距是一种非接触检测技术,不受光线、被测对象颜色等的影响,在较恶劣的环境(如含粉尘)具有一定的适应能力。因此,用途极度广泛。例如:测绘地形图,建造房屋、桥梁、道路、开挖矿山、油井等,利用超声波测量地面距离的方法,是利用光电技术实现的,超声测距仪的优点是:仪器造价比光波测距仪低,省力、操作方便。
超声测距仪在先进的机器人技术上也有应用,把超声波源安装在机器人身上,由它不断向周围发射超声波并且同时接收由障碍物反射回波来确定机器人的自身位置,用它作为传感器控制机器人的电脑等等。由于超声波易于定向发射,方向性好,强度好控制,它的应用价值己被普遍重视。
总之,由以上分析可看出:利用超声波测距,在许多方面有很多优势。因此,本课题的研究是非常有实用和商业价值。
五、结论
本设计的测量距离符合市场要求,测量的盲区也控制在23cm以内。针对市场需求,本设计还可以加大发射功率,让测量的距离更加的远。在显示方面,也可以对程序做适当改动,使开始发射超声波时LED显示出温度值,到超声波回波接收到以后通过计算得出距离值时,LED自动切换显示距离值,这样在视觉效果上得到更加直观的了解。
参考文献:
[1]MCS一51/96系列单片机原理及应用(修订版)[M].北京:北京航空航天大学出版社.2002.46-170
[2]金篆芷王明时:现代传感器技术[M].电子工业出版社.1995.331—335
[3]MCS一51/96系列单片机原理及应用(修订版)[M].北京:北京航空航天大学出版社.2002.46-170
[4]超声波测距仪的设计[J].传感器技术.2002
Ⅱ 51单片机超声波测距代码
1602液晶显示 的超声波模块程序
接口程序里边都有、、
#include
//#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs=P2^3;
sbit lcden=P2^2;
sbit trig=P2^0; //超声波发送
//sbit echo=P3^2; //超声波接受
//P0____________DB0-DB7
uchar dis[]="Disp_HC-SR04";
uchar num[]="0123456789";
uint distance;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=121;y>0;y--);
}
void HC_init()
{
TMOD=0x09;
TR0=1;
TH0=0;TL0=0;
}
uint HC_jisuan()
{
uint dist,timer;
timer=TH0;
timer<<=8;
timer=timer|TL0;
dist=timer/53; //晶振11.0592MHz 距离cm=微秒us/58
return dist; //1个机器周期是12个时钟周期 timer*12/(58*11.0592)=timer/53
}
void HC_run()
{
uint tempH=0x00,tempL=0x00;
TH0=0;TL0=0;
trig=0;
trig=1;
delay(1);
trig=0;
while((TH0-tempH!=0||TL0-tempL!=0)||(TH0==0&&TL0==0))
{
tempH=TH0;
tempL=TL0;
}
delay(1);
}
void lcd_write_com(uchar com) //LCD写指令
{
lcdrs=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_write_data(uchar date) //LCD写数据
{
lcdrs=1;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_init() //LCD初始化
{
lcden=0;
lcd_write_com(0x38);
lcd_write_com(0x0c);
lcd_write_com(0x06);
lcd_write_com(0x01);
}
void lcd_display(uchar temp)
{
uint i;
lcd_write_com(0x82);
for(i=0;i<12;i++)
{
lcd_write_data(dis[i]);
}
lcd_write_com(0x80+0x41);
lcd_write_data('D');
lcd_write_data('i');
lcd_write_data('s');
lcd_write_data('t');
lcd_write_data('a');
lcd_write_data('n');
lcd_write_data('c');
lcd_write_data('e');
lcd_write_data(':');
lcd_write_data(num[temp/100]);
lcd_write_data(num[temp/10%10]);
lcd_write_data(num[temp%10]);
lcd_write_data('c');
lcd_write_data('m');
}
void main()
{
lcd_init();
HC_init();
while(1)
{
HC_run();
distance=HC_jisuan();
lcd_display(distance);
delay(200);
}
}
Ⅲ 51单片机控制的超声波测距仪程序
希望对你有帮助
//超声波模块显示程序
#include <reg52.h> //包括一个52标准内核的头文件
#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,,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秒*344)/2
// X秒=( 2*Y米)/344 ==》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=0x7f;flag++;break;
case 0x01:P0=shi;P2=0xbf;flag++;break;
case 0x02:P0=;P2=0xdf;flag=0;break;
}
}
//显示数据转换程序
void conversion(uint temp_data)
{
uchar ge_data,shi_data,_data ;
_data=temp_data/100 ;
temp_data=temp_data%100; //取余运算
shi_data=temp_data/10 ;
temp_data=temp_data%10; //取余运算
ge_data=temp_data;
_data=SEG7[_data];
shi_data=SEG7[shi_data]&0x7f;
ge_data =SEG7[ge_data];
EA=0;
= _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;}
}
Ⅳ 求一段汇编程序,利用51单片机控制超声波传感器测距的程序。
; 基于AT89C2051单片机超声波测距系统
; 测量范围35-300厘米
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 中断入口程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG 0000H
AJMP START
ORG 000BH
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 主 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START : MOV R0,#70H ;立即数70H送寄存器R0中
MOV R7,#0BH ;立即数0BH送寄存器R7中
MOV 20H,#00H ;立即数00H送20H单元中
CLEARDISP: MOV @R0,#00H ;立即数立即数00H送R0中的地址单元中
INC R0 ;寄存器R0加1
DJNZ R7,CLEARDISP;寄存器中的数值减1非零时转移
MOV TMOD,#01H ;置定时器T0工作方式样3,对内部机器周期计数
CJZCX:MOV TL0,#00H ;装入定时器初值
MOV TH0,#00H
MOV R0,#0FH
MOV R1,#5bH
puzel:MOV 14H,#08H ;超声波发射持续200us
Here:CPL P3.5 ;输出40kHz方波
NOP ;
NOP ;
NOP ;
DJNZ 14H,Here ;
SETB TR0
SETB P3.2
MOV R6,#53H ;延时1.5ms
DL0: MOV R5,#03H
DJNZ R5,$
DJNZ R6,DL0
QBA:JNB P3.7,QBC
DJNZ R1,QBA
DJNZ R0,QBA
QBC:CLR P3.2
CLR TR0
MOV 70H,tl0
MOV 71H,tH0
MOV R2,71H
MOV R3,70H
MOV R6,#22H
MOV R7,#0H
LCALL MULD
MOV R6,#64H
MOV R7,#0H
LCALL DIVD
MOV 73H,R2
MOV 74H,R3
MOV R3,#0H
MOV R4,#0H
MOV R5,#0H
MOV R6,73H
MOV R7,74H
LCALL HB2
MOV A,R4 ;分离BCD
MOV B,#10H
DIV AB
MOV 78H,A
MOV 77H,B
MOV A,R5
MOV B,#10H
DIV AB
MOV 76H,A
MOV 75H,B
MOV 7AH,#0EFH
XXX:LCALL DISPLAY
DJNZ 7AH,XXX
AJMP CJZCX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 乘34程序(乘声速) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MULD: MOV A,R3 ;计算R3乘R7
MOV B,R7
MUL AB
MOV R4,B ;暂存部分积
MOV R5,A
MOV A,R3 ;计算R3乘R6
MOV B,R6
MUL AB
ADD A,R4 ;累加部分积
MOV R4,A
CLR A
ADDC A,B
MOV R3,A
MOV A,R2 ;计算R2乘R7
MOV B,R7
MUL AB
ADD A,R4 ;累加部分积
MOV R4,A
MOV A,R3
ADDC A,B
MOV R3,A
CLR A
RLC A
XCH A,R2 ;计算R2乘R6
MOV B,R6
MUL AB
ADD A,R3 ;累加部分积
MOV R3,A
MOV A,R2
ADDC A,B
MOV R2,A
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 除100程序(除法) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DIVD: CLR C ;比较被除数和除数
MOV A,R3
SUBB A,R7
MOV A,R2
SUBB A,R6
JC DVD1
SETB OV ;溢出
RET
DVD1: MOV B,#10H ;计算双字节商
DVD2: CLR C ;部分商和余数同时左移一位
MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
XCH A,R2
RLC A
XCH A,R2
MOV F0,C ;保存溢出位
CLR C
SUBB A,R7 ;计算(R2R3-R6R7)
MOV R1,A
MOV A,R2
SUBB A,R6
ANL C,/F0 ;结果判断
JC DVD3
MOV R2,A ;够减,存放新的余数
MOV A,R1
MOV R3,A
INC R5 ;商的低位置一
DVD3: DJNZ B,DVD2 ;计算完十六位商(R4R5)
MOV A,R4 ;将商移到R2R3中
MOV R2,A
MOV A,R5
MOV R3,A
CLR OV ;设立成功标志
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; BCD转换 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HB2: CLR A ;BCD码初始化
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#10H ;转换双字节十六进制整数
HB3: MOV A,R7 ;从高端移出待转换数的一位到CY中
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R5 ;BCD码带进位自身相加,相当于乘2
ADDC A,R5
DA A ;十进制调整
MOV R5,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R3
ADDC A,R3
MOV R3,A ;双字节十六进制数的万位数不超过6,不用调整
DJNZ R2,HB3 ;处理完16bit
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 显示程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY: MOV R1,#76H ;立即数76H送寄存器中
MOV R5,#0FEH ;立即数FEH送寄存器R5中
PLAY: MOV A,R5 ;寄存器R5中的数值送累加器A中
MOV P3,A ;累加器A中的数值送P3口
MOV A,@R1 ;以寄存器R1中的数为地址单元的数值送累加器中
MOV DPTR,#TAB ;16位地址送地址寄存器中
MOVC A,@A+DPTR ;以中的地址为基地变址寻址单元中的数送累加器
MOV P1,A ;累加器A中的数值送P1口
MOV R6,#14H ;立即数据14送寄存器R6中
DL1:MOV R7,#19H ;立即数据19送寄存器R7中
DL2:DJNZ R7,DL2 ;寄存器中的数据减1,不为零时则转移
DJNZ R6,DL1 ;寄存器中的数据减1,不为零时则转移
INC R1 ;寄存器R1中的数值加1
MOV A,R5 ;寄存器R5中的数值送累加器A中
JNB ACC.2,ENDOUT ;地址位为0则转到ENDOUT
RL A ;累加器循环右移
MOV R5,A ;累加器A中的数值送寄存器R5中
AJMP PLAY ;绝对短转移
ENDOUT: SETB P3.5 ;置P3.5口
MOV P1,#0FFH ;立即数0FEH送P1口
RET ;返回
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
END ;结束
我见过一款制作容易免调试的超声波测距板,你可到“谷歌”上搜索一下《一款制作容易免调试的超声波测距板》,该超声波测距板结构简单、制作容易不需要调试、测量精度高,比较适合单片机初学都使用,同时也是单片机课程设计比较好的实训课题。该超声波测距系统,提供套件,及组装好的板件,含原理图、源程序、设计说明等。
Ⅳ 单片机超声波雷达测距的C语言程序设计,具体看问题补充
功能这么多的单片机超声波雷达测距的C语言程序设计,这里可能没有人会无偿给你做,你到淘宝网上看看吧,找一下:“单片机超声波测距模块电子设计制作C程序”这是一款比较好的单片机超声波雷达测距的C语言程序设计,附的资料比较多,有Protel格式原理图、PCB图,有源程序,制作非常容易,只要按图焊接好元件,基本不需要调试,最远可测量到6.99米,报警距离还可调节。
Ⅵ 超声波测距仪的设计需要用到哪些软件
设计电原理图、PCB图需要PROTEL;编写51系列单片机程序需要用到KEIL等单片机编译软件(不同系统列的单片机编译软件也不同);下载单片机程序需要相应的下载软件,如果要进行仿真,还要用到Proteus仿真软件。
Ⅶ 帮忙详细解答一下基于单片机的超声波测距仪的汇编源程序(急求啊)
我可以负责的告诉你,用C吧,完全可以胜任。
2003年的时候我们为了确保MCU的效率(时效性),强制使用汇编写的超声波程序,结果程序写不大,汇编你也知道,写百八十行可以,代码多了,这程序就没法看了,更谈不上程序升级和维护了。因此,那一代超声波产品的功能很弱。
2006年,我们要重新设计第二代超声波产品,要求可靠性好、功能强大,自然的代码量也要多了,当时我们仍然固执的使用汇编、绝不用C,可汇编的代码仍然写不长,为了方便技术人员管理和后续的产品升级,我把这一套复杂的系统代码分成了4级,也就是4套汇编代码,分别在32个MCU里运行(同一个设备里),这4套代码分别交给4个人来编写和维护,这4个人中若有人跳槽走了,由于他掌握的代码量小,功能又单一,接替他的人也很容易接手。(否则,这4套汇编程序,集中在一个冗长的代码里,那么这套代码将很难维护,而且几乎只能有1个人才能完全看懂它,一旦这个人走了,别人很难接手这套‘烂’程序,这对于产品的持续改进非常不利)
2008年,我们试探性的,在DSP(TMS320F28335)上用C完成了所有的功能,而且程序量比汇编要少得多,可读性、可维护性也要好得多。后来,我们在单片机上,也用C完成了绝大部分功能,原来担心的时效性问题从没有发生,这才领悟:2003-2008这5年,我们绕了一个大圈。
从此以后,我们就不再用汇编了,用C写超声波程序一直至今(偶尔嵌入汇编代码),算一下也有5年了,从没觉得C有任何局限性。
那么,你是还觉得必须要用汇编么?
Ⅷ 超声波测距程序分析
程序我没有仔细看,有些思路你考虑一下:
1、不知道你用的哪个型号的单片机,计数器所用的时钟频率是多少?5cm意味着约300uS的声波传输时间,结合你的计数频率和计数器的位数,看看300uS你的计数器有没有溢出;
2、超过5cm的时候,用示波器探一下有没有收到声波信号,可能是你的放大倍数不够,信号太弱导致信号没有被识别;
3、仔细考虑一下你的收发探头的安装方式,有没有可能接收到直射波,我觉得这种可能性要大一些;超声测距,接收探头必须只接收到反射波,否则测出来肯定不准确;
4、测试不准确,可以考虑进行多次测量,去掉一半的异常值(比如说测回来8个数,去掉2个最大的,再去掉2个最小的),然后取平均;这样测出来的结果相对准确一些。
就是这些了,希望对你有帮助。