專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

一款液晶顯示的超聲波測距板

作者:huqin   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2013年11月14日   【字體:

   這是一款液晶顯示超聲波測距板,資料是從網(wǎng)上收集整理的。該測距板顯示屏為3310手機液晶屏,測量范圍是4cm--450cm。單片機用的是51系列單片機,超聲波接收用的是CX20106A。為了使精度盡可能的提高,硬件方面使用了18B20監(jiān)測溫度,由溫度算出聲速的變化;軟件方面使用了“近距離<--->遠距離”自動調(diào)節(jié)“盲區(qū)時間”進行測量。因為盲區(qū)時間設(shè)小一點,可以測到較小的距離,但是測遠距離時就極不穩(wěn)定了;而盲區(qū)時間大了則相反;.軟件較正使用的是數(shù)據(jù)擬合的方式,即測出幾十組數(shù)據(jù)(儀器測出的矩離和實際矩離),輸入EXCEL里面,畫出XY散點圖。然后再擬合出距離關(guān)系曲線。這種方法可以使測量點盡量靠近每一個實際距離點。

 




 

源程序:

#include "stdio.h"

#include "math.h"

#include "regx52.h"

#include "binary.h"

#include "intrins.h"

#define  VOUT P3_7   //脈沖產(chǎn)生端口

#define  DQ  P1_0     //ds18b20 端口

 

/******************系統(tǒng)全局變量***************/

typedef  unsigned char uchar;

typedef  unsigned int uint;

bit Success;       //測量成功標志位

bit   Done;             //測量完成標志位

bit Mode;              //測量模式:0--近距離,1---遠距離

uint nCount;

uint nResult;

 

/******************18B20相關(guān)函數(shù)及變量***************/

bit SignedFlag=0;   //符號標志位  ,負為1,正為0

uchar TempInt;              //整數(shù)部分溫度

uint TempDot;        //小數(shù)部分溫度

void ReadTemperature(void);      //在程序中調(diào)用此函數(shù)

void Init_DS18B20(void);

unsigned char ReadOneChar(void);

void WriteOneChar(unsigned char dat);

void delayx(unsigned int i);

#include "18b20.h"

 

/******************LCD相關(guān)函數(shù)******************/

sbit SCLK = P2^0;        // 串行時鐘

sbit SDIN = P2^1;         // 串行數(shù)據(jù)輸入

sbit LCD_DC = P2^2;           // 數(shù)據(jù)/命令 選擇端

sbit LCD_CE = P2^3;           // 片選

sbit LCD_RST = P2^4;  // 外部復(fù)位

#include "Nokia5110.c"

 

/***********超聲波測量相關(guān)函數(shù)定義***************/

void StartInit();

void Delay_us(uint i);                //微秒級延時:T=7+2*(X-1) us

void StartMeasure();

void DisplayResult();

void ConvertCount();

void Delay_ms(uint x);

 

////////////////////////主函數(shù)////////////////////////////////

void main()

{

       unsigned long Sum;

       uchar i;

       uchar num;

       bit bOK;

       uchar

       TCON=B00000000;       //INT0電平觸發(fā)

       TMOD=0X01;      //T0作為計數(shù)輸入

       IP=B00000001;      //置INT0優(yōu)先級最高

 

       LCD_init();           //液晶初始化

       LCD_clear();  //清屏顯示

       DisplayChinese(0,0,13,16,3,0,0,WORD);     //在LCD上顯示“溫度:”

       DisplayChinese(72,0,13,16,1,3,0,WORD);   //在LCD上顯示“℃”

       DisplayChinese(0,2,13,16,3,4,0,WORD);     //在LCD上顯示"聲速:”

 

       while(1)     //測量系統(tǒng)主循環(huán)

       {   

              bOK=0;

              num=0;

              Sum=0;

              ReadTemperature();            //檢測當(dāng)前環(huán)境溫度

            

           for(i=1; i<=3; ++i)        //循環(huán)測量,求平均值

              {

                     StartInit();             //測量初始化

                     StartMeasure();             //開始測量第1次,確定大概范圍

                     if(Success==1)

                     {

                            bOK=1;             //有1次成功,則測距成功

                            Sum=(nCount>Sum)?nCount:Sum;      //取測量最大值

                     }

                     Delay_ms(80);         //延時10ms后繼續(xù)測量

              }

 

              nCount=Sum;

              Success=bOK;

              DisplayResult();

       }          

}

 

/***************所用到的相關(guān)函數(shù)功能實現(xiàn)*****************/

void INT_0() interrupt 0  using 0  //運行到此處說明測距成功

{   

       TR0=0;          //關(guān)計數(shù)

       ET0=0;          //關(guān)定時器中斷

       EX0=0;          //關(guān)INT0中斷

       while(!P3_2); //等待CX20106輸出電平變高

       //將計數(shù)器數(shù)據(jù)放進nCount,用來進行數(shù)據(jù)處理

       nCount=TH0;

       nCount=nCount<<8;

       nCount|=TL0;

       Success=1;

       Done=1;

 

       return;          

}

 

void INT_T0()  interrupt 1 using 1

{   

       //運行到此處說明測距失敗

       TR0=0;

       EX0=0;

       Success=0;

       Done=1;

 

       return ;

}

 

void StartInit()

{

        TH0=0;

        TL0=0;         //計數(shù)器置0

        EA=1;         //開總中斷

        ET0=0;         //關(guān)T0中斷

        EX0=0;        //關(guān)INT0中斷

        Success=0; //測量成功標志位

        Done=0;       //測量一次標志位

}

 

void StartMeasure()

{

       //產(chǎn)生脈沖波

       uchar LOOP;

       ET0=1;

     

       for (LOOP = 0;LOOP < 4; )

       {

        P3 = P3 ^ 0x80;

        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

              _nop_();_nop_();_nop_();_nop_();//_nop_();_nop_();

         LOOP++;

       }

       VOUT = 1;

       TR0 = 1; //啟動計數(shù)器

 

       if(Mode==0)          //近距離測量模式

       {

              Delay_us(41); //50us延時測量,防止回波干擾

       }

       else                    //遠距離測量模式

       {

              Delay_us(300);      //50us延時測量,防止回波干擾

       }

 

       EX0=1;                       //開INT0中斷

       while(Done==0);           //等待測量結(jié)束

}

 

void DisplayResult()

{

       float temp=0;

       char String[10];

 

       //算出當(dāng)前溫度

       temp=TempInt+TempDot/10000.0;            

       //顯示當(dāng)前溫度

       sprintf(String,"%0.2f",temp);

       DisplayEnglish(33,0,String);

       //算出當(dāng)前聲速

       temp=332+0.607*temp;            

       //顯示當(dāng)前聲速

       sprintf(String,"%0.1fm",temp);

       DisplayEnglish(33,2,String);

 

       if(Success==1)                                   //測距成功,顯示“成功”,并顯示距離

       {   

              temp=nCount*temp/2000+0.5;      // 算出距離

 

              //顯示遠、近距離測量的結(jié)果

              if(Mode==0)

              {

                     nResult=(0.9723*temp-14.803)+0.5;                                       //此式由擬合得到

                     DisplayEnglish(0,4,"N");

              }

              else

              {   

                     nResult=0.9648*temp-5.7716+0.5;              //此式由擬合得到                          

                     DisplayEnglish(0,4,"F");

              }

                            

              sprintf(String,"%5u cm",nResult);         //將整數(shù)轉(zhuǎn)換為字符串

              //拼湊顯示最終結(jié)果“xxx.xcm”

              DisplayEnglish(8,4,String);                 

              DisplayEnglish(40,4,".");                  

              String[5]='\0';

              DisplayEnglish(48,4,&String[4]);

              Delay_ms(50);

 

       }

       else                         //測距失敗,顯示“失敗”提示

       {

        DisplayEnglish(0,4," --Fail-- ");

       }

 

       if(nResult>500)

       {

              Mode=1;

       }

       else

       {

              Mode=0;

       }

 

}

 

void Delay_ms(uint x)    //12M環(huán)境下延時1ms

{

        uchar j;

        while(x--)

        {

           for(j=0;j<125;j++);

        }

}

 

void Delay_us(uint i)   //微秒級延時:T=7+2*(X-1) us

{

    while(--i);

}

關(guān)閉窗口

相關(guān)文章