單片機超聲波傳感器測量距離
設計一個(gè)超聲波測距器,可以應用于汽車(chē)倒車(chē)、建筑施工工地以及一些工業(yè)現場(chǎng)的位置監控,也可用于如液位、井深、管道長(cháng)度的測量等場(chǎng)合。要求測量范圍在0.10-3.00m,測量精度1cm,測量時(shí)與被測物體無(wú)直接接觸,能夠清晰穩定地顯示測量結果。
本文引用地址:http://dyxdggzs.com/article/201611/315675.htm二、設計思路
超聲波傳感器及其測距原理
超聲波是指頻率高于20KHz的機械波。為了以超聲波作為檢測手段,必須產(chǎn)生超生波和接收超聲波。完成這種功能的裝置就是超聲波傳感器,習慣上稱(chēng)為超聲波換能器或超聲波探頭。超聲波傳感器有發(fā)送器和接收器,但一個(gè)超聲波傳感器也可具有發(fā)送和接收聲波的雙重作用。超聲波傳感器是利用壓電效應的原理將電能和超聲波相互轉化,即在發(fā)射超聲波的時(shí)候,將電能轉換,發(fā)射超聲波;而在收到回波的時(shí)候,則將超聲振動(dòng)轉換成電信號。
超聲波測距的原理一般采用渡越時(shí)間法TOF(timeofflight)。首先測出超聲波從發(fā)射到遇到障礙物返回所經(jīng)歷的時(shí)間,再乘以超聲波的速度就得到二倍的聲源與障礙物之間的距離
測量距離的方法有很多種,短距離的可以用尺,遠距離的有激光測距等,超聲波測距適用于高精度的中長(cháng)距離測量。因為超聲波在標準空氣中的傳播速度為331.45米/秒,由單片機負責計時(shí),單片機使用12.0M晶振,所以此系統的測量精度理論上可以達到毫米級。
由于超聲波指向性強,能量消耗緩慢,在介質(zhì)中傳播距離遠,因而超聲波可以用于距離的測量。利用超聲波檢測距離,設計比較方便,計算處理也較簡(jiǎn)單,并且在測量精度方面也能達到要求。
超聲波發(fā)生器可以分為兩類(lèi):一類(lèi)是用電氣方式產(chǎn)生超聲波,一類(lèi)是用機械方式產(chǎn)生超聲波。本課題屬于近距離測量,可以采用常用的壓電式超聲波換能器來(lái)實(shí)現。
根據設計要求并綜合各方面因素,可以采用AT89S51單片機作為主控制器,用動(dòng)態(tài)掃描法實(shí)現LED數字顯示,超聲波驅動(dòng)信號用單片機的定時(shí)器完成,超聲波測距器的系統框圖如下圖所示:
超聲波測距器系統設計框圖
三、系統組成
硬件部分
主要由單片機系統及顯示電路、超聲波發(fā)射電路和超聲波檢測接收電路三部分組成。采用AT89S51來(lái)實(shí)現對CX20106A紅外接收芯片和TCT40-10系列超聲波轉換模塊的控制。單片機通過(guò)P1.0引腳經(jīng)反相器來(lái)控制超聲波的發(fā)送,然后單片機不停的檢測INT0引腳,當INT0引腳的電平由高電平變?yōu)榈碗娖綍r(shí)就認為超聲波已經(jīng)返回。計數器所計的數據就是超聲波所經(jīng)歷的時(shí)間,通過(guò)換算就可以得到傳感器與障礙物之間的距離。
軟件部分
主要由主程序、超聲波發(fā)生子程序、超聲波接收中斷程序及顯示子程序等部分。
四、系統硬件電路設計
1.單片機系統及顯示電路
單片機采用89S51或其兼容系列。采用12MHz高精度的晶振,以獲得較穩定的時(shí)鐘頻率,減小測量誤差。單片機用P1.0端口輸出超聲波轉化器所需的40KHz方波信號,利用外中斷0口檢測超聲波接受電路輸出的返回信號。顯示電路采用簡(jiǎn)單實(shí)用的4位共陽(yáng)LED數碼管,段碼用74LS244驅動(dòng),位碼用PNP三極管驅動(dòng)。單片機系統及顯示電路如下圖所示
單片機及顯示電路原理圖
2.超聲波發(fā)射電路原理圖參考期刊如圖所示:
超聲波發(fā)射電路原理圖
壓電超聲波轉換器的功能:利用壓電晶體諧振工作。內部結構上圖所示,它有兩個(gè)壓電晶片和一個(gè)共振板。當它的兩極外加脈沖信號,其頻率等于壓電晶片的固有振蕩頻率時(shí),壓電晶片將會(huì )發(fā)生共振,并帶動(dòng)共振板振動(dòng)產(chǎn)生超聲波,這時(shí)它就是一超聲波發(fā)生器;如沒(méi)加電壓,當共振板接受到超聲波時(shí),將壓迫壓電振蕩器作振動(dòng),將機械能轉換為電信號,這時(shí)它就成為超聲波接受轉換器。超聲波發(fā)射轉換器與接受轉換器其結構稍有不同。
3.超聲波檢測接受電路
參考紅外轉化接收期刊的電路采用集成電路CX20106A,這是一款紅外線(xiàn)檢波接收的專(zhuān)用芯片,常用于電視機紅外遙控接收器??紤]到紅外遙控常用的載波頻率38KHz與測距超聲波頻率40KHz較為接近,可以利用它作為超聲波檢測電路。實(shí)驗證明其具有很高的靈敏度和較強的抗干擾能力。適當改變C4的大小,可改變接受電路的靈敏度和抗干擾能力。
超聲波接收電路圖
五、系統程序設計
超聲波測距軟件設計主要由主程序,超聲波發(fā)射子程序,超聲波接受中斷程序及顯示子程序組成。下面對超聲波測距器的算法,主程序,超聲波發(fā)射子程序和超聲波接受中斷程序逐一介紹。
1.超聲波測距器的算法設計
下圖示意了超聲波測距的原理,即超聲波發(fā)生器T在某一時(shí)刻發(fā)出的一個(gè)超聲波信號,當超聲波遇到被測物體后反射回來(lái),就被超聲波接收器R所接受。這樣只要計算出發(fā)生信號到接受返回信號所用的時(shí)間,就可算出超聲波發(fā)生器與反射物體的距離。
距離計算公式:d=s/2=(c*t)/2
*d為被測物與測距器的距離,s為聲波的來(lái)回路程,c為聲速,t為聲波來(lái)回所用的時(shí)間
聲速c與溫度有關(guān),如溫度變化不大,則可認為聲速是基本不變的。如果測距精度要求很高,則應通過(guò)溫度補償的方法加以校正。聲速確定后,只要測得超聲波往返時(shí)間,即可求得距離。在系統加入溫度傳感器來(lái)監測環(huán)境溫度,可進(jìn)行溫度被償。這里可以用DS18B20測量環(huán)境溫度,根據不同的環(huán)境溫度確定一聲速提高測距的穩定性。為了增強系統的可靠性,應在軟硬件上采用抗干擾措施。
不同溫度下的超聲波聲速表
溫度/
-30
-20
-10
0
10
20
30
100
聲速c(m/s)
313
319
325
323
338
344
349
386
2.主程序
主程序首先對系統環(huán)境初始化,設置定時(shí)器T0工作模式為16位的定時(shí)計數器模式,置位總中斷允許位EA并給顯示端口P0和P2清0。然后調用超聲波發(fā)生子程序送出一個(gè)超聲波脈沖,為避免超聲波從發(fā)射器直接傳送到接收器引起的直接波觸發(fā),需延遲0.1ms(這也就是測距器會(huì )有一個(gè)最小可測距離的原因)后,才打開(kāi)外中斷0接收返回的超聲波信號。由于采用12MHz的晶振,機器周期為1us,當主程序檢測到接收成功的標志位后,將計數器T0中的數(即超聲波來(lái)回所用的時(shí)間)按下式計算即可測得被測物體與測距儀之間的距離,設計時(shí)取20℃時(shí)的聲速為344m/s則有:
d=(C*T0)/2=172T0/10000cm(其中T0為計數器T0的計數值)
測出距離后結果將以十進(jìn)制BCD碼方式LED,然后再發(fā)超聲波脈沖重復測量過(guò)程。主程序框圖如下
3.超聲波發(fā)生子程序和超聲波接收中斷程序
超聲波發(fā)生子程序的作用是通過(guò)P1.0端口發(fā)送2個(gè)左右的超聲波信號頻率約40KHz的方波,脈沖寬度為12us左右,同時(shí)把計數器T0打開(kāi)進(jìn)行計時(shí)。超聲波測距器主程序利用外中斷0檢測返回超聲波信號,一旦接收到返回超聲波信號(INT0引腳出現低電平),立即進(jìn)入中斷程序。進(jìn)入該中斷后就立即關(guān)閉計時(shí)器T0停止計時(shí),并將測距成功標志字賦值1。如果當計時(shí)器溢出時(shí)還未檢測到超聲波返回信號,則定時(shí)器T0溢出中斷將外中斷0關(guān)閉,并將測距成功標志字賦值2以表示此次測距不成功。
六.軟硬件調試及性能
超聲波測距儀的制作和調試,其中超聲波發(fā)射和接收采用Φ15的超聲波換能器TCT40-10F1(T發(fā)射)和TCT40-10S1(R接收),中心頻率為40kHz,安裝時(shí)應保持兩換能器中心軸線(xiàn)平行并相距4~8cm,其余元件無(wú)特殊要求。若能將超聲波接收電路用金屬殼屏蔽起來(lái),則可提高抗干擾能力。根據測量范圍要求不同,可適當調整與接收換能器并接的濾波電容C4的大小,以獲得合適的接收靈敏度和抗干擾能力。
硬件電路制作完成并調試好后,便可將程序編譯好下載到單片機試運行。根據實(shí)際情況可以修改超聲波發(fā)生子程序每次發(fā)送的脈沖寬度和兩次測量的間隔時(shí)間,以適應不同距離的測量需要。根據所設計的電路參數和程序,測距儀能測的范圍為0.07~5.5m,測距儀最大誤差不超過(guò)1cm。系統調試完后應對測量誤差和重復一致性進(jìn)行多次實(shí)驗分析,不斷優(yōu)化系統使其達到實(shí)際使用的測量要求。
后續工作需實(shí)驗后才能驗證
根據參考電路和集成的電路器件測距范圍有限10m以?xún)葹楹谩?/p>
程序清單
以下是用匯編語(yǔ)言編寫(xiě)的超聲波測距控制源程序:
采用AT89S51 12MHz晶振
顯示緩沖單元在40H~43H,使用內存44H、45H、46H用于計算距離
20H用于標志
VOUT EQU P1.0 ;脈沖輸出端口
*中斷入口程序*
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 ;40~43H為顯示數據存放單元(40為最高位)
MOV R7,#0BH
CLEARDISP:MOV @R0, #00H
INC R0
DJNZ R7, CLEARDISP
MOV 20H, #00H
MOV TMOD, #21H ;T1為8位自動(dòng)重裝模式,T0為16位定時(shí)器
MOV TH0, #00H ;65ms初值
MOV TL0, #00H ;40KHz初值
MOV TH1, #0F2H
MOV TL1, #0F2H
MOV P0, #0FFH
MOV P1, #0FFH
MOV P2, #0FFH
MOV P3, #0FFH
MOV R4, #04H ;超聲波脈沖個(gè)數控制(為賦值的一半)
SETB PX0
SETB ET0
STEB EA
CLR 00H
SETB TR0 ;開(kāi)啟測距定時(shí)器
START1: LCALL DISPLAY
JNB 00H, START1 ;收到反射信號時(shí)標志位為1
CLR EA
LCALL WORK ;計算距離子程序
SETB EA
CLR 00H
SETB TR0 ;重新開(kāi)啟測距定時(shí)器
MOV R2, #64H ; 測量間隔控制(約4*100=400ms)
LOOP: LCALL DISPLAY
DJNZ R2, LOOP
SJMP START 1
*中斷程序*
;T0中斷,65ms中斷一次
INTT0: CLR EA
CLR TR0
MOV TH0, #00H
MOV TL0, #00H
SETB ET1
SETB EA
SETB TR0 ;啟動(dòng)計時(shí)器T0,用以計算超聲波來(lái)回時(shí)間
SETB TR1 ;開(kāi)啟發(fā)超聲波用定時(shí)器T1
OUT: RETI
;T1中斷,發(fā)超聲波用
INTT1: CPL VOUT
DJNZ R4,RETIOUT
CLR TR1 ;超聲波發(fā)送完畢,關(guān)T1
CLR ET1
MOV R4,#04H
SETB EX0 ;開(kāi)啟接收回波中斷
RETIOUT: RETI
;外中斷0,收到回波時(shí)進(jìn)入
PINT0: CLR TR0 ;關(guān)計數器
CLR TR1
CLR ET1
CLR EA
CLR EX0
MOV 44H, TL0 ;將計數值移入處理單元
MOV 45H, TH0
SETB 00H ;接收成功標志
RETI
*延時(shí)程序*
DL1MS: MOV R6, #14H
DL1: MOV R7, #19H
DL2: DJNZ R6, DL2
DJNZ R6, DL1
RET
*顯示程序*
;40H為最高位,43H為最低位,先掃描高位
DISPLAY: MOV R1, #40H;G
MOV R5,#0F7H;G
PLAY: MOV A, R5
MOV P0, #0FFH
MOV P2, A
MOV A, @R1
MOV DPTR, #TAB
MOVC A, @A+DPTR
MOV P0, A
LCALL DLIMS
INC R1
MOV A, R5
JNB ACC.0, ENDOUT;G
RR A
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
;共陽(yáng)數碼管 0 ,1, 2,3,4,5,6,7,8,9,不亮,A, —
*距離計算程序(=計算值×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 40H, #0AH ;最高位為0,不點(diǎn)亮
JJ0: MOV A R0
MOV R4, A
MOV A R1
MOV R5 A
MOV R3, #00D
MOV R2, #100D
LCALL DIV4BY2
MOV 41H, R4
MOV A, 41H
JNZ JJ1
MOV A, 40H ;此高位為0,先看最高位是否為不亮
SUBB A, #0AH
JNZ JJ1
MOV 41H, #0AH ; 最高位不亮,次高位也不亮
JJ1: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #10D
LCALL DIV4BY2
MOV 42H, R4
MOV A 42H
JNZ JJ2
MOV A, 41H ;次高位為0,先看次高位是否為不亮
SUBB A, #0AH
JNZ JJ2
MOV 42H, #0AH ;次高位不亮,次高位也不亮
JJ2: MOV 43H, R0
POP B
POP PSW
POP ACC
RET
*兩字節無(wú)符號數乘法程序
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
*四字節/兩字節無(wú)符號數除法程序*
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
JC DIVLOOP2
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
附C51程序
#include
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
extern void cs_t(void);
extern void delay(uint);
extern void display(uchar*);
//data uchar display(uchar*);
data uchar testok;
void main (void)
{
data uchar dispram[5];
data uint i;
data ulong time;
P0=0xff;
P2=0xff;
TMOD=0x11;
IE=0x80;
while (1)
{
cs_t();
delay(1);
testok=0;
EX0=1;
ET0=1;
while(! testok) display(dispram);
if (1==testok)
{
time=TH0;
time=(time<<8)| TL0;
time*=172;
time/=10000;
dispram[0]=(uchar) (time%10);
time/=10;
dispram[1]=(uchar) (time%10);
time/=10;
dispram[2]=(uchar) (time%10);
dispram[3]=(uchar) (time/10);
if (0==dispram[3]) dispram[3]=17;
} else
{
dispram [0]=16;
dispram [1]=16;
dispram [2]=16;
dispram [3]=16;
}
for (i=0;i<300;i++) display(dispram);
}
}
void cs_r(void) interrupt 0
{
TR0=0;
ET0=0;
EX0=0;
testok=1;
}
void overtime(void) interrupt 1
{
EX0=0;
TR0=0;
ET0=0;
testok=2;
}
NAME CS_T
?PR?CS_T?CS_T SEGMENT CODE
PUBLIC CS_T
RSEG ?PR?CS_T?CS_T
CS_T: PUSH ACC
MOV TH0, #00H
MOV TL0, #00H
MOV A, #4D
SETB TR0
CS_T1: CPL p1.0
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ ACC,CS_T1
POP ACC
RET
;
END
name delay
?pr?_delay?delay segment code
public _delay
rseg ?pr?_delay?delay
_delay: push acc
mov a,r7
jz dela1
inc r6
dela1: mov r5,#50d
djnz r5, $
djnz r7,dela1
djnz r6,dela1
pop acc
ret
end
NAME DISPLAY
?PR?_DISPLAY?display segment code
?co?_DISPLAY?display segment data
EXTRN CODE (_DELAY)
PUBLIC _DISPLAY
RSEG ?CO?_DISPLAY?DISPLAY
?_display?byte:
dispbit: ds 1
dispnum: ds 1
rseg ?pr?_display?display
_display: push acc
push dph
push dpl
push psw
inc dispnum
mov a,dispnum
cjne a,#4d,disp1
DISP1: JC DISP2
MOV DISPNUM,#00H
MOV DISPBIT,#0FEH
DISP2: MOV A,R1
ADD A,DISPNUM
MOV R0,A
MOV A,@R0
MOV DPTR,#DISPTABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,DISPNUM
CJNE A,#2D,DISP3
CLR P0.7
DISP3: MOV P2,DISPBIT
MOV R5,#00H
MOV R7,#0AH
LCALL _DELAY
MOV P0,#0FFH
MOV P2,#0FFH
MOV A,DISPBIT
RL A
MOV DISPBIT,A
POP PSW
POP DPL
POP DPH
POP ACC
RET
DISPTABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH,0BFH,0FFH
END
評論