谁能给我一篇超声波测距的程序的谢谢了

谁能给我一篇超声波测距的程序的谢谢了,第1张

相关资料,请参考

超声波测距仪设计及其应用分析

[摘要] 本文利用超声波传输中距离与时间的关系,采用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

//晶振=8M

//MCU=STC10F04XE

//P0.0-P0.6共阳数码管引脚

//Trig = P1^0

//Echo = P3^2

#include <reg52.h>//包括一个52标准内核的头文件

#define uchar unsigned char //定义一下方便使用

#define uint unsigned int

#define ulong unsigned long

//***********************************************

sfr CLK_DIV = 0x97//为STC单片机定义,系统时钟分频

//为STC单片机的IO口设置地址定义

sfr P0M1 = 0X93

sfr P0M0 = 0X94

sfr P1M1 = 0X91

sfr P1M0 = 0X92

sfr P2M1 = 0X95

sfr P2M0 = 0X96

//***********************************************

sbit Trig = P1^0//产生脉冲引脚

sbit Echo = P3^2//回波引脚

sbit test = P1^1//测试用引脚

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

CLK_DIV=0X03//系统时钟为1/8晶振(pdf-45页)

P0M1 = 0 //将io口设置为推挽输出

P1M1 = 0

P2M1 = 0

P0M0 = 0XFF

P1M0 = 0XFF

P2M0 = 0XFF

i=0

flag=0

test =0

Trig=0 //首先拉低脉冲输入引脚

TMOD=0x11 //定时器0,定时器1,16位工作方式

TR0=1 //启动定时器0

IT0=0 //由高电平变低电平,触发外部中断

ET0=1 //打开定时器0中断

//ET1=1 //打开定时器1中断

EX0=0 //关闭外部中断

EA=1//打开总中断0

while(1) //程序循环

{

EA=0

Trig=1

delay_20us()

Trig=0//产生一个20us的脉冲,在Trig引脚

while(Echo==0)//等待Echo回波引脚变高电平

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 //没有回波则清零

test = !test //测试灯变化

}

/// 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=geP2=0xfdflag++break

case 0x01:P0=shiP2=0xfeflag++break

case 0x02:P0=baiP2=0xfbflag=0break

}

}

//*****************************************************************

/*

//定时器1中断,用做超声波测距计时

timer1() interrupt 3 // 定时器0中断是1号

{

TH1=0

TL1=0

}

*/

//******************************************************************

//显示数据转换程序

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]

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=0bt<100bt++)

}

/*

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} /*交换值

}

*/

我这是单片机控制超声波探头的汇编源程序,已验证可以

中断入口程序 *

********************************************

ORG 0000H

LJMP START

ORG 0003H

LJMP PINT0

ORG 000BH

LJMP INTT0

ORG 0013H

RETI

ORG 001BH

LJMP INTT1

ORG 0023H

RETI

ORG 002BH

RETI

********************************************

* 主 程 序 *

********************************************

START: MOV SP,#4FH

MOV R0,#40H

MOV R7,#0BH

CLEARDISP: MOV @R0,#00H

INC R0

DJNZR7,CLEARDISP

MOV 20H,#00H

MOV TMOD,#21H T1为8位自动重装模式,T0为16位定时器

MOV TH0,#00H 65毫秒初值

MOV TL0,#00H

MOV TH1,#0F2H 40KHZ初值

MOV TL1,#0F2H

MOV P0,#0FFH

MOV P1,#0FFH

MOV P2,#0FFH

MOV P3,#0FFH

MOV R4,#04H 超声波肪冲个数控制(为赋值的一半)

SETBPX0

SETBET0

SETBEA

SETBTR0 开启测距定时器

start1: LCALL DISPLAY

JNB00H,START1收到反射信号时标志位为1

CLREA

LCALL WORK 计算距离子程序

SETB EA

CLR00H

SETB TR0 重新开启测距定时器

MOVR2,#64H 测量间隔控制(约4*100=400MS)

LOOP: LCALL DISPLAY

DJNZ R2,LOOP

SJMP Start1

****************************************************

*中断程序* *

****************************************************

T0中断,65毫秒中断一次

INTT0:CLR EA

CLR TR0

MOV TH0,#00H

MOV TL0,#00H

SETBET1

SETBEA

SETBTR0 启动计数器T0,用以计算超声来回时间

SETBTR1 开启发超声波用定时器T1

OUT:RETI

T1中断,发超声波用

INTT1: CPL VOUT

DJNZR4,RETIOUT

CLR TR1超声波发送完毕,关T1

CLR ET1

MOV R4,#04H

SETBEX0开启接收回波中断

RETIOUT:RETI

外中断0,收到回波时进入

PINT0: CLR TR0关计数器

CLR TR1

CLR ET1

CLR EA

CLR EX0

MOV 44H,TL0将计数值移入处理单元

MOV 45H,TH0

SETB00H接收成功标志

RETI

****************************************************

*显示程序 *

****************************************************

40H为最高位,43H为最低位,先扫描高位

DISPLAY: MOV R1,#40HG

MOV R5,#0F7HG

PLAY: MOV A,R5

MOV P0,#0FFH

MOV P2,A

MOV A,@R1

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV P0,A

LCALL DL1MS

INC R1

MOV A,R5

JNBACC.0,ENDOUTG

RRA

MOV R5,A

AJMP PLAY

ENDOUT: MOV P2,#0FFH

MOV P0,#0FFH

RET

TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,88H,0BFH

共阳段码表"0" "1" "2" "3" "4" "5""6" "7" "8" "9" "不亮""A""-"

****************************************************

*延时程序 *

****************************************************

DL1MS: MOVR6,#14H

DL1: MOVR7,#19H

DL2: DJNZ R7,DL2

DJNZ R6,DL1

RET

****************************************************

*距离计算程序 (=计数值*17/1000cm) *

****************************************************

work: PUSH ACC

PUSH PSW

PUSH B

MOV PSW, #18h

MOV R3, 45H

MOV R2, 44H

MOV R1, #00D

MOV R0, #17D

LCALL MUL2BY2

MOV R3, #03H

MOV R2, #0E8H

LCALL DIV4BY2

LCALL DIV4BY2

MOV 40H, R4

MOV A,40H

JNZ JJ0

MOV 43H,#0AH

JJ0: MOV A, R0

MOV R4, A

MOV A, R1

MOV R5, A

MOV R3, #00D

MOV R2, #100D

LCALL DIV4BY2

MOV 42H, R4

MOV A,42H

JNZ JJ1

MOV A,40H

SUBB A,#0AH

JNZ JJ1

MOV 42H,#0AH

JJ1: MOV A, R0

MOV R4, A

MOV A, R1

MOV R5, A

MOV R3, #00D

MOV R2, #10D

LCALL DIV4BY2

MOV 41H, R4

MOV A,41H

JNZ JJ2

MOV A,42H

SUBB A,#0AH

JNZ JJ2

MOV 41H,#0AH

JJ2: MOV 40H, R0

POP B

POP PSW

POP ACC

RET

****************************************************

*两字节无符号数乘法程序*

****************************************************

R7R6R5R4 <= R3R2 * R1R0

MUL2BY2: CLR A

MOV R7, A

MOV R6, A

MOV R5, A

MOV R4, A

MOV 46H, #10H

MULLOOP1: CLR C

MOV A, R4

RLC A

MOV R4, A

MOV A, R5

RLC A

MOV R5, A

MOV A, R6

RLC A

MOV R6, A

MOV A, R7

RLC A

MOV R7, A

MOV A, R0

RLC A

MOV R0, A

MOV A, R1

RLC A

MOV R1, A

JNC MULLOOP2

MOV A, R4

ADD A, R2

MOV R4, A

MOV A, R5

ADDC A, R3

MOV R5, A

MOV A, R6

ADDC A, #00H

MOV R6, A

MOV A, R7

ADDC A, #00H

MOV R7, A

MULLOOP2: DJNZ 46H, MULLOOP1

RET

****************************************************

*四字节/两字节无符号数除法程序 *

****************************************************

R7R6R5R4/R3R2=R7R6R5R4(商)...R1R0(余数)

DIV4BY2: MOV 46H, #20H

MOV R0, #00H

MOV R1, #00H

DIVLOOP1: MOV A, R4

RLC A

MOV R4, A

MOV A, R5

RLC A

MOV R5, A

MOV A, R6

RLC A

MOV R6, A

MOV A, R7

RLC A

MOV R7, A

MOV A, R0

RLC A

MOV R0, A

MOV A, R1

RLC A

MOV R1, A

CLR C

MOV A, R0

SUBB A, R2

MOV B, A

MOV A, R1

SUBB A, R3

JCDIVLOOP2

MOV R0, B

MOV R1, A

DIVLOOP2: CPL C

DJNZ 46H, DIVLOOP1

MOV A, R4

RLC A

MOV R4, A

MOV A, R5

RLC A

MOV R5, A

MOV A, R6

RLC A

MOV R6, A

MOV A, R7

RLC A

MOV R7, A

RET

END


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12043801.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-20
下一篇2023-05-20

发表评论

登录后才能评论

评论列表(0条)

    保存