larryliuhao 发表于 2012-5-27 00:01:12

【急】菜鸟求助单片机超声波测距问题~~

我自己做了个超声波测距,其原理图如下:
发射电路用MAX232:
接受电路用CX20106:
我感觉这样设计没问题,但是我焊好之后测距的时候出现了如下问题:
由于超声波有一个盲区,所以我延时了300us确保接收头不会直接接收发射传的波,
但是我测距的时候一直都显示我延时超声波走的距离的一半,直到我延时2ms的时候才能正常测距,显示才会跳动但是最小能侧距离就是超声波2ms走的距离的一半,
当我延时到4ms的时候这是测距的最远距离达到最大,但是最小距离就是超声波4ms走的距离的一半。
请问各位高手这个应该如何处理,让我既能测距远最近测距也能小到几cm?先谢谢了~~~~~~

yan.ch.ao 发表于 2012-5-27 00:29:45

{:smile:},过段时间也做做!

larryliuhao 发表于 2012-5-27 17:48:37

肿么没人回答的捏?{:cry:}

Lavind 发表于 2012-5-27 23:47:54

看了三遍才明白是怎么回事儿。。
如果方便的话,把代码贴上来吧~~
这样找问题方便点

larryliuhao 发表于 2012-5-28 00:32:04

Lavind 发表于 2012-5-27 23:47 static/image/common/back.gif
看了三遍才明白是怎么回事儿。。
如果方便的话,把代码贴上来吧~~
这样找问题方便点 ...

不好意思,表述有问题,代码如下,是51的,加18B20和加了两片595移位锁存的的数码管显示#include<reg52.h>
#include <intrins.h>

#define HC595_Delay() {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}

sbit Trig =P3^7;         //触发
sbit Echo =P3^2;         //接收信号
sbit DQ = P3^3;
sbit DS = P2^0;
sbit OE = P2^1;
sbit ST = P2^2;
sbit SH = P2^3;
sbit MR = P2^4;

unsigned char flag, tltemp,TH,TL;
unsigned char time_H,time_L;      //存储高电平时间
unsigned char decimal,ge,shi,bai;   
unsigned int distance2;
double distance,time,TN,speed;
unsigned char NumCode =
{
        0xf5, //0
        0x44, //1
        0x79, //2
        0x5d, //3
        0xcc, //4
        0x9d, //5
        0xbd, //6
        0x45, //7
        0xfd, //8
        0xcd, //9
        0x02, //.
        0x00
};
unsigned char position =
{       
        0x10,
        0x80,
        0x40,
        0x20
};

/**************
    nms延时
***************/
void delay_nms(unsigned int t)
{
    unsigned char i;
    while(t--)
    {
      for(i = 114;i > 0;i--)
                    ;
    }
}

void delay_100us(void)
{
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
}

/***************
    12us延时
****************/
void delay_12nop(void)
{
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
        _nop_();
    _nop_();
}

void HC595_Data_Write( const unsigned char W_data )
{
        unsigned char i,Temp_Data = W_data;

        for( i = 0;i < 8;i++ )
        {
                SH = 0; ; //为上升沿做准备
                if( Temp_Data & 0x80 )
                {
                        DS = 1 ; //最高位是否为1,是则给从设备输入1
                }
                else
                {
                        DS = 0;; //否则从设备输入0
                }
                HC595_Delay();
                SH = 1; //串行时钟(SCLK)上升沿
                Temp_Data <<= 1; //下一个数据位
        }
}

void Send_Data_Disp( const unsigned char Data,const unsigned char Addr )
{
        MR = 0;
        HC595_Delay();
        MR = 1; // 给74HC595 一个有效的RST 信号
        ST = 0; // 为ST_CP 的上升沿做准备
        HC595_Data_Write( Addr ); // 写待显示位的地址
        HC595_Data_Write( NumCode[ Data ] ); // 在被选择位上送显示字码
        ST = 1; // 给ST_CP 一个有效的上升沿
        HC595_Delay(); // 在必要时适量延时
        ST = 0; // 为一下次上升沿做准备
}

void Open_HC595( void )
{
        unsigned char i;

        OE = 0 ;
        MR = 0;
        for(i = 0;i<100;i++ );
        MR = 1;
}

/**********************
    数码管显示函数
***********************/
void display(void)
{
        unsigned char k;

    time = time_H*256+time_L;
//        if(distance > 178)
//            distance = (time*speed*100/1000000)/2+20;
//        else
                distance = (time*speed*100/1000000)/2;
    distance2 = distance*10;
    bai = distance2/1000;
    shi = (distance2%1000)/100;
    ge = (distance2%100)/10;
    decimal = distance2%10;
        for(k = 0;k < 3;k++)
        {
            if(bai != 0)
            {
              Send_Data_Disp( bai ,~position );
            }
                  if(bai!=0 || shi != 0)
                   {
                     Send_Data_Disp( shi ,~position );
                   }

                   Send_Data_Disp( ge ,~position );

                Send_Data_Disp( 10 ,~position );

                   Send_Data_Disp( decimal ,~position );

                Send_Data_Disp( 11 ,~position );
        }
}

/**********************************************
function: initialize ds18b20
**********************************************/
bit init_ds18b20 (void)
{                                                       
    unsigned char i;
    bit flag;      //variable to check whether ds18b20 exists
   
    DQ = 1;         //P348 step 1
   
    for (i = 0; i < 2; i ++)
      ;             //P348 step 2: delay 6us
   
    DQ = 0;            //P348 step 3
   
    display();             //P348 step 4: delay 600us
   
    DQ = 1;         //P348 step 5
   
    for (i = 0; i < 10; i ++)
      ;            
   
    flag = DQ;       //P348 step 7

    display();             //waiting for the end of the impulse

    return (flag);
           
}


/**********************************************
function: read a byte from ds18b20
**********************************************/
unsigned char read (void)
{
    unsigned char i,j;
    unsigned char dat;

    for (i = 0; i < 8; i ++)
    {
      DQ = 1;
      _nop_ ();
           
      DQ = 0;
      _nop_ ();
           
      DQ = 1;
           
      for (j = 0; j < 2; j ++)
            ;         //delay 6us
      dat >>= 1;
      if (DQ == 1)
            dat |= 0x80;
      else
            dat |= 0x00;

      for (j = 0; j < 8; j ++)
                    ;
    }
    display();
    return (dat);
}

/**********************************************
function: write a byte into ds18b20
**********************************************/
void write (unsigned char dat)
{
    unsigned char i,j;
   
    for (i = 0; i <8; i ++)
    {
      DQ = 1;
      _nop_ ();

      DQ = 0;

      DQ = dat & 0x01;

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

      DQ = 1;
           
      for (j = 0; j < 1; j ++)
                    ;
           
      dat >>= 1;
    }
    display();
}

/**********************************************
function: get ready for testing a temperature
**********************************************/
void ready (void)
{
    init_ds18b20 ();       
    write (0xcc);
    write (0x44);
   
    display();
   
    init_ds18b20 ();
    write (0xcc);
    write (0xbe);

    display();
}

/**************************
      定时中断初始化
***************************/
void inint(void)
{
    TMOD=0x01;
    TH0=0;
    TL0=0;
    TR0=0;
    IT0=0;
    EX0=0;
    EA=1;
}

/*************
    主函数
**************/
void main(void)
{
   inint();
   Open_HC595();
   while(1)
   {
      flag = 0;
      ready ();
      display();               
      TL = read ();   //read the lower position first
      TH = read ();      //and then the high one
      display();
      TN = TH * 16 + TL / 16;
      speed = 331.4+0.607*TN;
      display();

      Trig=1;
      delay_12nop();
      Trig=0;
                delay_12nop();
                Trig=1;
      delay_12nop();
          Trig=0;

      while(!Echo);
      TR0=1;          //启动定时器0
                EX0=0;
                  //就是这里的延时用几百us不行要延时4ms才行
                delay_100us();
                delay_100us();
//                delay_nms(4);
                                 
      EX0=1;          //打开外部中断
      while(TH0 < 180);
      TR0=0;          //关闭定时器0
      TH0=0;          //定时器0清零          
      TL0=0;          //定时器0清零       
      display();      
    }
}

/************************************
    外部中断0,检测回波高电平时间
*************************************/   
void int0_routine(void)interrupt 0   
{
   EX0 = 0;            //关闭外部中断
   time_H = TH0;    //取出定时器0的值   
   time_L = TL0;    //取出定时器0的值            
}
页: [1]
查看完整版本: 【急】菜鸟求助单片机超声波测距问题~~