找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1110|回復: 0
打印 上一主題 下一主題
收起左側

單片機超聲波測距加溫度補償程序有什么問題嗎? 求幫助

[復制鏈接]
跳轉到指定樓層
樓主
ID:718252 發(fā)表于 2020-6-6 09:42 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
有沒有大佬給看看有什么問題。

#include <reg51.H>//器件配置文件
#include <intrins.h>

//傳感器接口
sbit echo  = P3^2;
sbit trig  = P3^3;
//按鍵聲明
sbit S1  = P1^4;   //切換厚度和溫度顯示


sbit W1=P1^0;
sbit W2=P1^1;
sbit W3=P1^2;
sbit W4=P1^3;
//蜂鳴器
sbit Feng= P2^0;
sbit ds=P3^7;                //DS18B20的接口


//變量聲明
int temp;
int j=0;
unsigned int  time=0;
unsigned int  timer=0;
unsigned char posit=0;
unsigned int S=0;
float S0=0;
float S2=0;
float v=0;
unsigned int h=0;
float h0=0;

//模式 0正常模式 1調(diào)整
char Mode=0;
bit  flag=0;
bit flag_KEY=0;
float distance[5]={0,0,0,0,0};
unsigned char const discode[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0xff/*-*/};    //數(shù)碼管顯示碼0123456789-和不顯示

unsigned char disbuff[4]       ={0,0,0,0};         //數(shù)組用于存放距離信息
unsigned char disbuff_wd[4]    ={0,0,0,0};//溫度信息
void Display();
//延時20ms(不精確)
void delay(void)
{
    unsigned char a,b,c;
    for(c=2;c>0;c--)
        for(b=38;b>0;b--)
            for(a=60;a>0;a--);
}
/*********************************************************/
//毫秒級延時
void delayms(unsigned char z)  
{
       unsigned char a,b;
       for(a=z; a>0; a--)
                for(b=110; b>0; b--);
}
/*********************************************************/

//微秒級延時
void delayus(unsigned char z)  
{
       while(z)
         z--;
}
/********************************************************/
void delay_ms(unsigned int ms)  //1ms延時
{
    unsigned char a;
    while(ms--)
for(a=123;a>0;a--);
}

/*********************************************************/
//DS18B20初始化
void ds18b20init()
{
           ds=0;
           delayus(80);                //延時480-960us
           ds=1;
           delayus(4);                 //等待應答
}
/*********************************************************/
//DS18B20讀命令子程序(讀一字節(jié))
unsigned char dushuju()
{
    unsigned char i,dat,m;
     for(i=8;i>0;i--)
     {
           ds=0;
           delayus(1);
           ds=1;
           delayus(2);
           m=ds;
           dat=(m<<7)|(dat>>1);   //讀出的數(shù)據(jù)最低位在最前面,剛好一個字節(jié)在dat里
           delayus(8);
      }
    return dat;
}
/*********************************************************/
//DS18B20寫命令子程序(寫一字節(jié))
void xiemingling(unsigned int shuju)
{
       unsigned int i;
       bit m;
       for(i=8;i>0;i--)
       {
          m=shuju&0x01;
          shuju=shuju>>1;
          if(m)                           //寫1
          {
                   ds=0;
                   delayus(2);
                   ds=1;
                   delayus(8);
          }
          else                     //寫0
          {
                   ds=0;
                   delayus(8);
                   ds=1;
                   delayus(2);
          }
       }
}


/*********************************************************/  
//DS18B20開始獲取溫度并轉換
void zhuanhuan()
{
           ds18b20init();
           delayms(1);
           xiemingling(0xcc);        //寫跳過讀ROM指令
           xiemingling(0x44);       //寫溫度轉換命令
}
/*********************************************************/
//DS18B20讀寄存器中存儲的溫度數(shù)據(jù)
int duwendu()
{
           unsigned int a,b;
           ds18b20init();
           delayms(1);
           xiemingling(0xcc);                     //跳過ROM,忽略64位ROM地址
           xiemingling(0xbe);                    //讀內(nèi)部RAM中的9字節(jié)的溫度數(shù)據(jù)
           a=dushuju();                            //讀低8位
           b=dushuju();                           //讀高8位
           b=b<<8;                                //高8位左移8位
           temp=b|a;                             // 高8位和低8位組合為1個字
           temp=temp*0.0625;              //溫度在寄存器中位12位,分辨率為0.0625度
           return temp;
}


/*********************************************************/

//按鍵掃描
void Key_()
{
    if(flag_KEY==0)
    {
        
        //功能
        if(S1==0)        //設置鍵
        {
            delay();
            if(S1==0)
            {
                Mode++;        //模式加
                flag_KEY=1;
                if(Mode>=2)        //加到2時清零
                {
                    Mode=0;
                }

            }
        }
    }
    if((P1&0x70)==0x70)
    {
        flag_KEY=0;
    }
}
/**********************************************************************************************************/
//掃描數(shù)碼管
void Display(void)                 
{
if(Mode==0)              //非設置狀態(tài)時
    {
        if((S2>=4000)||(flag==1)) //超出測量范圍顯示“-”
        {   
            Feng=0;            //蜂鳴器報警
            flag=0;
            disbuff[0]=10;        
            disbuff[1]=10;       //“-”
            disbuff[2]=10;       //“-”
            disbuff[3]=10;       //“-”
        }
        else
        {
            
            if((S2>100.3)||(S2<99.7))
            {
                Feng=0;    //報警
            }
            else
            {    Feng=1;        //關閉報警   
            
            h0=110-S2;
            h=(int)(h0*10);
            disbuff[0]=h/1000;         //將距離數(shù)據(jù)拆成單個位賦值
            disbuff[1]=h%1000/100;
            disbuff[2]=h%1000%100/10;
            disbuff[3]=h%1000%100%10;
            }
        }
    }
    else
    {
            Feng=1;

            disbuff_wd[0]=temp/1000;
            disbuff_wd[1]=temp%1000/100;
            disbuff_wd[2]=temp%1000%100/10;
            disbuff_wd[2]=temp%1000%100%10;
    }

    //正常顯示
    if(Mode==0)
    {
        P0=0x00;  //關閉顯示
     if(posit==2)
        {P0=discode[disbuff[posit]]|0x80;}
        else{
            P0=discode[disbuff[posit]];
        }
        switch(posit)
        {
            case 0 : W1=0;W2=1;W3=1;W4=1; break;
            case 1 : W1=1;W2=0;W3=1;W4=1; break;
            case 2 : W1=1;W2=1;W3=0;W4=1; break;
            case 3 : W1=1;W2=1;W3=1;W4=0; break;
        }
        posit++;
        if(posit>3)        //每進一次顯示函數(shù),變量加1
            posit=0;        //加到3時清零
    }
    //溫度顯示
    else
    {
        P0=0x00;
   
            P0=discode[disbuff_wd[posit]];
        
        switch(posit)
        {
            case 0 : W1=0;W2=1;W3=1;W4=1; break;
            case 1 : W1=1;W2=0;W3=1;W4=1; break;
            case 2 : W1=1;W2=1;W3=0;W4=1; break;
            case 3 : W1=1;W2=1;W3=1;W4=0; break;
        }
        posit++;
        if(posit>3)
            posit=0;
    }
}
/**********************************************************************************************************/
//計算
float Conut(void)
{
    time=(float)(TH0*256+TL0)*1.085;      //讀出T0的計時數(shù)值
    TH0=0;
    TL0=0;                  //清空計時器
    v=(331.5+0.607*temp);    //聲速與溫度的函數(shù)關系:聲速=331.5+0.607*溫度
    S0=v*time/20000;          //S0的單位是毫米
    return S0;
}

//定時器0
void zd0() interrupt 1          //T0中斷用來計數(shù)器溢出,超過測距范圍
{
    flag=1;                         //中斷溢出標志
}
/**********************************************************************************************************/
//定時器1
void zd3() interrupt 3          //T1中斷用來掃描數(shù)碼管和計800MS啟動模塊
{
    TH1=0xf8;
    TL1=0x30;                 //定時2ms
    Key_();                    //掃描按鍵
    Display();                //掃描顯示
    timer++;                //變量加
    if(timer>=400)            //400次就是800ms
    {
        timer=0;
        trig=1;                      //800MS  啟動一次模塊
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        trig=0;
    }
}
/**********************************************************************************************************/
//主函數(shù)
void main(void)
{  
    TMOD=0x11;           //設T0為方式1
    TH0=0;
    TL0=0;         
    TH1=0xf8;           //2MS定時
    TL1=0x30;
    ET0=1;                //允許T0中斷
    ET1=1;               //允許T1中斷
    TR1=1;               //開啟定時器
    EA=1;                    //開啟總中斷
  j=0;   
   
   
    while(1)
    {
      duwendu();
      while(j!=5)
      {
      
        
                                      
          while(!echo);        //當上次接收完波后,RX引腳是低電平,取反就是1,此while成立,反復判斷echo狀態(tài)。當echo沒有接收到返回波時是高電平,取反就是0,此while不成立,跳出
          TR0=1;            //開啟計數(shù)
          while(echo);        //當echo沒有接收到返回波,此while成立,程序停在這里一直判斷echo狀態(tài)。當RX接收到返回波,RX引腳變?yōu)榈碗娖剑藈hile不成立,跳出
          TR0=0;            //停止計數(shù)
          distance[j]=Conut();            //計算
            S2=S2+distance[j];
            j=j+1;
       }
         S2=S2/5;
         Display();
        
    }
}
                          
超聲波測距.7z (147.51 KB, 下載次數(shù): 3)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表