❶ 用51單片機實現超聲波測距怎樣才可以測到4m
輸出用並聯門電路驅動,如CD4069,以增大輸出電流。
接收採用低雜訊運放,如NE5532,放大1000倍。
採用接收,發射分開的探頭
超聲波測距系統的軟體設計,由於超聲發射感測器與超聲接收感測器相隔很近,當發射超聲波時,接收感測器會收到很強的干擾信號。為防止系統的誤測,在軟體上採用延遲接收技術,來提高系統的抗干擾能力。一旦按下起始鍵,即發送發射超聲波的指令,同時單片機控制系統開始執行程序,完成對溫度的采樣、濾波,然後獲得發送、接收超聲波的時間間隔,最後計算出距離值。
(1) 接收放大電路,可加入帶通濾波或鎖相放大(LM567)以盡可能減少干擾信號引起誤觸發,另外為防止發射信號直接進入接收端所以設置一定的延時。鎖相應用電路,調整在40KHZ上,但要考慮加入後對接收處理的延時,用軟體調整。
另一方面可採用自動增益補償技術,隨著時間的增加, AGC的放大倍數呈指數規律變化,從而保證了超聲波接收器波形的幅值不隨測量距離的變化而大幅變化,使得每次在同一個波頭觸發計時電路,提高了系統測量准確度。電路可以採用如下圖所示或者採用單片AD603實現,在這里不具體討論。
(2)發射驅動電路,為放大驅動脈沖可以再加入一級三極體放大電路,三極體要選用高頻的如9018以減少放大後波形的失真;另一方面還可以根據超聲波發生器的特點合理設計阻抗匹配,功放效率和機電轉換效率;為此可採用脈沖變壓器,脈沖變壓器是超聲換能器驅動電路中最重要的器件,它的用途是升高脈沖電壓信號,並使功率放大器的輸出阻抗與換能器的負載阻抗匹配。一般脈沖變壓器以變壓器的功率、原副邊電壓信號的幅值確定變壓器的尺寸和變比;而超聲換能器驅動用變壓器則主要以功率和原副邊電感及阻抗匹配確定變壓器的尺寸和變比。缺點是製作和測量都比較麻煩。在大量程應用場合還可以應用電容瞬間放電或電感瞬間放電產生高壓激勵脈沖。
(3)其它可改善的地方,可採用超聲波測距專用晶元SB5027;也可以採用LM1812N單片超聲波收發集成電路。
❷ 基於51單片機的紅外測距
1、單片機 紅外發射管 紅外接收管 + 邏輯演算法
2、一般情況下,常見的管子,就是類似於發光二極體的樣子,接收的距離很近,你自己搭電路的話要考慮排除干擾,信號放大,也許50元,也解決不了。還有一種是3隻腳的,這種接收方面好一點,價格也不是很貴,大概5元。還有更好的器件,配對使用,檢出有效距離300mm,大概是20-30元,具體看你想怎麼用了,項目是怎麼規定的了
3、利用波速來計算距離,測量出幾個納秒的時間差,使用單片機則是不可能的。
4、利用電磁波來測距、測速,是利用了變頻、差頻的原理,前端的電路和器件,都是使用模擬電路中高頻電子線路的理論和電路器件。
5、單片機之類的數字電路根本跟不上這個速度,只能做後期的低速工作,如顯示報警等。
6、其實,用單片機做搶答器,也是蒙人的,誤差的概率也是極大的。
❸ 51單片機可不可以一起實現顯示時間和超聲波測距兩個功能(用1602顯示)
當然可以呀,不過這個程序會很麻煩,因為你的時間顯示刷新1602應該是每秒一次的,這個一個定時器就能實現,剩下的超聲波測距用另一個定時器就能實現的,其實最好的實現頒發並不是這樣的,加一個DS1302或者是DS12C887這樣你的單片機只要潛心的去處理測距就行了,時間久有一個晶元替你去搞定,年月日時分秒星期都能顯示,有電池斷電不對丟失數據,最方便的是DS12C887隻是有點貴
❹ 51單片機 HC-SR04超聲波測距 我寫的C語言代碼,請問
1、HC-SR04使用方法:給觸發端子trig一個10us以上的高電平即可觸發,觸發後echo端子將接受到高電平,高電平的持續時間就是測距的往返時間。
2、常式:
#include<reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
/*位定義*/
sbitCHUFA=P0^1;//位定義超聲波觸發端(10us以上高電平觸發)
sbitJIESHOU=P0^3;//接收端(接受高電平)
sbitBEEP=P2^0;//蜂鳴器
sbitOUT0=P3^2;//外部中斷0
ucharJS_FLAG;//接收標志
uintCF_TIME,t0,t1,shu;
/*函數聲明*/
voidtimer0();
voidint0();
voiddisplay(uint);
main(){
CHUFA=0;//初始化拉低觸發端和接收端電平
JIESHOU=0;
JS_FLAG=0;
CF_TIME=15;//初始化觸發時間(大於10us)
TMOD=0x11;//定時器方式選擇
EA=1;//開總中斷
ET0=1;//開定時器0中斷
EX0=1;//開外部中斷0
IT0=0;//外部中斷選擇下降沿觸發
//JIESHOU=1;
while(1){
OUT0=JIESHOU;//外部中斷0被賦值為接收端信號,當出現下降沿是觸發外部中斷0
if(JS_FLAG==0){//如果沒有接收到高電平則觸發
CHUFA=1;
while(CF_TIME--);//10us以上高電平觸發感測器
}
if(JIESHOU==1){
TR0=1;//如果接收端收到高電平則啟動定時器
JS_FLAG=1;//並且標志位置1
BEEP=0;//蜂鳴器響
}
display(t1);//顯示測量時間(秒)
}
}
/*定時器0中斷程序*/
voidtimer0()interrupt1{
TH0=(65536-10000)/256;//裝初值10ms
TL0=(65536-10000)%256;
t0++;//每進入一次中斷t0加1
}
/*外部中斷0中斷程序*/
voidint0()interrupt0{
TR0=0;//一旦進入外部中斷0,說明接收端收到下降沿信號。關閉定時器0
JS_FLAG=0;//接收標志位置0
BEEP=1;//關閉蜂鳴器
t1=t0*10/1000;//測量時間為進入定時器中斷次數t0乘以每次時間10ms,除以1000化為秒為單位
t0=0;//t0清零
}
/*數碼管顯數函數*/
voiddisplay(uintshu){
//數碼管顯示函數
}
❺ 51單片機超聲測距中,公式:uS/58=厘米或者 uS/148=英寸是怎麼得來的,為什麼US/58就是厘米
因為通常音速是340m/s,測距的話就是L=340m/s*T/2=T*170m/s=T*1s/170m=T*58uS/cm
❻ 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);
}
}
❼ 51單片機超聲波測距最遠距離是多少
51單片機超聲波測距最遠距離是30m。
提高超聲波測試距離的辦法有三種:
1、降低超聲波的頻率;
2、加大超聲波發射功率;
3、提高超聲波接收的靈敏度,提高放大電路的增益;如果用的是模塊,要注意它的技術文檔。
51單片機的優點:
51單片機之所以成為經典,成為易上手的單片機主要有以下特點:從內部的硬體到軟體有一套完整的按位操作系統,稱作位處理器,處理對象不是字或位元組而是位。不但能對片內某些特殊功能寄存器的某位進行處理,如傳送、置位、清零、測試等,還能進行位的邏輯運算,其功能十分完備,使用起來得心應手。
❽ 51單片機控制的超聲波測距儀程序
希望對你有幫助
//超聲波模塊顯示程序
#include <reg52.h> //包括一個52標准內核的頭文件
#define uchar unsigned char //定義一下方便使用
#define uint unsigned int
#define ulong unsigned long
sbit Tx = P3^3; //產生脈沖引腳
sbit Rx = P3^2; //回波引腳
uchar code SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//數碼管0-9
uint distance[4]; //測距接收緩沖區
uchar ge,shi,,temp,flag,outcomeH,outcomeL,i; //自定義寄存器
bit succeed_flag; //測量成功標志
//********函數聲明
void conversion(uint temp_data);
void delay_20us();
void pai_xu();
void main(void) // 主程序
{ uint distance_data,a,b;
uchar CONT_1;
i=0;
flag=0;
Tx=0; //首先拉低脈沖輸入引腳
TMOD=0x11; //定時器0,定時器1,16位工作方式
TR0=1; //啟動定時器0
IT0=0; //由高電平變低電平,觸發外部中斷
ET0=1; //打開定時器0中斷
EX0=0; //關閉外部中斷
EA=1; //打開總中斷0
while(1) //程序循環
{
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 < 30);//等待測量的結果,周期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;
switch(flag)
{case 0x00:P0=ge; P2=0x7f;flag++;break;
case 0x01:P0=shi;P2=0xbf;flag++;break;
case 0x02:P0=;P2=0xdf;flag=0;break;
}
}
//顯示數據轉換程序
void conversion(uint temp_data)
{
uchar ge_data,shi_data,_data ;
_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;
= _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;}
}