我自己做了个超声波测距,其原理图如下:
发射电路用MAX232:
E39XE%]Q$~)WH5(6EQ@XTQ3.jpg (110.69 KB, 下载次数: 1)
下载附件
2012-5-26 23:50 上传
我感觉这样设计没问题,但是我焊好之后测距的时候出现了如下问题:
由于超声波有一个盲区,所以我延时了300us确保接收头不会直接接收发射传的波,
但是我测距的时候一直都显示我延时超声波走的距离的一半,直到我延时2ms的时候才能正常测距,显示才会跳动但是最小能侧距离就是超声波2ms走的距离的一半,
当我延时到4ms的时候这是测距的最远距离达到最大,但是最小距离就是超声波4ms走的距离的一半。
请问各位高手这个应该如何处理,让我既能测距远最近测距也能小到几cm?先谢谢了~~~~~~
不好意思,表述有问题,代码如下,是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[12] =
- {
- 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[4] =
- {
- 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[3] );
- }
- if(bai!=0 || shi != 0)
- {
- Send_Data_Disp( shi ,~position[2] );
- }
- Send_Data_Disp( ge ,~position[1] );
- Send_Data_Disp( 10 ,~position[1] );
- Send_Data_Disp( decimal ,~position[0] );
- Send_Data_Disp( 11 ,~position[1] );
- }
- }
- /**********************************************
- 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的值
- }
复制代码一周热门 更多>