新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機超聲波傳感器測量距離

        單片機超聲波傳感器測量距離

        作者: 時間:2016-11-18 來源:網絡 收藏
        一、設計要求

        設計一個超聲波測距器,可以應用于汽車倒車、建筑施工工地以及一些工業現場的位置監控,也可用于如液位、井深、管道長度的測量等場合。要求測量范圍在0.10-3.00m,測量精度1cm,測量時與被測物體無直接接觸,能夠清晰穩定地顯示測量結果。

        本文引用地址:http://www.104case.com/article/201611/315675.htm

        二、設計思路

        超聲波傳感器及其測距原理

        超聲波是指頻率高于20KHz的機械波。為了以超聲波作為檢測手段,必須產生超生波和接收超聲波。完成這種功能的裝置就是超聲波傳感器,習慣上稱為超聲波換能器或超聲波探頭。超聲波傳感器有發送器和接收器,但一個超聲波傳感器也可具有發送和接收聲波的雙重作用。超聲波傳感器是利用壓電效應的原理將電能和超聲波相互轉化,即在發射超聲波的時候,將電能轉換,發射超聲波;而在收到回波的時候,則將超聲振動轉換成電信號。

        超聲波測距的原理一般采用渡越時間法TOF(timeofflight)。首先測出超聲波從發射到遇到障礙物返回所經歷的時間,再乘以超聲波的速度就得到二倍的聲源與障礙物之間的距離

        測量距離的方法有很多種,短距離的可以用尺,遠距離的有激光測距等,超聲波測距適用于高精度的中長距離測量。因為超聲波在標準空氣中的傳播速度為331.45米/秒,由單片機負責計時,單片機使用12.0M晶振,所以此系統的測量精度理論上可以達到毫米級。

        由于超聲波指向性強,能量消耗緩慢,在介質中傳播距離遠,因而超聲波可以用于距離的測量。利用超聲波檢測距離,設計比較方便,計算處理也較簡單,并且在測量精度方面也能達到要求。

        超聲波發生器可以分為兩類:一類是用電氣方式產生超聲波,一類是用機械方式產生超聲波。本課題屬于近距離測量,可以采用常用的壓電式超聲波換能器來實現。

        根據設計要求并綜合各方面因素,可以采用AT89S51單片機作為主控制器,用動態掃描法實現LED數字顯示,超聲波驅動信號用單片機的定時器完成,超聲波測距器的系統框圖如下圖所示:

        超聲波測距器系統設計框圖

        三、系統組成

        硬件部分

        主要由單片機系統及顯示電路、超聲波發射電路和超聲波檢測接收電路三部分組成。采用AT89S51來實現對CX20106A紅外接收芯片和TCT40-10系列超聲波轉換模塊的控制。單片機通過P1.0引腳經反相器來控制超聲波的發送,然后單片機不停的檢測INT0引腳,當INT0引腳的電平由高電平變為低電平時就認為超聲波已經返回。計數器所計的數據就是超聲波所經歷的時間,通過換算就可以得到傳感器與障礙物之間的距離。

        軟件部分

        主要由主程序、超聲波發生子程序、超聲波接收中斷程序及顯示子程序等部分。

        四、系統硬件電路設計

        1.單片機系統及顯示電路

        單片機采用89S51或其兼容系列。采用12MHz高精度的晶振,以獲得較穩定的時鐘頻率,減小測量誤差。單片機用P1.0端口輸出超聲波轉化器所需的40KHz方波信號,利用外中斷0口檢測超聲波接受電路輸出的返回信號。顯示電路采用簡單實用的4位共陽LED數碼管,段碼用74LS244驅動,位碼用PNP三極管驅動。單片機系統及顯示電路如下圖所示

        單片機及顯示電路原理

        2.超聲波發射電路原理圖參考期刊如圖所示:

        超聲波發射電路原理圖

        壓電超聲波轉換器的功能:利用壓電晶體諧振工作。內部結構上圖所示,它有兩個壓電晶片和一個共振板。當它的兩極外加脈沖信號,其頻率等于壓電晶片的固有振蕩頻率時,壓電晶片將會發生共振,并帶動共振板振動產生超聲波,這時它就是一超聲波發生器;如沒加電壓,當共振板接受到超聲波時,將壓迫壓電振蕩器作振動,將機械能轉換為電信號,這時它就成為超聲波接受轉換器。超聲波發射轉換器與接受轉換器其結構稍有不同。

        3.超聲波檢測接受電路

        參考紅外轉化接收期刊的電路采用集成電路CX20106A,這是一款紅外線檢波接收的專用芯片,常用于電視機紅外遙控接收器。考慮到紅外遙控常用的載波頻率38KHz與測距超聲波頻率40KHz較為接近,可以利用它作為超聲波檢測電路。實驗證明其具有很高的靈敏度和較強的抗干擾能力。適當改變C4的大小,可改變接受電路的靈敏度和抗干擾能力。

        超聲波接收電路圖

        五、系統程序設計

        超聲波測距軟件設計主要由主程序,超聲波發射子程序,超聲波接受中斷程序及顯示子程序組成。下面對超聲波測距器的算法,主程序,超聲波發射子程序和超聲波接受中斷程序逐一介紹。

        1.超聲波測距器的算法設計

        下圖示意了超聲波測距的原理,即超聲波發生器T在某一時刻發出的一個超聲波信號,當超聲波遇到被測物體后反射回來,就被超聲波接收器R所接受。這樣只要計算出發生信號到接受返回信號所用的時間,就可算出超聲波發生器與反射物體的距離。

        距離計算公式:d=s/2=(c*t)/2

        *d為被測物與測距器的距離,s為聲波的來回路程,c為聲速,t為聲波來回所用的時間

        聲速c與溫度有關,如溫度變化不大,則可認為聲速是基本不變的。如果測距精度要求很高,則應通過溫度補償的方法加以校正。聲速確定后,只要測得超聲波往返時間,即可求得距離。在系統加入溫度傳感器來監測環境溫度,可進行溫度被償。這里可以用DS18B20測量環境溫度,根據不同的環境溫度確定一聲速提高測距的穩定性。為了增強系統的可靠性,應在軟硬件上采用抗干擾措施。

        不同溫度下的超聲波聲速表

        溫度/

        -30

        -20

        -10

        0

        10

        20

        30

        100

        聲速c(m/s)

        313

        319

        325

        323

        338

        344

        349

        386

        2.主程序

        主程序首先對系統環境初始化,設置定時器T0工作模式為16位的定時計數器模式,置位總中斷允許位EA并給顯示端口P0和P2清0。然后調用超聲波發生子程序送出一個超聲波脈沖,為避免超聲波從發射器直接傳送到接收器引起的直接波觸發,需延遲0.1ms(這也就是測距器會有一個最小可測距離的原因)后,才打開外中斷0接收返回的超聲波信號。由于采用12MHz的晶振,機器周期為1us,當主程序檢測到接收成功的標志位后,將計數器T0中的數(即超聲波來回所用的時間)按下式計算即可測得被測物體與測距儀之間的距離,設計時取20℃時的聲速為344m/s則有:

        d=(C*T0)/2=172T0/10000cm(其中T0為計數器T0的計數值)

        測出距離后結果將以十進制BCD碼方式LED,然后再發超聲波脈沖重復測量過程。主程序框圖如下

         

        3.超聲波發生子程序和超聲波接收中斷程序

        超聲波發生子程序的作用是通過P1.0端口發送2個左右的超聲波信號頻率約40KHz的方波,脈沖寬度為12us左右,同時把計數器T0打開進行計時。超聲波測距器主程序利用外中斷0檢測返回超聲波信號,一旦接收到返回超聲波信號(INT0引腳出現低電平),立即進入中斷程序。進入該中斷后就立即關閉計時器T0停止計時,并將測距成功標志字賦值1。如果當計時器溢出時還未檢測到超聲波返回信號,則定時器T0溢出中斷將外中斷0關閉,并將測距成功標志字賦值2以表示此次測距不成功。

        六.軟硬件調試及性能

        超聲波測距儀的制作和調試,其中超聲波發射和接收采用Φ15的超聲波換能器TCT40-10F1(T發射)和TCT40-10S1(R接收),中心頻率為40kHz,安裝時應保持兩換能器中心軸線平行并相距4~8cm,其余元件無特殊要求。若能將超聲波接收電路用金屬殼屏蔽起來,則可提高抗干擾能力。根據測量范圍要求不同,可適當調整與接收換能器并接的濾波電容C4的大小,以獲得合適的接收靈敏度和抗干擾能力。

        硬件電路制作完成并調試好后,便可將程序編譯好下載到單片機試運行。根據實際情況可以修改超聲波發生子程序每次發送的脈沖寬度和兩次測量的間隔時間,以適應不同距離的測量需要。根據所設計的電路參數和程序,測距儀能測的范圍為0.07~5.5m,測距儀最大誤差不超過1cm。系統調試完后應對測量誤差和重復一致性進行多次實驗分析,不斷優化系統使其達到實際使用的測量要求。

        后續工作需實驗后才能驗證

        根據參考電路和集成的電路器件測距范圍有限10m以內為好。

        程序清單

        以下是用匯編語言編寫的超聲波測距控制源程序:

        采用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位自動重裝模式,T0為16位定時器

        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 ;超聲波脈沖個數控制(為賦值的一半)

        SETB PX0

        SETB ET0

        STEB EA

        CLR 00H

        SETB TR0 ;開啟測距定時器

        START1: LCALL DISPLAY

        JNB 00H, START1 ;收到反射信號時標志位為1

        CLR EA

        LCALL WORK ;計算距離子程序

        SETB EA

        CLR 00H

        SETB TR0 ;重新開啟測距定時器

        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 ;啟動計時器T0,用以計算超聲波來回時間

        SETB TR1 ;開啟發超聲波用定時器T1

        OUT: RETI

        ;T1中斷,發超聲波用

        INTT1: CPL VOUT

        DJNZ R4,RETIOUT

        CLR TR1 ;超聲波發送完畢,關T1

        CLR ET1

        MOV R4,#04H

        SETB EX0 ;開啟接收回波中斷

        RETIOUT: RETI

        ;外中斷0,收到回波時進入

        PINT0: CLR TR0 ;關計數器

        CLR TR1

        CLR ET1

        CLR EA

        CLR EX0

        MOV 44H, TL0 ;將計數值移入處理單元

        MOV 45H, TH0

        SETB 00H ;接收成功標志

        RETI

        *延時程序*

        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

        ;共陽數碼管 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,不點亮

        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

        *兩字節無符號數乘法程序

        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

        *四字節/兩字節無符號數除法程序*

        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



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 山阳县| 永定县| 庆元县| 商南县| 逊克县| 芦山县| 乐亭县| 延吉市| 彩票| 鄢陵县| 从化市| 视频| 霸州市| 额济纳旗| 郎溪县| 惠州市| 封开县| 自贡市| 林州市| 绩溪县| 清水河县| 久治县| 秭归县| 黄山市| 安新县| 平凉市| 宝丰县| 嘉定区| 黄龙县| 普兰店市| 酉阳| 平和县| 台湾省| 建宁县| 江孜县| 都安| 呼伦贝尔市| 中宁县| 保定市| 卢湾区| 浮山县|