發布日期:2022-10-09 點擊率:477
一、原理介紹
遇到障礙物,能夠感應做出反應,超聲波可以作為一種測量手段,超聲波在固體液體氣體中傳播良好,氣體中速度約為340m/s。如果知道時間,那么就可以計算出距離。利用宏晶STC89C52計算超聲波模塊HC-SR04反饋信號高電平的時間,換算成距離顯示在數碼管上(這里用573和138組合的共陰極數碼管顯示電路)。
STC89C52是國產宏晶的一塊8位寄存器芯片,IO準雙向口,可以輸入輸出,七個中斷源,六個中斷通道,有ISP系統,支持USB串口下載,8KB系統可編程下載Flash(程序儲存空間),512BRAM(數據儲存空間),27個特殊功能寄存器。
HC-SR04超聲波模塊,模塊四個引腳觸發信號Trig,回聲信號Echo,供電VCC和GND,測量周期60ms以上。當給Trig一個10us以上的脈沖時,HC-SR04內部自動循環發出8個40KHz的脈沖,Echo剛收到回波時置一(超出一定范圍收到的信號不夠HC-SR04置一定時器不計數),單片機定時器開始計數,直到Echo沒有收到信號置零,記了TH+TL次機器周期,一個機器周期需要12個振蕩周期,由此時間就可以計算出來,再用時間X速度就可以計算出距離S。
數碼管有七段的,十四段的,十六段的,這里用的八位共陰極七段數碼管。共陰極數碼管就是共地,a,b,c,d,e,f,g,h對應哪一段輸入高電平,哪一段LED亮,所以特定的組合可以顯示0~9數字,所以有共陰極段碼表,一組數組,顯示幾就對P0端口賦值對應這個數值的下標的數組元素。
HC-SR04收發信號,STC89C52計算結果,數碼管顯示,74HC573負責數碼管的段選,74LS138負責數碼管的位選。
二、仿真測試
完整的電路仿真圖如圖一所示,首先打開Protues ISIS新建一個空白文件,從庫中拾取元件,選擇IC芯片AT89C52,第一步取兩個20PF~33PF的電容一個晶振和個地信號組成晶振電路,第二步給P0口上拉一的330歐的排阻,第三步加入兩個四位共陰極(CC)七段數碼管,第四步加一個74HC573進行段選,連接數碼管的段選引腳,第五步加入一個74LS138,三位地址線控制八位位選,連接上數碼管的位選位,第六步構造一個HC-SR04超聲波傳感器模塊,并根據程序連好線,第七步加入一個信號源和一個示波器,方便模擬測試,電路連接完成。
圖一 仿真電路
激勵源連接在HC-SR04模塊的Echo腳上,進行如圖二的設置。
圖二 激勵源設置
示波器分別接上HC-SR04的Trig和Echo腳,雙擊主控芯片,打開程序生成的hex文件,點擊運行,得到如圖三的結果。
圖三 仿真結果
首先黃色線是Trig,放大看了下,如圖四。單位5us,由圖可見四格多,這個觸發信號高電平20幾us,符合資料中Trig觸發信號高電平要保持10us以上。其次水平滾輪每20代表一格即一個單位,結合圖三和圖五,兩個發射信號水平滾輪數間隔左右,800格左右,單位為1ms,即800ms,符合程序中發射間隔800ms。最后數碼管顯示34,給Echo的方波200hz,占空比40%,即高電平2ms,12M晶振的單片機一個機器周期1us,定時器需要計數2000次,所以TH+TL=2000,根據公式S=(Th+TL)X1.7/100=34cm。綜上所述,仿真程序設計沒有問題。
圖四 觸發信號保持時間
圖五 觸發信號間隔時間
三、程序設計
? ?
#include "reg51.h"
#include
//常變量定義:
code unsigned char table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//表:共陰數碼管 0-9 -
unsigned int ?time=0;
unsigned int ?timer=0;
unsigned long S=0;
bit flag =0;
unsigned char l_disbuff[4]={ 0,0,0,0};//顯示緩沖
unsigned char l_posit=1; //位選擇
//引腳定義:
//sbit SMG_q = P2^2; //定義數碼管陽級控制腳(千位)本例程只用到三位數碼管
sbit SMG_b = P2^2; //定義數碼管陽級控制腳(百位)
sbit SMG_s = P2^3; //定義數碼管陽級控制腳(十位)
sbit SMG_g = P2^4; //定義數碼管陽級控制腳(個位)
sbit RX = P2^1; //模塊引腳
sbit TX = P2^0;
//顯示函數,參數為顯示內容
void display()
{
P0=0x00; //
switch(l_posit){
case 0: //選擇千位數碼管,關閉其它位
//SMG_q=0;
SMG_b=1;
SMG_s=1;
SMG_g=1;
P0=table[l_disbuff[0]];
break;
case 1: //選擇百位數碼管,關閉其它位
//SMG_q=1;
SMG_b=0;
SMG_s=1;
SMG_g=1;
P0=table[l_disbuff[1]];//加入小數點要與一下
break;
case 2: //選擇十位數碼管,關閉其它位
//SMG_q=1;
SMG_b=1;
SMG_s=0;
SMG_g=1;
P0=table[l_disbuff[2]];
break;
case 3: //選擇個位數碼管,關閉其它位
//SMG_q=1;
SMG_b=0;
SMG_s=0;
SMG_g=1;
P0=table[l_disbuff[3]];
break;
}
l_posit++;
if(l_posit>3)
l_posit=0;
}
void Count(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100; ? ? //算出來是CM
if((S>=700)||flag==1) //超出測量范圍顯示“-”
{ ?
?flag=0;
?l_disbuff[1]=10; ? //“-”
?l_disbuff[2]=10; ? //“-”
?l_disbuff[3]=10; ? //“-”
}
else
{
?l_disbuff[1]=S%1000/100;
?l_disbuff[2]=S%1000%100/10;
?l_disbuff[3]=S%1000%10 %10;
}
}
void zd0() interrupt 1 //T0中斷用來計數器溢出,超過測距范圍
{
? ? flag=1; //中斷溢出標志
}
void ?zd3() ?interrupt 3 //T1中斷用來掃描數碼管和計800MS啟動模塊
{
TH1=0xf8;
TL1=0x30;
display();
timer++;
if(timer>=400)
{
?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;
}?
}
void ?main( ?void ?)
{ ?
? ? TMOD=0x11; ? //設T0,T1為方式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為零時等待
TR0=1; ? ?//開啟計數
while(RX); //當RX為1計數并等待
TR0=0; //關閉計數
? ? ?Count(); //計算
}
}
? ? ? ? ? ? ?
四、實物測試
一、模塊介紹
1.1 模塊圖示
模塊共有四個引腳,分別是Vcc(供5V電源)、Trig(控制端,下文簡稱Tr)、Echo(接收端,下文簡稱Ec)、Gnd(地線)
2.2 產品參數
?
二、 工作原理(時序)
在初始狀態時,Tr引腳電平由單片機拉高,Ec引腳電平由傳感器拉低。工作時,首先由單片機將Tr引腳拉低后再給一個高電平脈沖(持續時間至少為10us),傳感器收到該脈沖信號后開始向外發射8個40KHz的方波即用來測距的超聲波。該測距超聲波以聲速(340m/s)向前傳播,在遇到障礙物時,該超聲波被反彈向回傳播,因此最終能夠被傳感器接收到,傳感器會記錄從發射超聲波到接收到超聲波的所經歷的時間t。傳感器在收到返回的信號后,由Ec引腳輸出一個與t相同時間的高電平脈沖。此時,我們只需要通過單片機內部定時/計數器記錄Ec引腳高電平脈沖時間即可得超聲波的傳播時間t。因此可算出傳感器到障礙物間的距離=340*(t/2)? ?(因為t是超聲波一來一回經歷的時間,所以單程時間要除以2)。
?
三、例程(例程均為自己編寫且仿真通過)
單片機為AT89C52,工作頻率為12Mhz,最終結果通過八段數碼管顯示。
注意:因為12MHz的單片機的機器周期為1us,即計數值就等于以us為單位的時間值,因此計算公式 可以寫為? 時間=TH0*256+TL0;但如果使用的單片機工作頻率為11.0592MHz,其機器周期為1.085us,因此時間計算公式需寫為? 時間=(TH0*256+TL0)*1.085
?
四、仿真電路
?
左肩理想右肩擔當,君子不怨永遠不會停下腳步!
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
大多數人感覺超聲波測距proteus仿真是無法實現的,雖然proteus自帶的庫有GUR03和SRF04兩種模型,但是卻與實際傳感器使用方法相差甚遠,即使求助度娘也很難找到簡單易懂的教程。
gur03和srf04.png (8.23 KB, 下載次數: 61)
下載附件
2020-3-31 23:52 上傳
之前很多人想做超聲波測距仿真但都沒有找到很好的辦法去實現,在軟件里沒有這樣的元件,有人用一個按鍵開關去模擬仿真,這樣仿真出來的效果,非常不好。還有人用555時基電路產生一個延時信號(555電路作為超聲波仿真的內部元件),來模擬超聲波頭發送后遇到回波返射回來的這階段時間,來對單片機超聲波測距單片機系統進行模擬,能完成對超聲波測距模塊大致仿真,但需要繁雜的設計。
下面是一個超聲波測距模塊的proteus模型,能直接用于proteus仿真,且使用方法與實際傳感器幾乎一致,模型如下圖。樓主千辛萬苦終于完成了仿真,分享交流一下,請大家不嗇賜教!
ULTRASonIC SENSOR.png (23.56 KB, 下載次數: 82)
下載附件
2020-3-31 23:56 上傳
(library文件見附件)
下面是仿真效果:
simulation.png (157.85 KB, 下載次數: 77)
下載附件
2020-4-1 00:06 上傳
單片機程序代碼:#include
//生成20us的脈沖寬度的觸發信號
Trig=1;
Delay20us();
Trig=0;
//等待回響信號變高電平
while(!Echo);
TR0=1; //啟動定時器0
//等待回響信號變低電平
while(Echo);
TR0=0; //關閉定時器0
//返回距離值(mm)
return (SPEEDSOUND*(TH0*256.0+TL0))/2000;
}
//HCSR04初始化
void HCSR04_Initialize()
{
SPEEDSOUND=334.1+25*0.61;
Trig=0;
Echo=0;
TMOD=0x01;
}
//測距的數值排序求平均
float DistanceStatistics()
{
uchar i;
float disData;
for(i=0;i<7;i++) //連續測距
{
disData+=MeasuringDistance();
delay(1);
}
return disData/7.0;
}
void main()
{
LcdInitiate();//1602初始化
HCSR04_Initialize();//HC-SR04初始化
while(1)
{
Distancevalue=DistanceStatistics() ;
display_val((int)Distancevalue,0x45);//顯示距離值
delay(1000);
LEDRed=~LEDRed; //測距系統工作指示燈
}
}
復制代碼
全部文件已打包,請自行下載(2個文件內容一樣,推薦下載7z的):
7z:
7z壓縮版.7z
(96.58 KB, 下載次數: 124)
2021-4-28 19:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
winrar:
超聲波測距(仿真原理圖+源程序).rar
(102.08 KB, 下載次數: 1048)
2021-5-17 18:03 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
推薦閱讀
單片機學習筆記————proteus實現虛擬串口
一、環境搭建1.proteus軟件2.虛擬串口軟件3.串口助手二、繪制原理圖使用非門的原因:由于MAX232在proteus中的非符號管腳并無取反的作用。實際不需要。
發表于 2021-11-09
ARM嵌入式實驗 熟悉PROTEUS電子仿真軟件的使用(LPC2138)
一、實驗目的掌握RPROTEUS電子仿真軟件的安裝過程;掌握RPROTEUS電子仿真軟件的使用方法;掌握創建電子仿真原理圖的過程;掌握為ARM芯片添加程序并仿真調試的過程。二、實驗內容實現流水燈仿真實驗。安裝RPROTEUS電子仿真軟件,根據實驗原理圖創建一個PROTEUS原理圖,并添加相應的元件和導線;使用RealView MDK集成開發環境建立并生成實現流水燈的代碼,為ARM芯片添加代碼,最后查看仿真運行結果。三、實驗要求了解RPROTEUS電子仿真軟件的安裝過程;能夠使用RPROTEUS電子仿真軟件建立原理圖并添加元件和導線;能夠設置元件及芯片的參數,并為ARM芯片添加代碼;能夠檢查并修改原理圖的錯誤,并進行仿真運行
發表于 2021-08-11
CVAVR編譯在proteus7.4中無法正確運行問題
這個問題主要會出現在用CVAVR來編譯的程序中。一時興起想弄個仿真,結果怎么著都不正常,AVR的端口一閃一閃的,覺得很奇怪,后來才發現是看門狗溢出了導致單片機不停的復位,把程序下到網上的proteus的AVR中就可以,網上下的proteus中的ATmega16何庫里找出來的不太一樣,就是沒明白為什么庫里調出來的不行。 后來在仿真日志中發現原來是看門狗一直都開著,我又沒喂狗,因此一直都把處理器復位了,這回我更郁悶,我又沒開看門狗,又沒配置fuse,為什么自己會開呢,搞了N久后,發現有這個可能,一個CVAVR本身編譯之后在proteus仿真中,默認開了看門狗(實際上我并沒有開?。。。《以趯嵨镏?,要配置fuse才能開的吧?)經過考究后
發表于 2021-08-05
proteus7.7+Keil2仿真80C51控制流水燈
, 我們還要收集實驗所需的器件(比如多個LED發光二極管、多個阻值不同的電阻、多個不同類型的開關等). 上面的問題可以通過proteus來較好的解決.在"流水燈"實驗中, 我們可以直接在proteus中繪制原理圖. 在proteus元件庫中, 我們可以找到需要的器件, 這是很方便的.在繪制完原理圖后, 打開Keil2, 將編寫好的控制程序(.c)進行編譯, 之后定位到編譯生成的.hex文件, 進入proteus, 將80C51控制程序的路徑改為定位的位置即可.從上面使用proteus進行實驗的步驟來看, 使用軟件仿真是一種極其靈活的方式.將電路的原理圖(下圖示)繪制完畢后, 我們來看一下軟件控制部分
發表于 2021-08-04
proteus7.7+Keil2仿真80C51控制路口信號燈(無綠燈倒計時+綠燈倒計
本例的控制程序未使用80C51的(定時器)中斷功能, 而是以for循環作為延時函數, 以粗略提供0.5s和1s的時延.本例的控制邏輯為①南北方向圓餅燈為紅燈時, 南北方向車輛停止在停車線內等待. ②南北方向圓餅燈為綠燈時, 南北方向車輛(直行和左轉)同時放行. ③東西方向圓餅燈為紅燈時, 東西方向車輛停止在停車線內等待. ④東西方向圓餅燈為綠燈時, 東西方向車輛(直行和左轉)同時放行. ⑤圓餅燈為黃燈時, 未越過停車線的車輛應停車等待. ⑥南北方向和東西方向的右轉車輛在不影響交通秩序的前提下, 可不用看圓餅燈通行.本例的設計邏輯其實并不復雜. 我先將南北方向的信號控制設計好, 之后相對于南北方向設計東西方向即可. 如果非
發表于 2021-08-04
proteus7.7+Keil2仿真80C51控制路口信號燈(帶左轉信號燈)
要想設計帶左轉信號的路口信號燈, 就必須先將圓餅信號燈的控制邏輯理解透徹.在本例的設計過程中, 我設計了本路口的信號控制邏輯: 南北直行放行 -> 東西直行放行 -> 南北左轉放行 -> 東西左轉放行, 若不考慮數碼管的顯示問題, 則只需對圓餅信號燈的控制程序稍加修改即可. 但在實際應用中, 大部分的路口都配備了數字顯示數碼管, 用于顯示直行方向紅、黃、綠燈的倒計時秒數, 以提升交通通行效率——所以, 在此很有必要將倒計時顯示功能加入到設計中.我將完整的信號控制邏輯繪制為下圖.在實際編程中, 由于我一開始并未將控制邏輯完全理清, 所以編寫的控制程序是在圓餅信號控制系統之上經過修修補補完成的, 多少有點碰巧的成分.
發表于 2021-08-04
下一篇: PLC、DCS、FCS三大控
上一篇: 電氣控制線路圖控制原