超聲波測距資料:內(nèi)涵原理圖電路圖,程序,以及pcb,實訓報告。
0.png (52.96 KB, 下載次數(shù): 194)
下載附件
2018-6-28 05:24 上傳
全部資料51hei下載地址:
超聲波測距.rar
(3.77 MB, 下載次數(shù): 924)
2018-6-27 19:38 上傳
點擊文件名下載附件
超聲波測距資料 下載積分: 黑幣 -5
單片機課程設計報告 學 院 電子信息科學學院 設 計 題 目 超聲波測距 專 業(yè) 名 稱 電子信息工程 班 級 XXXXX 學號、姓 名 XXXXXXXXXXXXXXXXXXXXXX 指 導 教 師 XXXXXX 2018年 1 月 10日
目錄
摘要: 1 系統(tǒng)設計目的、要求、總體方案及硬件設計 1 設計目的和要求 1.1設計目的 1.2設計要求 2 硬件電路設計 2.1總體方案設計 2 單元電路設計 2.1晶振電路 2.2復位電路 2.3電源設計部分 2.4 8位數(shù)碼管顯示電路 2.5報警電路設計 2.6超聲波測距模塊 2.7 超聲波傳感器原理 2.9按鍵電路 2.10硬件電路總圖 3 軟件設計 3.1 主程序流程圖 3.2超聲波測距模塊流程圖 4 pr otel軟件仿真及PCB板 4.1 原理圖的繪制 4.2 Protues仿真結(jié)果 4.3 Pcb圖 5 實驗結(jié)果 程序: 總結(jié) 附錄 參考文獻
超聲波測距 摘要: 超聲波指向性強,能量消耗緩慢,在介質(zhì)中傳播的距離比較遠,因此超聲波常用于障礙物的距離測量。由于超聲波可以做到無接觸檢測距離,這一特性在人體獲其他物體高度的測量上會非常方便。本設計采用以AT89C51為核心的低成本、高精度、數(shù)字顯示超聲波測距的硬件電路和軟件設計方法。整個電路采用模塊化設計,由主程序、中斷程序、HC-RS04超聲波傳感器的發(fā)射接受程序、顯示子程序等模塊組成。最終通過電路來實現(xiàn)測距功能,當距離小于設定值或距離超過程序設定最遠距離值啟動報警機制。
關鍵詞 AT89C51單片機;HC-SR04超聲波傳感器;蜂鳴器; 1 系統(tǒng)設計目的、要求、總體方案及硬件設計1 設計目的和要求1.1設計目的了解超聲波測距原理; 根據(jù)超聲波測距原理,設計超聲波測距儀的硬件結(jié)構(gòu)電路和軟件程序; 1.2設計要求 1.自己設定測量距離,要求做到測量距離精確; 2.以數(shù)碼管的形式顯示測量的距離; 3.用蜂鳴器以及二極管實現(xiàn)報警功能; 4.報警距離必須可調(diào); 2 硬件電路設計2.1總體方案設計 按模塊劃分可分為數(shù)據(jù)采集、按鍵控制、數(shù)碼管顯示、發(fā)光二極管和蜂鳴器報警四個子模塊。電路結(jié)構(gòu)劃分可以劃分為:超聲波傳感器、蜂鳴器、單片機控制電路。本次設計的核心是單片機控制模塊,所以此設計是單片機應用系統(tǒng) 的一種應用。系統(tǒng)采用STC89C51RD+單片機作為核心控制單元,當測量距離小于設定距離時,主控芯片將測量的距離與設定值進行比較處理,然后控制蜂鳴器報警。系統(tǒng)總體的設計框圖如圖所示:
圖一:總體方案設計 2 單元電路設計2.1晶振電路AT89C51雖然有內(nèi)部振蕩電路,但要形成時鐘,必須外部附加電路。AT89C51單片機的時鐘產(chǎn)生方法有兩種。內(nèi)部時鐘方式和外部時鐘方式。 晶振是給單片機提供工作信號脈沖的 這個脈沖就是單片機的工作速度 比如 12M晶振單片機工作速度就是每秒12M 當然單片機的工作頻率是有范圍的不能太大 一般24M就不上去了不然不穩(wěn)定。 本次設計采用的是內(nèi)部時鐘方式:
如圖二所示:晶振與單片機的腳XTAL0和腳XTAL1內(nèi)部的振蕩電路便產(chǎn)生自激振蕩。構(gòu)成的振蕩電路中會產(chǎn)生偕波(也就是不希望存在的其他頻率的波) 這個波對電路的影響不大 但會降低電路的時鐘振蕩器的穩(wěn)定性。為了電路的穩(wěn)定性起見 ATMEL公司只是建議在晶振的兩引腳處接入兩個10pf-50pf的瓷片電容接地來削減偕波對電路的穩(wěn)定性的影響所以晶振所配的電容在10pf-50pf之間都可以的沒有什么計算公式。 因為一個機器周期含有6個狀態(tài)周期,而每個狀態(tài)周期為2個振蕩周期,所以一個機器周期共有12個振蕩周期,如果外接石英晶體振蕩器的振蕩頻率為12MHZ,一個振蕩周期為1/12us,故而一個機器周期為1us。如圖7所示為時鐘電路。 圖二:晶振電路 2.2復位電路 在電路圖中,電容的的大小是1uf,電阻的大小是100。所以根據(jù)公式,可以算出電容充電到電源電壓的0.7倍(單片機的電源是5V,所以充電到0.7倍即為3.5V),需要的時間是100*1UF=0.0001S。也就是說在電腦啟動的0.0001S內(nèi),電容兩端的電壓時在0~3.5V增加。這個時候100電阻兩端的電壓為從5~1.5V減少(串聯(lián)電路各處電壓之和為總電壓)。所以在0.0001S內(nèi),RST引腳所接收到的電壓是5V~1.5V。在5V正常工作的51單片機中小于1.5V的電壓信號為低電平信號,而大于1.5V的電壓信號為高電平信號。所以在開機0.0001S內(nèi),單片機系統(tǒng)自動復位(RST引腳接收到的高電平信號時間為0.0001S左右)。 復位方法有上電自動復位和手動復位兩種,單片機在時鐘電路工作以后, 在RESET端持續(xù)給出2個機器周期的高電平時就可以完成復位操作。例如使用晶振頻率為12MHz時,則復位信號持續(xù)時間應不小于2us。本設計采用的是自動復位電路。如圖3示為復位電路。 圖三:復位電路 2.3電源設計部分 三節(jié)5號電池共4.5V 2.4 8位數(shù)碼管顯示電路本電路的顯示首先考慮到兩種方案,一種數(shù)碼管顯示,另外一種是LCD屏幕顯示。LCD屏幕顯示雖然看得比較清晰,但是成本較高。所以從節(jié)約成本的角度出發(fā)決定使用4位8段數(shù)碼管,數(shù)碼管接在P0口需要驅(qū)動, 驅(qū)動方式一:用芯片74HC573驅(qū)動 驅(qū)動方式二:用PNP三極管放大從而驅(qū)動 驅(qū)動方式三:P0口接上拉電阻驅(qū)動 綜上三種方式考慮,P0口接上拉電阻驅(qū)動會比較節(jié)約成本,并且接線比較簡單,可以減少電路的復雜度。所以最終選擇驅(qū)動方式三。位選分別接在P1.0-P1.3口,如圖四所示: 圖四:數(shù)碼管顯示 2.5報警電路設計 當測量距離超過設定的最大距離值時以及測量距離小于報警數(shù)時電路會觸發(fā)報警系統(tǒng),使得蜂鳴器長響LED燈亮起來,如圖五所示: 圖五:報警系統(tǒng) 2.6超聲波測距模塊超聲波模塊采用現(xiàn)成的HC-SR04超聲波模塊,該模塊可提供 2cm-400cm 的非接觸式距離感測功能,測距精度可達高到 3mm。模塊包括超聲波發(fā)射器、接收器與控制電路。基本工作原理:采用 IO 口 TRIG 觸發(fā)測距,給至少 10us 的高電平信號;模塊自動發(fā)送 8 個 40khz 的方波如圖6,自動檢測是否有信號返回;有信號返回,通過 IO 口 ECHO 輸出一個高電平,高電平持續(xù)的時間就是超聲波從發(fā)射到返回的時間。測試距離=(高電平時間*聲速(340M/S))/2。實物如下圖7。其中VCC 供5V 電源,GND 為地線,TRIG 觸發(fā)控制信號輸入,ECHO 回響信號輸出等四支線。 超聲波探測模塊HC-SR04的使用方法如下:IO口觸發(fā),給Trig口至少10us的高電平,啟動測量;模塊自動發(fā)送8個40Khz的方波并隨時檢測是否有信號返回,有信號返回,通過Echo輸出一個高電平,高電平持續(xù)的時間就是超聲波從發(fā)射到返回的時間,測試距離=(高電平時間*340)/ 2,單位為m。程序中測試功能主要由兩個函數(shù)完成。 實現(xiàn)中采用定時器0進行定時測量,8分頻,TCNTT0預設值0XCE,當timer0溢出中斷發(fā)生2500次時為125ms,計算公式為(單位:ms): T = (定時器0溢出次數(shù) * (0XFF - 0XCE))/ 1000 其中定時器0初值計算依據(jù)分頻不同而有差異。
圖六:Tring觸發(fā)波形
圖七:超聲波傳感器HC-SR04 和仿真圖 2.7 超聲波傳感器原理市面上常見的超聲波傳感器多為開放型,其內(nèi)部結(jié)構(gòu)如圖8所示,一個復合式振動器被靈活地固定在底座上。該復合式振動器是由諧振器以及一個金屬片和一個壓電陶瓷片組成的雙壓電晶片元件振動器。諧振器呈喇叭形,目的是能有效地輻射由于振動而產(chǎn)生的超聲波,并且可以有效地使超聲波聚集在振動器的中央部位。 當電壓作用于壓電陶瓷時,就會隨電壓和頻率的變化產(chǎn)生機械變形。另一方面,當振動壓電陶瓷時,則會產(chǎn)生一個電荷。利用這一原理,當給由兩片壓電陶瓷或一片壓電陶瓷和一個金屬片構(gòu)成的振動器,所謂叫雙壓電晶片元件,施加一個電信號時,就會因彎曲振動發(fā)射出超聲波。相反,當向雙壓電晶片元件施加超聲振動時,就會產(chǎn)生一個電信號;谝陨献饔茫憧梢詫弘娞沾捎米鞒暡▊鞲衅。
圖8 超聲波內(nèi)部結(jié)構(gòu) 超聲波是一種在彈性介質(zhì)中的機械振蕩,其頻率超過20KHz,分橫向振蕩和縱向振蕩兩種,超聲波可以在氣體、液體及固體中傳播,其傳播速度不同。它有折射和反射現(xiàn)象,且在傳播過程中有衰減。 2.8測距分析 超聲波發(fā)射器向某一方向發(fā)射超聲波,在發(fā)射時刻的同時開始計時,超聲波在空氣中傳播,途中碰到障礙物就立即返回來,超聲波接收器收到反射波就立即停止計時。超聲波在空氣中的傳播速度為340m/s,根據(jù)計時器記錄的時間t,就可以計算出發(fā)射點距障礙物的距離(s),即:s=340t/2 最常用的超聲測距的方法是回聲探測法,超聲波發(fā)射器向某一方向發(fā)射超聲波,在發(fā)射時刻的同時計數(shù)器開始計時,碰到障礙物的阻擋就立即反射回來,超聲波接收器收到反射回的超聲波就立即停止計時并計算出距離。以超聲波在空氣中的傳播速度為340m/s計算,根據(jù)定時器算出的時間t,就可以計算出發(fā)射點距障礙物面的距離s,即:s=340t/2。 由于超聲波也是一種聲波,其聲速V與溫度有關。在使用時,如果傳播介質(zhì)溫度變化不大,則可近似認為超聲波速度在傳播的過程中是基本不變的。如果對測距精度要求很高,則應通過溫度補償?shù)姆椒▽y量結(jié)果加以數(shù)值校正。聲速確定后,只要測得超聲波往返的時間,即可求得距離。這就是超聲波測距的基本原理。如圖9所示:
圖9 超聲波的測距原理 (3-1)
(3-2)
式中:L---兩探頭之間中心距離的一半. 又知道超聲波傳播的距離為: ( 3-3)式中:v—超聲波在介質(zhì)中的傳播速度; t—超聲波從發(fā)射到接收所需要的時間. 將(3—2)、(3—3)代入(3-1)中得: ( 3-4)其中,超聲波的傳播速度v在一定的溫度下是一個常數(shù)(例如在溫度T=30度時,V=349m/s);當需要測量的距離H遠遠大于L時,則(3—4)變?yōu)? ( 3-5) 所以,只要需要測量出超聲波傳播的時間t,就可以得出測量的距離H. 2.9按鍵電路 本設計設置了三個按鍵開關,鏈接P1.4的按鍵負責報警數(shù)的加一操作,連接P1.5的按鍵負責報警數(shù)的減一操作,連接P1.6的按鍵負責模式的選擇。模式0:超聲波測距模式,模式1:設置報警數(shù)如圖10所示:
圖10:按鍵開關 2.10 硬件電路總圖
圖10:超聲波測距模式
11:調(diào)節(jié)報警數(shù)
3 軟件設計
3.1 主程序流程圖 按工作原理和硬件電路圖得到主流程圖如下:
主流程圖
3.2超聲波測距模塊流程圖
超聲波測試模塊流程
4 protel軟件仿真及PCB板 仿真平臺為Proteus軟件,Proteus軟件是世界上著名的EDA工具(仿真軟件),能完成原理圖布圖、代碼調(diào)試到單片機與外圍電路協(xié)同仿真,一鍵切換到PCB設計它不僅具有其它EDA工具軟件的仿真功能,還能仿真單片機及外圍器件,是目前最好的仿真單片機及外圍器件的工具。 PROTEUS電路設計是在PROTEUS ISIS環(huán)境中繪制的,該編輯環(huán)境具有良好的人機交互界面,功能強大極易上手。首先通過桌面進入主程序,繪制原來圖的主要任務是從元件庫中選取繪制電路所需要的元件。可以通過點擊選擇器頂端左側(cè)的“P”或者通過命令打開,我們常用的是按鈕;在查找到并放置完所有需要的器件后,我們需要接著連接元件,即在PROTEUS ISIS的編輯窗口布線。PROTEUS ISIS中沒有布線模式,但用戶可以在任意時刻放置連線和編輯連線。在完成繪制所需的電路圖前,用戶需要放置并連接斷軸。在電路原理圖中放置兩種通用的端子,一種是接地端子一種是電源端子。當在PROTEUS ISIS編輯窗口放置元件時,每一元件都有唯一的元件標號及元件值與之對應。原件號是PROTEUS ISIS的實時注釋功能自動標注的,這一功能可在菜單中設置選擇是否開啟。PROTEUS ISIS中也支持塊操作,當用戶需要對電路中的某一部分進行操作時,可以使用該功能。系統(tǒng)共支持塊移動、塊復制、塊旋轉(zhuǎn)、塊刪除等實用功能,充分利用這些功能可以極大的提高我們繪圖的效率。我們繪制完所有的元件后,最后進行統(tǒng)一標注,PROTEUS ISIS支持注釋功能,可以把我們所繪制的原理圖中的器件根據(jù)我們的需要添加上特殊的注釋,以表示特定的含義。根據(jù)設計電路繪制完后的電路圖如圖4-1所示。 4.1 原理圖的繪制
圖4-1 4.2 Protues仿真結(jié)果模式0:測量距離 模式1:調(diào)節(jié)報警數(shù) 測量距離超過4米 測量距離小于報警數(shù) 4.3 Pcb圖
5 實驗結(jié)果
單片機源程序如下:
- #include <reg52.H>//器件配置文件
- #include <intrins.h>
- //傳感器接口
- sbit RX = P3^2;
- sbit TX = P3^3;
- //按鍵聲明
- sbit S1 = P1^4;
- sbit S2 = P1^5;
- sbit S3 = P1^6;
- //蜂鳴器
- sbit Feng= P2^0;
- sbit W1=P1^0;
- sbit W2=P1^1;
- sbit W3=P1^2;
- sbit W4=P1^3;
- //變量聲明
- unsigned int time=0;
- unsigned int timer=0;
- unsigned char posit=0;
- unsigned long S=0;
- unsigned long BJS=50;//報警距離80CM
- //模式 0正常模式 1調(diào)整
- char Mode=0;
- bit flag=0;
- bit flag_KEY=0;
- unsigned char const discode[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0xff/*-*/};
- //數(shù)碼管顯示碼0123456789-和不顯示unsigned char const positon[4]={0xfd,0xfb,0xf7,0xfe}; //位選
- unsigned char disbuff[4] ={0,0,0,0}; //數(shù)組用于存放距離信息
- unsigned char disbuff_BJ[4] ={0,0,0,0};//報警信息
- void Display();
- //延時20ms(不精確)
- void delay(void)
- {
- unsigned char a,b,c;
- for(c=2;c>0;c--)
- for(b=38;b>0;b--)
- for(a=60;a>0;a--);
- }
- //按鍵掃描
- void Key_()
- {
- if(flag_KEY==0)
- {
- if(Mode!=0)
- {
- //+
- if(S1==0)
- {
- delay(); //延時去抖
- if(S1==0)
- {
- BJS++; //報警值加
- flag_KEY=1;
- if(BJS>=151) //最大151
- {
- BJS=0;
- }
- // while(S1==0)
- // Display();
- }
-
- }
- //-
- if(S2==0)
- {
- delay();
- if(S2==0)
- {
- BJS--; //報警值減
- flag_KEY=1;
- if(BJS<=1) //最小1
- {
- BJS=150;
- }
- // while(S2==0)
- // Display();
- }
-
- }
- }
- //功能
- if(S3==0) //設置鍵
- {
- delay();
- if(S3==0)
- {
- Mode++; //模式加
- flag_KEY=1;
- if(Mode>=2) //加到2時清零
- {
- Mode=0;
- }
- while(S3==0)
- Display();
- }
- }
- }
- if((P1&0x70)==0x70)
- {
- flag_KEY=0;
- }
- }
- /**********************************************************************************************************/
- //掃描數(shù)碼管
- void Display(void)
- {
- //正常顯示
- if(Mode==0)
- {
- P0=0x00; //關閉顯示
- if(posit==1)//數(shù)碼管的小數(shù)點
- {
- P0=(discode[disbuff[posit]])|0x80;//按位或,最高位變?yōu)?,顯示小數(shù)點
- }
- else if(posit==0)
- {
- P0=~discode[11];
- }
- else
- {
- P0=discode[disbuff[posit]];
- }
- switch(posit)
- {
- case 0 : W1=0;W2=1;W3=1;W4=1; break;
- case 1 : W1=1;W2=0;W3=1;W4=1; break;
- case 2 : W1=1;W2=1;W3=0;W4=1; break;
- case 3 : W1=1;W2=1;W3=1;W4=0; break;
- }
- posit++;
- if(posit>3) //每進一次顯示函數(shù),變量加1
- posit=0; //加到3時清零
- }
- //報警顯示
- else
- {
- P0=0x00;
- if(posit==1)//數(shù)碼管的小數(shù)點
- {
- P0=(discode[disbuff_BJ[posit]])|0x80;
- }
- else if(posit==0)
- {
- P0=0x76; //顯示字母
- }
- else
- {
- P0=discode[disbuff_BJ[posit]];
- }
- switch(posit)
- {
- case 0 : W1=0;W2=1;W3=1;W4=1; break;
- case 1 : W1=1;W2=0;W3=1;W4=1; break;
- case 2 : W1=1;W2=1;W3=0;W4=1; break;
- case 3 : W1=1;W2=1;W3=1;W4=0; break;
- }
- posit++;
- if(posit>3)
- posit=0;
- }
- }
- /**********************************************************************************************************/
- //計算
- void Conut(void)
- {
- time=TH0*256+TL0; //讀出T0的計時數(shù)值
- TH0=0;
- TL0=0; //清空計時器
- S=(time*1.7)/100; //算出來是CM
- //聲音的速度是340m/s,時間的單位是us,計算到秒需要將時間數(shù)據(jù)/1000000,
- //長度=速度*時間,340*time/1000000,長度數(shù)據(jù)單位是m轉(zhuǎn)換成cm需要乘以100得到340*time/10000,
- //小數(shù)點都向左移兩位得到3.4*time/100,因為超聲波是往返了,所以再除以2,得到距離數(shù)據(jù)(time*1.7)/100
- if(Mode==0) //非設置狀態(tài)時
- {
- if((S>=700)||flag==1) //超出測量范圍顯示"-"
- {
- Feng=0; //蜂鳴器報警
- flag=0;
- disbuff[1]=10; //"-"
- disbuff[2]=10; //"-"
- disbuff[3]=10; //"-"
- }
- else
- {
- //距離小于報警距
- if(S<=BJS)
- {
- Feng=0; //報警
- }
- else //大于
- {
- Feng=1; //關閉報警
- }
- disbuff[1]=S%1000/100; //將距離數(shù)據(jù)拆成單個位賦值
- disbuff[2]=S%1000%100/10;
- disbuff[3]=S%1000%10 %10;
- }
- }
- else
- {
- Feng=1;
- disbuff_BJ[1]=BJS%1000/100;
- disbuff_BJ[2]=BJS%1000%100/10;
- disbuff_BJ[3]=BJS%1000%10 %10;
- }
- }
- /**********************************************************************************************************/
- //定時器0
- void zd0() interrupt 1 //T0中斷用來計數(shù)器溢出,超過測距范圍
- {
- flag=1; //中斷溢出標志
- }
- /**********************************************************************************************************/
- //定時器1
- void zd3() interrupt 3 //T1中斷用來掃描數(shù)碼管和計800MS啟動模塊
- {
- TH1=0xf8;
- TL1=0x30; //定時2ms
- Key_(); //掃描按鍵
- Display(); //掃描顯示
- timer++; //變量加
- if(timer>=400) //400次就是800ms
- {
- timer=0;
- TX=1; //800MS 啟動一次模塊
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- TX=0;
- }
- }
- /**********************************************************************************************************/
- //主函數(shù)
- void main(void)
- {
- TMOD=0x11; //設T0為方式1
- TH0=0;
- TL0=0;
- TH1=0xf8; //2MS定時
- TL1=0x30;
- ET0=1; //允許T0中斷
- ET1=1; //允許T1中斷
- TR1=1; //開啟定時器
- EA=1; //開啟總中斷
- while(1)
- {
- while(!RX); //當上次接收完波后,RX引腳是低電平,取反就是1,此while成立,反復判斷RX狀態(tài)。當RX沒有接收到返回波時是高電平,取反就是0,此while不成立,跳出
- TR0=1; //開啟計數(shù)
- while(RX); //當RX沒有接收到返回波,此while成立,程序停在這里一直判斷RX狀態(tài)。當RX接收到返回波,RX引腳變?yōu)榈碗娖,此while不成立,跳出
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
|