A. 51單片機如何控制超聲波感測器 求C語言程序(一定要能用)100追加
//超聲波模塊ME007顯示程序
//晶振=8M
//MCU=STC10F04XE
//P0.0-P0.6共陽數碼管引腳
//Trig = P1^0
//Echo = P3^2
#include <reg52.h> //包括一個52標准內核的頭文件
#define uchar unsigned char //定義一下方便使用
#define uint unsigned int
#define ulong unsigned long
//***********************************************
sfr CLK_DIV = 0x97; //為STC單片機定義,系統時鍾分頻
//為STC單片機的IO口設置地址定義
sfr P0M1 = 0X93;
sfr P0M0 = 0X94;
sfr P1M1 = 0X91;
sfr P1M0 = 0X92;
sfr P2M1 = 0X95;
sfr P2M0 = 0X96;
//***********************************************
sbit Trig = P1^0; //產生脈沖引腳
sbit Echo = P3^2; //回波引腳
sbit test = P1^1; //測試用引腳
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;
CLK_DIV=0X03; //系統時鍾為1/8晶振(pdf-45頁)
P0M1 = 0; //將io口設置為推挽輸出
P1M1 = 0;
P2M1 = 0;
P0M0 = 0XFF;
P1M0 = 0XFF;
P2M0 = 0XFF;
i=0;
flag=0;
test =0;
Trig=0; //首先拉低脈沖輸入引腳
TMOD=0x11; //定時器0,定時器1,16位工作方式
TR0=1; //啟動定時器0
IT0=0; //由高電平變低電平,觸發外部中斷
ET0=1; //打開定時器0中斷
//ET1=1; //打開定時器1中斷
EX0=0; //關閉外部中斷
EA=1; //打開總中斷0
while(1) //程序循環
{
EA=0;
Trig=1;
delay_20us();
Trig=0; //產生一個20us的脈沖,在Trig引腳
while(Echo==0); //等待Echo回波引腳變高電平
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; //沒有回波則清零
test = !test; //測試燈變化
}
/// 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=0xfd;flag++;break;
case 0x01:P0=shi;P2=0xfe;flag++;break;
case 0x02:P0=;P2=0xfb;flag=0;break;
}
}
//*****************************************************************
/*
//定時器1中斷,用做超聲波測距計時
timer1() interrupt 3 // 定時器0中斷是1號
{
TH1=0;
TL1=0;
}
*/
//******************************************************************
//顯示數據轉換程序
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];
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<100;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;} /*交換值
}
*/
我的一個超聲波程序
有問題,請問~~
//超聲波模塊顯示程序
#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 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[]); //將萬位數字的字元常量寫入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 < 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;
}
//顯示數據轉換程序
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;}
}
第一個需要修改,你還是試試這個吧!這個你先理解下,修改引腳……顯示為1602
B. 單片機超聲波測距系統原理
超聲波測距學習板,可應用於汽車倒車、建築施工工地以及一些工業現場的位置監控,也可用於如液位、井深、管道長度的測量等場合。要求測量范圍在0.27~4.00m,測量精度1cm,測量時與被測物體無直接接觸,能夠清晰穩定地顯示測量結果。超聲波測距原理
超聲波發生器內部結構有兩個壓電晶片和一個共振板。當它的兩極外加脈沖信號,其頻率等於壓電晶片的固有振盪頻時,壓電晶片將會發生共振,並帶動共振板振動,便產生超聲波。反之,如果兩電極間未外加電壓,當共振板接收到超聲波本時,將壓迫壓電晶片作振動,將機械能轉換為電信號,就成為超聲波接收器。在超聲探測電路中,發射端得到輸出脈沖為一系列方波,其寬度為發射超聲的時間間隔,被測物距離越大,脈沖寬度越大,輸出脈沖個數與被測距離成正比。超聲測距大致有以下方法:① 取輸出脈沖的平均值電壓,該電壓 (其幅值基本固定 )與距離成正比,測量電壓即可測得距離;② 測量輸出脈沖的寬度,即發射超聲波與接收超聲波的時間間隔 t,故被測距離為 S=1/2vt。本測量電路採用第二種方案。由於超 聲波 的聲速 與溫度有關,如果溫度變化不大,則可認為聲速基本不變 。如果測距精度要求很高,則應通 過溫度補償 的方法加以校正。超聲波測距適用於高精度的中長距離測量。因為超聲波在標准空氣中的傳播速度為331.45米/秒,由單片機負責計時,單片機使用12.0M晶振,所以此系統的測量精度理論上可以達到毫米級。
採用AT89C51或AT89S51單片機,晶振:12M,單片機用P1.0口輸出超聲波換能器所需的40K方波信號,利用外中斷0口監測超聲波接收電路輸出的返回信號,顯示電路採用簡單的4位共陽LED數碼管,斷碼用74LS244,位碼用8550驅動.
超聲波測距的演算法設計: 超聲波在空氣中傳播速度為每秒鍾340米(15℃時)。X2是聲波返回的時刻,X1是聲波發聲的時刻,X2-X1得出的是一個時間差的絕對值,假定X2-X1=0.03S,則有340m×0.03S=10.2m。由於在這10.2m的時間里,超聲波發出到遇到返射物返回的距離。
硬體部分採用AT89C51或AT89S51單片機,晶振:12M,單片機用P1.0口輸出超聲波換能器所需的40K方波信號,利用外中斷0口監測超聲波接收電路輸出的返回信號,顯示電路採用簡單的4位共陽LED數碼管,斷碼用74LS244,位碼用8550驅動. 主要由單片機系統及顯示電路、超聲波發射電路和超聲波檢測接收電路三部分組成。採用AT89S51來實現對CX20106A紅外接收晶元和TCT40-10系列超聲波轉換模塊的控制。單片機通過P1.0引腳經反相器來控制超聲波的發送,然後單片機不停的檢測INT0引腳,當INT0引腳的電平由高電平變為低電平時就認為超聲波已經返回。計數器所計的數據就是超聲波所經歷的時間,通過換算就可以得到感測器與障礙物之間的距離。
1.單片機系統及顯示電路
單片機採用89S51或其兼容系列。採用12MHz高精度的晶振,以獲得較穩定的時鍾頻率,減小測量誤差。
單片機用P1.0埠輸出超聲波轉化器所需的40KHz方波信號,利用外中斷0口檢測超聲波接受電路輸出的返回信號。顯示電路採用簡單實用的4位共陽LED數碼管,段碼用74LS244驅動,位碼用PNP三極體驅動。單片機系統及顯示電路如下圖所示.
使用CX20106A集成電路對接收探頭受到的信號進行放大、濾波。其總放大增益80db。以下是CX20106A的引腳注釋。
1腳:超聲信號輸入端,該腳的輸入阻抗約為40kΩ。
2腳:該腳與地之間連接RC串聯網路,它們是負反饋串聯網路的一個組成部分,改變它們的數值能改變前置放大器的增益和頻率特性。增大電阻R1或減小C1,將使負反饋量增大,放大倍數下降,反之則放大倍數增大。但C1的改變會影響到頻率特性,一般在實際使用中不必改動,推薦選用參數為R1=4.7Ω,C1=1μF。
3腳:該腳與地之間連接檢波電容,電容量大為平均值檢波,瞬間相應靈敏度低;若容量小,則為峰值檢波,瞬間相應靈敏度高,但檢波輸出的脈沖寬度變動大,易造成誤動作,推薦參數為3.3μf。
4腳:接地端。
5腳:該腳與電源間接入一個電阻,用以設置帶通濾波器的中心頻率f0,阻值越大,中心頻率越低。例如,取R=200kΩ時,f0≈42kHz,若取R=220kΩ,則中心頻率f0≈38kHz。
6腳: 該腳與地之間接一個積分電容,標准值為330pF,如果該電容取得太大,會使探測距離變短。
7腳:遙控命令輸出端,它是集電極開路輸出方式,因此該引腳必須接上一個上拉電阻到電源端,推薦阻值為22kΩ,沒有接受信號是該端輸出為高電平,有信號時則產生下降。 8腳:電源正極,4.5~5V。
軟硬體調試及性能
超聲波測距儀的製作和調試,其中超聲波發射和接收採用Φ16的超聲波換能器TCT40-16F1(T發射)和TCT40-16S1(R接收),中心頻率為40kHz,安裝時應保持兩換能器中心軸線平行並相距4~8cm,其餘元件無特殊要求。若能將超聲波接收電路用金屬殼屏蔽起來,則可提高抗干擾能力。根據測量范圍要求不同,可適當調整與接收換能器並接的濾波電容C4的大小,以獲得合適的接收靈敏度和抗干擾能力。
硬體電路製作完成並調試好後,便可將程序編譯好下載到單片機試運行。根據實際情況可以修改超聲波發生子程序每次發送的脈沖寬度和兩次測量的間隔時間,以適應不同距離的測量需要。根據所設計的電路參數和程序,測距儀能測的范圍為0.07~5.5m,測距儀最大誤差不超過1cm。系統調試完後應對測量誤差和重復一致性進行多次實驗分析,不斷優化系統使其達到實際使用的測量要求。後續工作需實驗後才能驗證 根據參考電路和集成的電路器件測距范圍有限10m以內為好。
C. 您好,如果想用單片機驅動超聲波感測器,驅動電路選擇什麼好
用單片機驅動一個開關管。
在初級階段,建議用NPN達林頓三極體,例如TIP142之類,電路比較簡單:在NPN達林頓管的集電極與電源之間,接一個脈沖變壓器(初級)。脈沖變壓器的次級接超聲波的發射頭。用於驅動的電源電壓不要太高,也盡量別用5V的單片機電源,建議用5V-12V的獨立電源供電,與單片機共地。
以上實驗成功以後,還需要進一步增加一些原件,用來提高電路的穩定性、可靠性,並減少餘震,當然那是後話了,一步一步來吧。
D. 51單片機控制超聲波測距,大家看看我的程序為什麼不對,詳細注釋
你好:
這時我用51單片機寫的HC_SR04超聲波測距程序。
其實很簡單的,程序一目瞭然。
希望我的回答能幫助到你。
很抱歉,回答者上傳的附件已失效
E. CD4049為什麼能把單片機輸出方波的電壓放大並且產生諧振來驅動超聲波感測器
CD4049,六反相器。
單片機輸出信號先經過一個反相器,分兩路,一路過一級反相到超聲波超感器1腳,另一路兩級反相到2腳。單片機輸出高電平時,1腳高電平2腳低電平,反之2高1低。無論單片機輸出電平高低,發射器兩端都將產生電壓,只是電壓方向不同而已。所以單片輸出方波,在超聲波發射器兩端就產生了交流電壓。
F. 一個單片機同時控制三個超聲波測距模塊,程序怎樣實現呢
只不過是單片機上接了三個模塊,是不可能同時控制的,寫程序時,分別對三個模塊進行測量,因單片機的速度是非常快的,從外觀上看就好像是同時測量的,可程序是不可能同時執行的,只是互相間隔的時間極短,表面上就同時了。確切說,從微觀上是分時控制,從宏觀上看是同時了。
G. 單片機如何接收超聲波感測器的信號
單片機和超聲換能器之間,應該是有發射電路和小信號放大電路。單片機控制發射電路發射,小信號放大電路接收到超聲換能器的信號,進行放大後接入單片機。至於要怎麼採集,採集的時間,要看你具體要實現的功能。