|
超聲波測距 數(shù)值顯示
單片機(jī)源程序如下:
- #include <reg52.h>
- #include <math.h>
- #include <stdio.h>
- #include <intrins.h>
- #include <string.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- sbit DQ = P2^7; //定義18B20引腳
- /*
- sbit G1 = P2^0;//數(shù)碼管1
- sbit G2 = P2^1;//數(shù)碼管2
- sbit G3 = P2^2;//數(shù)碼管3
- sbit G4 = P2^3;//數(shù)碼管4
- sbit key1=P3^5;//按鍵1
- */
- sbit G1 = P1^0;//數(shù)碼管1
- sbit G2 = P1^1;//數(shù)碼管2
- sbit G3 = P1^2;//數(shù)碼管3
- sbit G4 = P1^3;//數(shù)碼管4
- sbit key1=P1^4;//按鍵1
- sbit RX=P3^2;//回波引腳
- sbit TX=P3^3;//產(chǎn)生脈沖引腳
- uchar keyvalue=0;//鍵值
- uint keycount=0;//計時
- float time=0;//反射時間
- float C,T;//速度,溫度
- unsigned int timer=0;//計時
- unsigned long S=0;//測量的距離
- bit flag =0;//中斷溢出標(biāo)志
- unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};//段碼0-9
- unsigned char const positon[4]={ 0xfe,0xfd,0xfb,0xf7};//位選
- unsigned char disbuff[4] ={ 0,0,0,0,},posit=0;//自定義變量
- unsigned char tx[10]={0,0,0x2E,0,0,0,0,0xDF,0x43,0x0A};//存儲溫度
- /********************************************************************
- * 名稱 : Delay()
- * 功能 : 微秒級延時函數(shù)
- * 輸入 : num
- * 輸出 : 無
- ***********************************************************************/
- void Delay(int num)//延時函數(shù)
- {
- while(num--) ;
- }
- /********************************************************************
- * 名稱 : Delaynms()
- * 功能 : 毫秒級延時函數(shù)
- * 輸入 : num
- * 輸出 : 無
- ***********************************************************************/
- void Delaynms(unsigned int di) //延時
- {
- unsigned int da,db;
- for(da=0;da<di;da++)
- for(db=0;db<100;db++);
- }
- /********************************************************************
- * 名稱 : Init_DS18B20()
- * 功能 : 初始化ds1820
- * 輸入 : 無
- * 輸出 : dat
- ***********************************************************************/
- void Init_DS18B20(void)//初始化ds1820
- {
- unsigned char x=0;
- DQ = 1; //DQ復(fù)位
- Delay(8); //稍做延時
- DQ = 0; //單片機(jī)將DQ拉低
- Delay(80); //精確延時 大于 480us
- DQ = 1; //拉高總線
- Delay(14);
- x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- Delay(20);
- }
- /********************************************************************
- * 名稱 : ReadOneChar()
- * 功能 : 從DS18B20讀取一節(jié)數(shù)據(jù)
- * 輸入 : 無
- * 輸出 : dat
- ***********************************************************************/
- unsigned char ReadOneChar(void)//讀一個字節(jié)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號
- dat>>=1;
- DQ = 1; // 給脈沖信號
- if(DQ)
- dat|=0x80;
- Delay(4);
- }
- return(dat);
- }
- /********************************************************************
- * 名稱 : WriteOneChar()
- * 功能 : 對DS18B20寫一節(jié)數(shù)據(jù)
- * 輸入 : dat
- * 輸出 : 無
- ***********************************************************************/
- void WriteOneChar(unsigned char dat)//寫一個字節(jié)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- Delay(2);
- DQ = 1;
- dat>>=1;
- }
-
- }
- /********************************************************************
- * 名稱 : ReadTemperature()
- * 功能 : 讀取數(shù)據(jù) 轉(zhuǎn)換溫度
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void ReadTemperature(void)//讀取溫度
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned char Data_L=0;
- unsigned char num=0;
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳過讀序號列號的操作
- WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器
- a=ReadOneChar(); //讀低8位
- b=ReadOneChar(); //讀高8位
- tx[0] = (a/16+b*16)/10; //整數(shù)部分
- tx[1] = (a/16+b*16)%10;
- Data_L=a&0X0F;
- for(num=3;num<7;num++) //小數(shù)部分
- {
- Data_L=Data_L*10; //10 //100 //40 //80
- tx[num]=Data_L/16; //0 //6 //2 //5
- Data_L=Data_L%16; //10 //4 //8
- }
- }
- /********************************************************************
- * 名稱 : Display(void)
- * 功能 : 數(shù)碼管顯示距離
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Display(void)
- {
- if(posit==0)
- {
- P0=(discode[disbuff[posit]])&0x7f;
- }
- else
- {
- P0=discode[disbuff[posit]];
- }
- P2=positon[posit];
- if(++posit>=4)
- posit=0;
- }
- /********************************************************************
- * 名稱 : Conut(void)
- * 功能 : 計算距離
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Conut(void)
- {
- uchar i;
- time=TH0*256+TL0;
- TH0=0;
- TL0=0;
- if(time>290)//補(bǔ)償
- {
- i=time/290;
- time=time+i*25;
- }
- ReadTemperature(); //讀取溫度
- T=(tx[0]*1000+tx[1]*100+tx[3]*10+tx[4]);//溫度
- C=331.4+0.607*T/100;//當(dāng)時溫度對應(yīng)的聲波速度
-
- S=time*C/2/1000; //算出來是MM
- //S=time/58*10;//(time*1.7)/100; //算出來是CM
- if((S>=7000)||flag==1) //超出測量范圍顯示“-”
- {
- flag=0;
- disbuff[0]=10; //“-”
- disbuff[1]=10; //“-”
- disbuff[2]=10; //“-”
- disbuff[3]=10; //“-”
- }
- else
- {
- disbuff[0]=S/1000;
- disbuff[1]=S%1000/100;
- disbuff[2]=S%100%100/10;
- disbuff[3]=S%100%100%10;
- }
-
- }
- /********************************************************************
- * 名稱 : zd0()
- * 功能 : T0中斷用來計數(shù)器溢出,超過測距范圍
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void zd0() interrupt 1
- {
- flag=1; //中斷溢出標(biāo)志
- }
- /********************************************************************
- * 名稱 : zd3()
- * 功能 : T1中斷用來掃描數(shù)碼管和計800MS啟動模塊
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void zd3() interrupt 3
- {
- TH1=0xf8;
- TL1=0x30;
- timer++;
- if(keyvalue==1)
- keycount++;
- Display();//數(shù)碼管顯示
- }
- /********************************************************************
- * 名稱 : scankey()
- * 功能 : 按鍵掃描
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void scankey()
- {
- if(key1==0)//按鍵按下
- {
- Delaynms(5);//消抖
- if(key1==0)//再次檢測按鍵
- {
- keyvalue=1;
- while(!key1);//等待釋放
- }
- }
-
- }
- /********************************************************************
- * 名稱 : timeInit()
- * 功能 : 定時器初始化
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void timeInit()
- {
- TMOD=0x11; //設(shè)T0為方式1,GATE=1;
- TH0=0;
- TL0=0;
- TH1=0xf8; //2MS定時
- TL1=0x30;
- ET0=1; //允許T0中斷
- ET1=1; //允許T1中斷
- //TR1=1; //開啟定時器
- EA=1; //開啟總中斷
- }
- /********************************************************************/
- /********************************************************************/
- /* 名稱 : main()
- /* 功能 : 主函數(shù)
- /* 輸入 : 無
- /* 輸出 : 無
- /********************************************************************/
- /********************************************************************/
- void main(void)
- {
- uchar ab=0,i;
- Init_DS18B20();//18b20初始化
- timeInit();//定時器初始化
- while(1)
- {
- scankey();//按鍵掃描
- if(keyvalue==1)
- {
- TR1=1; //開啟定時器
- if(RX==1)//當(dāng)RX為零時等待
- {
- TR0=1; //開啟計數(shù)
- ab=1;
- }
- if(RX==0&&ab==1) //當(dāng)RX為1計數(shù)并等待
- {
- TR0=0; //關(guān)閉計數(shù)
- Conut(); //計算
- ab=0;
- }
- }
- if(timer>=400&&ab==0)
- {
- 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;
-
- }
-
- if(keycount>=4800)
- {
- keyvalue=0;
- keycount=0;
- TR1=0;
- P2=0xff;
- }
-
- }
-
- }
復(fù)制代碼
|
|