導航:首頁 > 操作系統 > 超聲示教儀單片機控制系統

超聲示教儀單片機控制系統

發布時間:2022-07-26 08:24:34

① 求一段匯編程序,利用51單片機控制超聲波感測器測距的程序。

; 基於AT89C2051單片機超聲波測距系統
; 測量范圍35-300厘米
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 中斷入口程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG 0000H
AJMP START
ORG 000BH
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 主 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START : MOV R0,#70H ;立即數70H送寄存器R0中
MOV R7,#0BH ;立即數0BH送寄存器R7中
MOV 20H,#00H ;立即數00H送20H單元中
CLEARDISP: MOV @R0,#00H ;立即數立即數00H送R0中的地址單元中
INC R0 ;寄存器R0加1
DJNZ R7,CLEARDISP;寄存器中的數值減1非零時轉移
MOV TMOD,#01H ;置定時器T0工作方式樣3,對內部機器周期計數
CJZCX:MOV TL0,#00H ;裝入定時器初值
MOV TH0,#00H
MOV R0,#0FH
MOV R1,#5bH
puzel:MOV 14H,#08H ;超聲波發射持續200us
Here:CPL P3.5 ;輸出40kHz方波
NOP ;
NOP ;
NOP ;
DJNZ 14H,Here ;
SETB TR0
SETB P3.2
MOV R6,#53H ;延時1.5ms
DL0: MOV R5,#03H
DJNZ R5,$
DJNZ R6,DL0
QBA:JNB P3.7,QBC
DJNZ R1,QBA
DJNZ R0,QBA
QBC:CLR P3.2
CLR TR0
MOV 70H,tl0
MOV 71H,tH0
MOV R2,71H
MOV R3,70H
MOV R6,#22H
MOV R7,#0H
LCALL MULD
MOV R6,#64H
MOV R7,#0H
LCALL DIVD
MOV 73H,R2
MOV 74H,R3
MOV R3,#0H
MOV R4,#0H
MOV R5,#0H
MOV R6,73H
MOV R7,74H
LCALL HB2
MOV A,R4 ;分離BCD
MOV B,#10H
DIV AB
MOV 78H,A
MOV 77H,B
MOV A,R5
MOV B,#10H
DIV AB
MOV 76H,A
MOV 75H,B
MOV 7AH,#0EFH
XXX:LCALL DISPLAY
DJNZ 7AH,XXX
AJMP CJZCX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 乘34程序(乘聲速) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MULD: MOV A,R3 ;計算R3乘R7
MOV B,R7
MUL AB
MOV R4,B ;暫存部分積
MOV R5,A
MOV A,R3 ;計算R3乘R6
MOV B,R6
MUL AB
ADD A,R4 ;累加部分積
MOV R4,A
CLR A
ADDC A,B
MOV R3,A
MOV A,R2 ;計算R2乘R7
MOV B,R7
MUL AB
ADD A,R4 ;累加部分積
MOV R4,A
MOV A,R3
ADDC A,B
MOV R3,A
CLR A
RLC A
XCH A,R2 ;計算R2乘R6
MOV B,R6
MUL AB
ADD A,R3 ;累加部分積
MOV R3,A
MOV A,R2
ADDC A,B
MOV R2,A
RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 除100程序(除法) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DIVD: CLR C ;比較被除數和除數
MOV A,R3
SUBB A,R7
MOV A,R2
SUBB A,R6
JC DVD1
SETB OV ;溢出
RET
DVD1: MOV B,#10H ;計算雙位元組商
DVD2: CLR C ;部分商和余數同時左移一位
MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
XCH A,R2
RLC A
XCH A,R2
MOV F0,C ;保存溢出位
CLR C
SUBB A,R7 ;計算(R2R3-R6R7)
MOV R1,A
MOV A,R2
SUBB A,R6
ANL C,/F0 ;結果判斷
JC DVD3
MOV R2,A ;夠減,存放新的余數
MOV A,R1
MOV R3,A
INC R5 ;商的低位置一
DVD3: DJNZ B,DVD2 ;計算完十六位商(R4R5)
MOV A,R4 ;將商移到R2R3中
MOV R2,A
MOV A,R5
MOV R3,A
CLR OV ;設立成功標志
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; BCD轉換 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HB2: CLR A ;BCD碼初始化
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#10H ;轉換雙位元組十六進制整數
HB3: MOV A,R7 ;從高端移出待轉換數的一位到CY中
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R5 ;BCD碼帶進位自身相加,相當於乘2
ADDC A,R5
DA A ;十進制調整
MOV R5,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R3
ADDC A,R3
MOV R3,A ;雙位元組十六進制數的萬位數不超過6,不用調整
DJNZ R2,HB3 ;處理完16bit
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 顯示程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY: MOV R1,#76H ;立即數76H送寄存器中
MOV R5,#0FEH ;立即數FEH送寄存器R5中
PLAY: MOV A,R5 ;寄存器R5中的數值送累加器A中
MOV P3,A ;累加器A中的數值送P3口
MOV A,@R1 ;以寄存器R1中的數為地址單元的數值送累加器中
MOV DPTR,#TAB ;16位地址送地址寄存器中
MOVC A,@A+DPTR ;以中的地址為基地變址定址單元中的數送累加器
MOV P1,A ;累加器A中的數值送P1口
MOV R6,#14H ;立即數據14送寄存器R6中
DL1:MOV R7,#19H ;立即數據19送寄存器R7中
DL2:DJNZ R7,DL2 ;寄存器中的數據減1,不為零時則轉移
DJNZ R6,DL1 ;寄存器中的數據減1,不為零時則轉移
INC R1 ;寄存器R1中的數值加1
MOV A,R5 ;寄存器R5中的數值送累加器A中
JNB ACC.2,ENDOUT ;地址位為0則轉到ENDOUT
RL A ;累加器循環右移
MOV R5,A ;累加器A中的數值送寄存器R5中
AJMP PLAY ;絕對短轉移
ENDOUT: SETB P3.5 ;置P3.5口
MOV P1,#0FFH ;立即數0FEH送P1口
RET ;返回
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
END ;結束

我見過一款製作容易免調試的超聲波測距板,你可到「谷歌」上搜索一下《一款製作容易免調試的超聲波測距板》,該超聲波測距板結構簡單、製作容易不需要調試、測量精度高,比較適合單片機初學都使用,同時也是單片機課程設計比較好的實訓課題。該超聲波測距系統,提供套件,及組裝好的板件,含原理圖、源程序、設計說明等。

② 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

③ 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;}
}

④ 基於單片機的超聲波多路數據採集系統

原來做過一個超聲波的控制類題目,使用四路超聲波來定位一個只能小汽車,用的mc9s12xs128,用中斷來採集信號,順序採集就行了,這里要使用有多路中斷資源的單片機,用來獲取超聲波的回撥信號確定距離,超聲波測距是有距離限制的,太遠了時間就會很長(自己算算就知道了),模塊網上選一個就行。
至於PC機上顯示,使用labview做上位機最快,很簡單的一種方式,而且有常式,數據發送使用串口,PL2303模塊就行
都大四了,一看就大學沒好好學習,不過將來未必都是靠專業吃飯的,但是學習態度和自己的努力就很重要了。

⑤ 51單片機最多可以控制幾個超聲波模塊

如果沒有時間限制,肯定是N個,因為是分時工作。如果是同時工作那就不行了。

⑥ 求用一塊單片機控制2個超聲波感測器的程序

#include <reg52.h>
#include <stdio.h>
#include <math.h>
#include "1602.h"
#include "delay.h"

sbit TRIG = P1^0 ;
sbit ECHO = P1^1 ;

unsigned char DisTempData[16];

/*------------------------------------------------
定時器0初始化
------------------------------------------------*/
void TIM0init(void)
{

TMOD|= 0x01;//定時器0工作方式1
TH0=0x00;
TL0=0x00;
ET0=1;
EA=1;
}
/*------------------------------------------------
主函數
------------------------------------------------*/
main()
{
float S; //距離變數
TIM0init(); //初始化定時器0
LCD_Init(); //初始化LCD
LCD_Write_String(0,1,"LY-UR04 demo");
while(1)
{

TRIG=1; //觸發信號是高電平脈沖,寬度大於10us
DelayUs2x(10);
TRIG=0;
while(!ECHO); //等待高電平
TR0=1;
while(ECHO); //等待低電平
TR0=0;
S=TH0*256+TL0;//取出定時器值高8位和低8位合並
S=S/58; //為什麼除以58等於厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 -> X秒=0.0058*Y米 -> 厘米=微秒/58
TH0=0;
TL0=0; //清除定時器0寄存器中的值
sprintf(DisTempData,"S=%6.2f CM ",S);//列印輸出結果
LCD_Write_String(0,0,DisTempData); //在液晶屏上顯示
DelayMs(250); //延時決定采樣速度

}
}

/*------------------------------------------------
定時器中斷子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
ECHO=0;
}

⑦ 51單片機控制的超聲波測距程序問題,為什麼num一直為0

嗯!這個問題是!你的外部中斷使用的是外部中斷0,而定時器使用的也是0.在51內,外部中斷0的優先順序是要大於定時器0的。所以在程序的最後是要先執行外部中斷0的!

然後你的程序就會先進入外部中斷服務,然後你在外部中斷中又把定時器中斷給關閉了!這樣你就不會走到定時器中斷的服務項中。

所以你的num一直是0

⑧ 怎麼用單片機控制兩個超聲波模塊測距 可以測一個但是兩個要怎麼辦 求大神!!!感激

這個跟你的程序流程有關系,你要設計好,兩個測距模塊的話。
第一個時間,A發射,然後接收好,記下數據後。再延時一會兒(消除雜波影響)。再啟動B模塊,也是發射,接收,記下數據。再延時一會兒。再啟動A。
單片機裡面大部分的功能實體都有2套,所以上面這種方法足夠用了。

⑨ 求超聲波發生器的單片機源代碼

//設計:ch314156

//模塊使用方法:一個控制口發一個10US以上的高電平,就可以在接收口等待高電平輸出.
//一有輸出就可以開定時器計時,當此口變為低電平時就可以讀定時器的值,此時就為此次測
//距的時間,方可算出距離.如此不斷的周期測,就可以達到你移動測量的值了

//波特率9600(晶振12M)
#include <reg52.h>
#include <intrins.h> //調用 _nop_(); 延時函數

#define uchar unsigned char
#define uint unsigned int

sbit trigger=P2^0; //觸發引腳
sbit rx=P2^1; //接收引腳
sbit key=P3^6; //按鍵

unsigned char key_scan(void);
uchar chaoshengbo(void);
void uart_init(void);
void uart(uchar distance);
void chaoshengbo_init(void);

uchar distance; //距離

void main()
{
uart_init(); //串口初始化
chaoshengbo_init(); //超聲波初始化
uart('A') ; //串口發送'A'

while(1)
{
if (key_scan() == 1) //按鍵按下
{
distance = chaoshengbo(); //超聲波測距
uart(distance); //串口發送距離 單位厘米
}
}
}

unsigned char key_scan(void) //按鍵查詢
{
unsigned char on = 0,i;
while(1)
{
if(key==0) //判斷是否按下
{
for(i=0;i<100;i++); //軟體延時
if(key==0) //再次判斷是否按下
{
on = 1;
break; //跳出循環
}
}

}
while(key==0);
return 1;
}

void uart_init(void) //串口初始化,用的是T1
{

TMOD=TMOD & 0x0f | 0x20;
TH1=0Xfd; //波特率9600(晶振12M)
TL1=0Xfd;
TR1=1;

REN=1;
SM0=0;
SM1=1;

}

void uart(uchar distance) //發送一個位元組
{
SBUF = distance;
while(!TI);
TI = 0;

}

void chaoshengbo_init(void) //超聲波初始化
{
trigger = 0;
}

uchar chaoshengbo(void) //超聲波測距,返回厘米值
{
trigger=1; //給至少10us的高電平信號

_nop_();
_nop_();
_nop_(); //延時
_nop_();
_nop_();
_nop_();
TMOD=TMOD & 0xf0 |0x01; //T0初始化
TH0=0X0;
TL0=0X0;

trigger=0;

while(!rx); //等待上升沿
EA = 0; //關中斷
TR0=1; //開啟T0定時器
while(rx); //等待下降沿
TR0=0; //關閉T0定時器
EA = 1; //開中斷

return (TH0*256+TL0)*0.034/2; //計算距離 單位厘米
}

⑩ 51單片機如何控制超聲波感測器

溫度感測器(temperature transcer)是指能感受溫度並轉換成可用輸出信號的感測器。

溫度感測器是溫度測量儀表的核心部分,品種繁多。按測量方式可分為接觸式和非接觸式兩大類,按照感測器材料及電子元件特性分為熱電阻和熱電偶兩類。

溫度感測器(temperature transcer)是指能感受溫度並轉換成可用輸出信號的感測器。溫度感測器是溫度測量儀表的核心部分,品種繁多。

按測量方式可分為接觸式和非接觸式兩大類,按照感測器材料及電子元件特性分為熱電阻和熱電偶兩類。

閱讀全文

與超聲示教儀單片機控制系統相關的資料

熱點內容
我的世界伺服器菜單插件如何使用 瀏覽:10
劉毅10000詞pdf 瀏覽:888
剛畢業的程序員會什麼 瀏覽:972
單片機控制64路開關量 瀏覽:980
win10截圖編程 瀏覽:418
怎樣把名字變成文件夾 瀏覽:201
文件怎麼搞成文件夾 瀏覽:728
多線程編程php 瀏覽:604
安卓機越用越卡有什麼辦法 瀏覽:15
高中生解壓操場適合做的游戲 瀏覽:393
程序員java招聘 瀏覽:458
未來之光手機雲伺服器 瀏覽:158
伺服器下載資料為什麼c盤滿了 瀏覽:263
怎麼清除空文件夾 瀏覽:544
如何查看派派伺服器 瀏覽:802
殺手6解壓畫面 瀏覽:669
誇張程序員 瀏覽:467
如何直播切兩個APP畫面 瀏覽:784
4x4測試伺服器怎麼獲得 瀏覽:740
開環與閉環python 瀏覽:517