① 程序中怎麼設置超聲波測距的范圍定時器初值該如何設置12M晶振
超聲波發射開始計時,接收到後停止計數器。得到一個時間,時間乘以速度得到距離。
最小范圍是由你設定的盲區所決定。因為要避開超聲波的餘震。一般可以達到20cm這樣。
最大范圍是有你所用的超聲波發射模塊的功率所決定,因為距離越遠,超聲波衰減的越厲害。如果測距要達到1500cm,那麼超聲波的路程就是3000cm,必須得大大提高發射的功率。同時加大測距間隔。
② 我自己寫了一個超聲波測距的程序,用51單片機,1602液晶顯示,但是現在顯示不出來,請各位大神幫忙
你好,我前段時間使用了HC-SR04超聲波測距儀來測距離,用51單片機控制,LCD1602顯示距離,精確到0.01cm,最大可測400cm。
我把我的程序給你,能做個測距和顯示的參考。
若我們使用的是同一型號的超聲波測距儀,可以回復我一起討論。
希望我的回答能幫助到你。
③ 求基於AT89C52超聲波測距簡易設計的源程序,要求用3個LED管顯示其測距,精確到小數點後2位如,X.XX米。
目前國內超聲波測距器的設計大多採用匯編語言設計。由於單片機應用系統的日趨復雜,要求所寫
的代碼規范化,模塊化,並便於多人以軟體工程的形式進行協同開發,匯編語言作為傳統的單片機應用系
統的編程語言,已經不能滿足這樣的實際需要了,而C語言以其結構化和能產生高效代碼滿足了這樣的需
求,成為電子工程師進行單片機系統編程時的首先編程語言。在本設計中,由於C語言程序有利於實現較
復雜的演算法,匯編語言程序具有較高的效率並且容易精確計算程序運行的時間,而超聲波測距器的程序既
有較復雜的距離計算又要求精確計算超聲波測距時程序運行的時間,所以本設計採用C語言和匯編語言
混合編程來實現。本文論述的是一種基於AT89C52單片機的超聲波測距器,可用於汽車倒車等場合⋯。
1設計要求
設計一個超聲波測距器,可以應用於汽車倒車、建築施工工地以及一些工業現場的位置監控,也可用
於如液位、井深、管道長度的測量等場合。要求測量范圍在0.10—5.00 m,測量精度lem,測量時與被測物
體無直接接觸,能夠清晰穩定地顯示測量結果。
2設計思路
2.1超聲波及其測距原理
超聲波是指頻率高於20KHz的機械波。為了以超聲波作為檢測手段,必須產生超聲波和接收超聲波。
完成這種功能的裝置就是超聲波感測器,習慣上稱為超聲波換能器或超聲波探頭。超聲波感測器有發送
器和接收器,但一個超聲波感測器也可具有發送和接收聲波的雙重作用。超聲波感測器是利用壓電效應
的原理將電能和超聲波相互轉化,即在發射超聲波的時候,將電能轉換為超聲波,發射超聲波;而在收到回
波的時候,則將超聲振動轉換成電信號。
超聲波測距的原理一般採用渡越時間法TOt(time of fliight)。首先測出超聲波從發射到遇到障礙物返
回所經歷的時間,再乘以超聲波的速度就得到二倍的聲源與障礙物之間的距離。測量距離的方法有很多
種,短距離的可以用尺,遠距離的有激光測距等,超聲波測距適用於高精度的中長距離測量。因為超聲波
收稿日期:2008-04-08
作者簡介:周功明(1963一),男,副教授,主要研究方向:電子信息科學技術。
·50· 綿陽師范學院學報(自然科學版) 第27卷
在標准空氣中的傳播速度為331.45粑秒,由單片機負責計時,單片機使用12.0M晶振,所以此系統的測
量精度理論上可以達到毫米級。由於超聲波指向性強,能量消耗緩慢,在介質中傳播距離遠,因而超聲波
可以用於距離的測量。利用超聲波檢測距離,設計比較方便,計算處理也較簡單,並且在測量精度方面也
能達到要求。
超聲波發生器可以分為兩類:一類是用電氣方式產生超聲波,一類是用機械方式產生超聲波。本課題
屬於近距離測量,可以採用常用的壓電式超聲波換能器來實現【7】。
2.2超聲波測距器的系統框圖
根據設計要求並綜合各方面因素,可以採用AT89C52單片機作為主控制器,用動態掃描法實現LED
數字顯示,超聲波驅動信號用單片機的定時器完成,超聲波測距器的系統框圖如下圖l所示¨2|:
3系統組成
3.1硬體部分
主要由單片機系統及顯示電路、超聲波發射電路
和超聲波檢測接收電路三部分組成。採用AT89C52來
實現對CX20106A紅外接收晶元和TCT40—10系列超
聲波轉換模塊的控制。單片機通過P1.0引腳經反相
\
超聲波接收E :, LED顯示單片機r
/\
Z ∑
超聲波發送高控制器
:> 掃描驅動
圖1 超聲波測距器系統設計框圖
Fig.1 Ultrasonic eLangi.g system design diagram
器來控制超聲波的發送,然後單片機不停的檢測INT0引腳,當INTO引腳的電平由高電平變為低電平時就
認為超聲波已經返回。計數器所計的數據就是超聲波所經歷的時間,通過換算就可以得到感測器與障礙
物之間的距離¨≈J。
3.2軟體部分
主要由主程序、超聲波發生子程序、超聲波接收中斷程序及顯示子程序等部分。
4系統硬體電路設計
4.1單片機系統及顯示電路
單片機採用AT89C52或其兼容系列。採用12MHz高精度的晶振,以獲得較穩定的時鍾頻率,減小測
量誤差。單片機用P1.0埠輸出超聲波轉化器所需的40KHz方波信號,利用外中斷0口檢測超聲波接收
電路輸出的返回信號。顯示電路採用簡單實用的4位共陽LED數碼管,段碼用74LS244驅動,位碼用PNP
三極體驅動。單片機系統及顯示電路如下圖2所示『1。31。
圖2單片機及顯示電路原理圖
Fig.2 MCU and display circuit schematics
第8期周功明等:基於AT89C52單片機的超聲波測距器設計·51.
4.2超聲波發射電路原理圖
壓電超聲波轉換器的功能:利用壓電晶體諧振工作。內部結構如圖3『3Ⅲ1所示,它有兩個壓電晶片和
一個共振板。當它的兩極外加脈沖信號,其頻
率等於壓電晶片的固有振盪頻率時,壓電晶片PI.O
將會發生共振,並帶動共振板振動產生超聲波,
這時它就是一超聲波發生器;如沒加電壓,當共
振板接收到超聲波時,將壓迫壓電振盪器作振
動,將機械能轉換為電信號,這時它就成為超聲
波接收轉換器。超聲波發射轉換器與接收轉換
器其結構稍有不同。
4.3超聲波檢測接收電路圖3發射電路原理圖
參考紅外轉化接收電路,本設計採用集成
F『g·3 U1『ms。nie劬啪mi『婦c『咖1『∞hem蚯c
電路CX20106A,這是一款紅外線檢波接收的專用晶元,常用於電視機紅外遙控接收器。考慮到紅外遙控
常用的載波頻率38KHz與測距超聲波頻率
40KHz較為接近,可以利用它作為超聲波檢測
電路。如圖4【3 J[71超聲波檢測接收電路原理圖
所示,適當改變C4的大小,可改變接收電路的
靈敏度和抗干擾能力。⋯. J。j-二
5系統程序設計
超聲波測距軟體設計主要由主程序,超聲
波發射子程序,超聲波接收中斷程序及顯示子
程序組成。下面對超聲波測距器的演算法,主程
序,超聲波發射子程序和超聲波接收中斷程序
逐一介紹。
5.1超聲波測距器的演算法設計
GND
圖4超聲波檢測接收電路原理圖
Fig.4 Ultrasonic receiver and detection circuit schematic
圖5【_列示意了超聲波測距的原理,即超聲
波發生器T在某一時刻發出的一個超聲波信號,當超聲波遇到被測物
體後反射回來,就被超聲波接收器R所接受。這樣只要計算出發生信
號到接收返回信號所用的時問,就可算出超聲波發生器與反射物體的
距離。
距離計算公式:d=s/2=(c木t)/2,其中d為被測物與測距器的距
離,s為聲波的來迴路程,c為聲速,t為聲波來回所用的時間。
圖5超聲波測距原理圖
Fig.5 Ultrasonic Ranging schematic
聲速c與溫度有關(見表1),如溫度變化不大,則可認為聲速是基
本不變的。如果測距精度要求很高,則應通過溫度補償的方法加以校正。聲速確定後,只要測得超聲波往
返時間,即可求得距離。在系統加入溫度感測器來監測環境溫度,可進行溫度補償。這里可以用DSl8820
測量環境溫度,根據不同的環境溫度確定一聲速提高測距的穩定性。為了增強系統的可靠性,可在軟硬體
上採用抗干擾措施。
表1不同溫度下的超聲波速表
Table I Under different temperatures ultrasonic velocity Table
·52· 綿陽師范學院學報(自然科學版) 第27卷
5.2主程序
主程序首先對系統環境初始化,設置定時器1D工作模式為16位的定時計數器模式,置位總中斷允許
位EA並給顯示端Po和P2清0。然後調用超聲波發生子程序送出一個超聲波脈沖,為避免超聲波從發射
器直接傳送到接收器引起的直接波觸發,需延遲0.1ms(這也就是測距器會有一個最小可測距離的原因)
後,才打開外中斷0接收返回的超聲波信號。由於採用12MHz的晶振,機器周期為lus,當主程序檢測到接
收成功的標志位後,將計數器喲中的數(即超聲波來回所用的時
間)按下式計算即可測得被測物體與測距儀之間的距離,設計時取
20℃時的聲速為344 m/s則有:d=(C木TO)/2=172T0/10000cm
(其中,ID為計數器,ID的計數值)。
測出距離後結果將以十進制BCD碼方式LED,然後再發超聲
波脈沖重復測量過程。主程序框圖如圖6所示。
5.3超聲波發生子程序和超聲波接收中斷程序
超聲波發生子程序的作用是通過PI.0埠發送2個左右的
超聲波信號頻率約40KHz的方波,脈沖寬度為12 US左右,同時把
計數器,ID打開進行計時。超聲波測距器主程序利用外中斷0檢
測返回超聲波信號,一旦接收到返回超聲波信號(INT0引腳出現
低電平),立即進入中斷程序。進入該中斷後就立即關閉計時器
,ID停止計時,並將測距成功標志字賦值l。如果當計時器溢出時
還未檢測到超聲波返回信號,則定時器rID溢出中斷將外中斷0關
閉,並將測距成功標志字賦值2以表示此次測距不成功H旬J。
5.4超聲波測距器的部分程序清單
/宰超聲波測距器彈片機c程序使用Keil C51 ver 7.09
。
木/
#include<re951.h>
#define uchar unsigned int
#define uint unsigned int
#define ulong unsigned long
Extem void ca_t(void);
Extem void delay(uint);
Extem void display(unchar);
Data unehar testtok;
/木超聲波測距器主程序術/
Void main(void)
{data unchar dispram[5];
data uint i;
data ulong time;
p0=0xff;
pl=0xff;
TMOD=0X11:
IE=0x80;
While(1)
{.「}
開始
系統初始化
發送超聲波脈沖
等待發射超聲波
計算距離
顯示結果0.5s
圖6主程序框圖
diagram of the main program
第8期周功明等:基於AT89C52單片機的超聲波測距器設計·53·
6軟硬體調試
超聲波測距儀的製作和調試,其中超聲波發射和接收採用中15的超聲波換能器TCT40一IOFl(T發
射)和TCT40—10S1(R接收),中心頻率為40kHz,安裝時應保持兩換能器中心軸線平行並相距4—8 cm,
其餘元件無特殊要求。若能將超聲波接收電路用金屬殼屏蔽起來,則可提高抗干擾能力。根據測量范圍
要求不同,可適當調整與接收換能器並接的濾波電容C4的大小,以獲得合適的接收靈敏度和抗干擾能力。
硬體電路製作完成並調試好後,便可將程序編譯好下載到單片機試運行。根據實際情況可以修改超
聲波發生子程序每次發送的脈沖寬度和兩次測量的間隔時間,以適應不同距離的測量需要∞】【71。
7 結束語
本文設計的是基於AT89C52單片機的超聲波測距器,可應用於汽車倒車等場合,提醒駕駛員倒車時有
效的避開可能對倒車造成危害的障礙物和行人,從而有效避免由於倒車造成的汽車碰撞或擦傷經濟損失
和人身安全問題。具有較強的實用性。
參考文獻:
[1] 周功明.基於AT89C2051彈片機的防盜自動報警電子密碼鎖系統設計[J].綿陽師范學院學報,2007,26(5):112—
116.
[14]
張齊.單片機應用系統設計技術一基於c語言編程[M].北京:電子工業出版社,2006.
李光飛.單片機c程序設計實例指導[M].北京:航空航天大學業出版社,2005.
樓燃苗,李光飛.51系列單片機設計實例[M].北京:航空航天大學業出版社,2003.
Zhongbo Li.Electronic Technique[M].Beijing:Mechannic Instrical Prees,2003.
賴麒文.8051單片機c語言徹底應用[M].北京:科學業出版社,2002.
何希才.感測器及其應用電路[M].北京:電子工業出版社,2001.
丁元傑.單片微機原理及應用[M].北京:機械工業出版社,2001.
孫串友,孫曉斌.感測技術基礎[M].北京:電子工業出版社,2001.
馬忠梅.單片機的c語言應用程序設計[M].北京:航空航天大學業出版社,1999.
劉喜昂,周志宇.基予多超聲感測器的機器人安全避障技術[J].測控技術,2003,23(2):71—73.
翟國富,劉茂愷.一種實時高精度的機器人用超聲波測距處理方法[J].應用聲學,1990,15(1):17—24.
Cray C,Swinhoe C F,Myinl.Target controlled infusion of ketamine曲analgessia for TIV A with propof01.Can.J Anesth,1999,
40:957.
R J Higgens.Electronics and Analog Integrated Circuits[M].N.J:Prentice—Hall Inc,2001.
④ 51單片機超聲波測距代碼是多少
1602液晶顯示 的超聲波模塊程序
介面程序里邊都有、、
#include<reg52.h>
//#include<delay.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs=P2^3;
sbit lcden=P2^2;
sbit trig=P2^0; //超聲波發送
//sbit echo=P3^2; //超聲波接受
//P0____________DB0-DB7
uchar dis[]="Disp_HC-SR04";
uchar num[]="0123456789";
uint distance;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=121;y>0;y--);
}
void HC_init()
{
TMOD=0x09;
TR0=1;
TH0=0;TL0=0;
}
uint HC_jisuan()
{
uint dist,timer;
timer=TH0;
timer<<=8;
timer=timer|TL0;
dist=timer/53; //晶振11.0592MHz 距離cm=微秒us/58
return dist; //1個機器周期是12個時鍾周期 timer*12/(58*11.0592)=timer/53
}
void HC_run()
{
uint tempH=0x00,tempL=0x00;
TH0=0;TL0=0;
trig=0;
trig=1;
delay(1);
trig=0;
while((TH0-tempH!=0||TL0-tempL!=0)||(TH0==0&&TL0==0))
{
tempH=TH0;
tempL=TL0;
}
delay(1);
}
void lcd_write_com(uchar com) //LCD寫指令
{
lcdrs=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_write_data(uchar date) //LCD寫數據
{
lcdrs=1;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_init() //LCD初始化
{
lcden=0;
lcd_write_com(0x38);
lcd_write_com(0x0c);
lcd_write_com(0x06);
lcd_write_com(0x01);
}
void lcd_display(uchar temp)
{
uint i;
lcd_write_com(0x82);
for(i=0;i<12;i++)
{
lcd_write_data(dis[i]);
}
lcd_write_com(0x80+0x41);
lcd_write_data('D');
lcd_write_data('i');
lcd_write_data('s');
lcd_write_data('t');
lcd_write_data('a');
lcd_write_data('n');
lcd_write_data('c');
lcd_write_data('e');
lcd_write_data(':');
lcd_write_data(num[temp/100]);
lcd_write_data(num[temp/10%10]);
lcd_write_data(num[temp%10]);
lcd_write_data('c');
lcd_write_data('m');
}
void main()
{
lcd_init();
HC_init();
while(1)
{
HC_run();
distance=HC_jisuan();
lcd_display(distance);
delay(200);
}
}
⑤ 請大俠幫忙編一下程 超聲波測距的
我做過和你一樣的電路的超聲波測距
下面是成功的代碼
#include <reg52.h> //包括一個52標准內核的頭文件
#include<intrins.h> //包含_nop_()函數定義的頭文件
#define uchar unsigned char //定義一下方便使用
#define uint unsigned int
#define ulong unsigned long
sbit Tx = P3^3; //產生脈沖引腳
sbit Rx = P3^2; //回波引腳
sbit RS=P2^0; //寄存器選擇位,將RS位定義為P2.0引腳
sbit RW=P2^1; //讀寫選擇位,將RW位定義為P2.1引腳
sbit E=P2^2; //使能信號位,將E位定義為P2.2引腳
sbit BF=P0^7; //忙碌標志位,,將BF位定義為P0.7引腳
unsigned char code string[ ]= {"CHAO SHENG BO"};
//unsigned char code string1[ ]={"QUICK STUDY MCU"};
unsigned char code digit[ ]={"0123456789"}; //定義字元數組顯示數字
//uchar code SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//數碼管0-9
uint distance[4]; //測距接收緩沖區
uchar kk,ww,ge,shi,,temp,flag,outcomeH,outcomeL,i; //自定義寄存器
bit succeed_flag; //測量成功標志
//********函數聲明
void conversion(uint temp_data);
void delay_20us();
void pai_xu();
/*****************************************************
函數功能:延時1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以認為是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函數功能:延時若干毫秒
入口參數:n
***************************************************/
void delay(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/*****************************************************
函數功能:判斷液晶模塊的忙碌狀態
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
unsigned char BusyTest(void)
{
bit result;
RS=0; //根據規定,RS為低電平,RW為高電平時,可以讀狀態
RW=1;
E=1; //E=1,才允許讀寫
_nop_(); //空操作
_nop_();
_nop_();
_nop_(); //空操作四個機器周期,給硬體反應時間
result=BF; //將忙碌標志電平賦給result
E=0; //將E恢復低電平
return result;
}
/*****************************************************
函數功能:將模式設置指令或顯示地址寫入液晶模塊
入口參數:dictate
***************************************************/
void WriteInstruction (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //根據規定,RS和R/W同時為低電平時,可以寫入指令
RW=0;
E=0; //E置低電平(根據表8-6,寫指令時,E為高脈沖,
// 就是讓E從0到1發生正跳變,所以應先置"0"
_nop_();
_nop_(); //空操作兩個機器周期,給硬體反應時間
P0=dictate; //將數據送入P0口,即寫入指令或地址
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個機器周期,給硬體反應時間
E=1; //E置高電平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個機器周期,給硬體反應時間
E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****************************************************
函數功能:指定字元顯示的實際地址
入口參數:x
***************************************************/
void WriteAddress(unsigned char x)
{
WriteInstruction(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
}
/*****************************************************
函數功能:將數據(字元的標准ASCII碼)寫入液晶模塊
入口參數:y(為字元常量)
***************************************************/
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS為高電平,RW為低電平時,可以寫入數據
RW=0;
E=0; //E置低電平(根據表8-6,寫指令時,E為高脈沖,
// 就是讓E從0到1發生正跳變,所以應先置"0"
P0=y; //將數據送入P0口,即將數據寫入液晶模塊
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個機器周期,給硬體反應時間
E=1; //E置高電平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個機器周期,給硬體反應時間
E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****************************************************
函數功能:對LCD的顯示模式進行初始化設置
***************************************************/
void LcdInitiate(void)
{
delay(15); //延時15ms,首次寫指令時應給LCD一段較長的反應時間
WriteInstruction(0x38); //顯示模式設置:16×2顯示,5×7點陣,8位數據介面
delay(5); //延時5ms ,給硬體一點反應時間
WriteInstruction(0x38);
delay(5);
WriteInstruction(0x38); //連續三次,確保初始化成功
delay(5);
WriteInstruction(0x0c); //顯示模式設置:顯示開,無游標,游標不閃爍
delay(5);
WriteInstruction(0x06); //顯示模式設置:游標右移,字元不移
delay(5);
WriteInstruction(0x01); //清屏幕指令,將以前的顯示內容清除
delay(5);
}
void main(void) // 主程序
{ uint distance_data,a,b;
uchar CONT_1;
uchar k; //定義變數i指向字元串數組元素
LcdInitiate(); //調用LCD初始化函數
delay(10); //延時10ms,給硬體一點反應時間
WriteAddress(0x01); // 從第1行第3列開始顯示
k = 0; //指向字元數組的第1個元素
while(string[k] != '\0')
{
WriteData(string[k]);
k++; //指向下字元數組一個元素
}
i=0;
flag=0;
Tx=0; //首先拉低脈沖輸入引腳
TMOD=0x10; //定時器0,定時器1,16位工作方式
// TR0=1; //啟動定時器0
IT0=0; //由高電平變低電平,觸發外部中斷
//ET0=1; //打開定時器0中斷
EX0=0; //關閉外部中斷
EA=1; //打開總中斷0
while(1) //程序循環
{
WriteAddress(0x41); // 從第2行第6列開始顯示
WriteData('J'); //將萬位數字的字元常量寫入LCD
WriteData('U'); //將萬位數字的字元常量寫入LCD
WriteData('L'); //將萬位數字的字元常量寫入LCD
WriteData('I'); //將萬位數字的字元常量寫入LCD
WriteData(':'); //將萬位數字的字元常量寫入LCD
WriteData(digit[ww]); //將萬位數字的字元常量寫入LCD
WriteData(digit[kk]); //將萬位數字的字元常量寫入LCD
WriteData(digit[]); //將萬位數字的字元常量寫入LCD
WriteData(digit[shi]); //將千位數字的字元常量寫入LCD
WriteData('.'); //將萬位數字的字元常量寫入LCD
WriteData(digit[ge]); //將百位數字的字元常量寫入LCD
WriteData(' '); //將百位數字的字元常量寫入LCD
WriteData('C'); //將萬位數字的字元常量寫入LCD
WriteData('M'); //將萬位數字的字元常量寫入LCD
EA=0;
Tx=1;
delay_20us();
Tx=0; //產生一個20us的脈沖,在Tx引腳
while(Rx==0); //等待Rx回波引腳變高電平
succeed_flag=0; //清測量成功標志
EX0=1; //打開外部中斷
TH1=0; //定時器1清零
TL1=0; //定時器1清零
TF1=0; //
TR1=1; //啟動定時器1
EA=1;
while(TH1 < 250);//等待測量的結果,周期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; //沒有回波則清零
}
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;
}
//顯示數據轉換程序
void conversion(uint temp_data)
{
uchar ge_data,shi_data,_data,k_data,w_data ;
w_data=temp_data/10000 ;
temp_data=temp_data%10000; //取余運算
k_data=temp_data/1000 ;
temp_data=temp_data%1000; //取余運算
_data=temp_data/100 ;
temp_data=temp_data%100; //取余運算
shi_data=temp_data/10 ;
temp_data=temp_data%10; //取余運算
ge_data=temp_data;
//_data=SEG7[_data];
//shi_data=SEG7[shi_data]&0x7f;
//ge_data =SEG7[ge_data];
EA=0;
kk=k_data;
ww=w_data;
= _data;
shi = shi_data;
ge = ge_data ;
EA=1;
}
//******************************************************************
void delay_20us()
{ uchar bt ;
for(bt=0;bt<60;bt++);
}
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;}
}
⑥ 51單片機超聲波測距代碼
1602液晶顯示 的超聲波模塊程序
介面程序里邊都有、、
#include
//#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs=P2^3;
sbit lcden=P2^2;
sbit trig=P2^0; //超聲波發送
//sbit echo=P3^2; //超聲波接受
//P0____________DB0-DB7
uchar dis[]="Disp_HC-SR04";
uchar num[]="0123456789";
uint distance;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=121;y>0;y--);
}
void HC_init()
{
TMOD=0x09;
TR0=1;
TH0=0;TL0=0;
}
uint HC_jisuan()
{
uint dist,timer;
timer=TH0;
timer<<=8;
timer=timer|TL0;
dist=timer/53; //晶振11.0592MHz 距離cm=微秒us/58
return dist; //1個機器周期是12個時鍾周期 timer*12/(58*11.0592)=timer/53
}
void HC_run()
{
uint tempH=0x00,tempL=0x00;
TH0=0;TL0=0;
trig=0;
trig=1;
delay(1);
trig=0;
while((TH0-tempH!=0||TL0-tempL!=0)||(TH0==0&&TL0==0))
{
tempH=TH0;
tempL=TL0;
}
delay(1);
}
void lcd_write_com(uchar com) //LCD寫指令
{
lcdrs=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_write_data(uchar date) //LCD寫數據
{
lcdrs=1;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_init() //LCD初始化
{
lcden=0;
lcd_write_com(0x38);
lcd_write_com(0x0c);
lcd_write_com(0x06);
lcd_write_com(0x01);
}
void lcd_display(uchar temp)
{
uint i;
lcd_write_com(0x82);
for(i=0;i<12;i++)
{
lcd_write_data(dis[i]);
}
lcd_write_com(0x80+0x41);
lcd_write_data('D');
lcd_write_data('i');
lcd_write_data('s');
lcd_write_data('t');
lcd_write_data('a');
lcd_write_data('n');
lcd_write_data('c');
lcd_write_data('e');
lcd_write_data(':');
lcd_write_data(num[temp/100]);
lcd_write_data(num[temp/10%10]);
lcd_write_data(num[temp%10]);
lcd_write_data('c');
lcd_write_data('m');
}
void main()
{
lcd_init();
HC_init();
while(1)
{
HC_run();
distance=HC_jisuan();
lcd_display(distance);
delay(200);
}
}