51單片機課程設計:基於51單片機的超聲波測距

51單片機課程設計:基於51單片機的超聲波測距(測距原理介紹)

    本程序利用超聲波模塊來進行距離的測量,並顯示在數碼管上,其他朋友可以在本程序的基礎上,修改部分代碼,應用到智能小車上或者其他測距設備上。

    超聲波測距的原理是:首先給模塊Trig端一個高電平,然後單片機開始計時,同時模塊會發射超聲波信號,當單片機檢測到Echo端爲高電平時(也就是說模塊收到反射的信號),計時停止。通過以上操作,我們就可以得到一個時間變量,然後調用對應的公式就可以將時間變量轉換爲距離。

    相關工程文件以及資料在文章下方,感興趣的朋友可以下載。

    關於粘貼複製亂碼的問題:如果程序複製到Keil編譯器上出現註釋亂碼,可以先建一個.c文件,也就是說不在keil裏面編輯,然後用記事本打開.c文件,將源碼複製進去,再在keil中添加文件即可。

/****************************************************************
                    基於51單片機的超聲波測距例程
如果需要在其他開發板上運行並顯示,只需要修改數碼管顯示模塊即可
DisplayData[8]用於存放轉換後的距離數據,也就是說你只需要將其中
的數據在其他顯示模塊顯示出來。
    引腳3.1 接模塊Trig
    引腳3.2 接模塊Echo
    晶振頻率一般都是12MHZ
                            2016-12-30---------------------SWorld
****************************************************************/
#include<reg52.h>
#define uchar unsigned char   //宏定義無符號字符型
#define uint  unsigned  int   //宏定義無符號整型
#define GPIO_DIG P0//位選以及段選數據輸出端口定義
unsigned char code DIG_CODE[10]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //顯示段碼 數碼管字跟
unsigned char DisplayData[8];//用來存放要顯示的8位數的值
sbit DUC=P2^2;//   DUC段選信號
sbit WEC=P2^3;//WEC    位選信號
sbit Trig=P3^1; 
sbit Echo=P3^2;
uchar succeed_flag=0;
uint timeH,timeL,distance=0,time=0,ss;
//float ;
//延時子程序   延時1ms
void delay_ms(uint c)
{
    uchar a, b;
    for(;c>0;c--)
    {
        for (b=38;b>0;b--)
        {
            for (a=13;a>0;a--);
        }      
    }   
}
//延時子程序  延時1us
void delay_us(uint c)
{
    uchar a ;
    for(;c>0;c--)
        for(a=0;a<5;a++);
}

//數碼管顯示
void DigDisplay()
{
    unsigned char i;
    unsigned int j;
    for(i=0;i<8;i++)
    {
        WEC=1;DUC=0;
        switch(i) //位選,選擇點亮的數碼管,
        {
            case(0):
                GPIO_DIG=0x7F; break;//顯示第0位
            case(1):
                GPIO_DIG=0xBF; break;//顯示第1位
            case(2):
                GPIO_DIG=0xDF; break;//顯示第2位
            case(3):
                GPIO_DIG=0xEF; break;//顯示第3位
            case(4):
                GPIO_DIG=0xF7; break;//顯示第4位
            case(5):
                GPIO_DIG=0xFB; break;//顯示第5位
            case(6):
                GPIO_DIG=0xFD; break;//顯示第6位
            case(7):
                GPIO_DIG=0xFE; break;//顯示第7位
        }
        WEC=0;DUC=1;
        GPIO_DIG=DisplayData[i];//發送段碼
        j=15; //掃描間隔時間設定
        while(j--);
        GPIO_DIG=0x00;//消隱
    }
}
//主函數模塊
void main(void)
{
    Trig=0;
    EA=1;
    TMOD=0x11;//定時器1,16位工作方式  定時器0 16位工作方式
    while(1)
    {
        EA=0;           //關總中斷
        Trig=1;         
        delay_us(20);   //延時20us
        Trig=0;         //20us脈衝
        while(Echo==0);    //等待Echo回波引腳變高電平
            succeed_flag=0; 
        EA=1; //開外部中斷
        EX0=1;         //打開外部中斷0
        TH1=0;          //定時器1缺清零
        TL1=0;   //計數溢出標誌
        TF1=0;          
        TR1=1;          //啓動定時器1
        delay_ms(20);      
        TR1=0;          //關閉定時器1
        EX0=0;          //關外部中斷
        if(succeed_flag==1)
        {   
            time=timeH*256+timeL;
            distance=time*0.172;  
         }                         
         if(succeed_flag==0)
        {
            distance=0;                    
        } 
        DisplayData[5]=DIG_CODE[distance/100];
        DisplayData[4]=DIG_CODE[(distance%100)/10];  
        DisplayData[3]=DIG_CODE[distance%10];  
        for(ss=0;ss<200;ss++)
        DigDisplay();
    }
}
//外部中斷0  用於判斷回波電路
void exter()  interrupt 0   
{   
     timeH =TH1;    //取出定時器值H
     timeL =TL1;    //取出定時器值L
     succeed_flag=1;//成功測量標誌
     EX0=0;         //關外部中斷
}
//定時器1中斷  用作超聲波測距計時
void timer1() interrupt 3  
{
    TH1=0;
    TL1=0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章