【急】菜鸟求助单片机超声波测距问题~~
我自己做了个超声波测距,其原理图如下:发射电路用MAX232:
接受电路用CX20106:
我感觉这样设计没问题,但是我焊好之后测距的时候出现了如下问题:
由于超声波有一个盲区,所以我延时了300us确保接收头不会直接接收发射传的波,
但是我测距的时候一直都显示我延时超声波走的距离的一半,直到我延时2ms的时候才能正常测距,显示才会跳动但是最小能侧距离就是超声波2ms走的距离的一半,
当我延时到4ms的时候这是测距的最远距离达到最大,但是最小距离就是超声波4ms走的距离的一半。
请问各位高手这个应该如何处理,让我既能测距远最近测距也能小到几cm?先谢谢了~~~~~~
{:smile:},过段时间也做做! 肿么没人回答的捏?{:cry:} 看了三遍才明白是怎么回事儿。。
如果方便的话,把代码贴上来吧~~
这样找问题方便点 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]