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

2020-02-05 09:15发布

  我自己做了个超声波测距,其原理图如下:
发射电路用MAX232: E39XE%]Q$~)WH5(6EQ@XTQ3.jpg (110.69 KB, 下载次数: 1) 下载附件 2012-5-26 23:50 上传
我感觉这样设计没问题,但是我焊好之后测距的时候出现了如下问题:
由于超声波有一个盲区,所以我延时了300us确保接收头不会直接接收发射传的波,
但是我测距的时候一直都显示我延时超声波走的距离的一半,直到我延时2ms的时候才能正常测距,显示才会跳动但是最小能侧距离就是超声波2ms走的距离的一半,
当我延时到4ms的时候这是测距的最远距离达到最大,但是最小距离就是超声波4ms走的距离的一半。
请问各位高手这个应该如何处理,让我既能测距远最近测距也能小到几cm?先谢谢了~~~~~~
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
larryliuhao
2020-02-05 18:47
Lavind 发表于 2012-5-27 23:47
看了三遍才明白是怎么回事儿。。
如果方便的话,把代码贴上来吧~~
这样找问题方便点 ...

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

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

  4. sbit Trig =P3^7;         //触发
  5. sbit Echo =P3^2;         //接收信号
  6. sbit DQ = P3^3;
  7. sbit DS = P2^0;
  8. sbit OE = P2^1;
  9. sbit ST = P2^2;
  10. sbit SH = P2^3;
  11. sbit MR = P2^4;

  12. unsigned char flag, tltemp,TH,TL;
  13. unsigned char time_H,time_L;      //存储高电平时间
  14. unsigned char decimal,ge,shi,bai;   
  15. unsigned int distance2;
  16. double distance,time,TN,speed;
  17. unsigned char NumCode[12] =
  18. {
  19.         0xf5, //0
  20.         0x44, //1
  21.         0x79, //2
  22.         0x5d, //3
  23.         0xcc, //4
  24.         0x9d, //5
  25.         0xbd, //6
  26.         0x45, //7
  27.         0xfd, //8
  28.         0xcd, //9
  29.         0x02, //.
  30.         0x00
  31. };
  32. unsigned char position[4] =
  33. {       
  34.         0x10,
  35.         0x80,
  36.         0x40,
  37.         0x20
  38. };

  39. /**************
  40.     nms延时
  41. ***************/
  42. void delay_nms(unsigned int t)
  43. {
  44.     unsigned char i;
  45.     while(t--)
  46.     {
  47.         for(i = 114;i > 0;i--)
  48.                     ;
  49.     }
  50. }

  51. void delay_100us(void)
  52. {
  53.         _nop_();_nop_();_nop_();_nop_();
  54.         _nop_();_nop_();_nop_();_nop_();
  55.         _nop_();_nop_();_nop_();_nop_();
  56.         _nop_();_nop_();_nop_();_nop_();
  57.         _nop_();_nop_();_nop_();_nop_();
  58.         _nop_();_nop_();_nop_();_nop_();
  59.         _nop_();_nop_();_nop_();_nop_();
  60.         _nop_();_nop_();_nop_();_nop_();
  61.         _nop_();_nop_();_nop_();_nop_();
  62.         _nop_();_nop_();_nop_();_nop_();
  63.         _nop_();_nop_();_nop_();_nop_();
  64.         _nop_();_nop_();_nop_();_nop_();
  65.         _nop_();_nop_();_nop_();_nop_();
  66.         _nop_();_nop_();_nop_();_nop_();
  67.         _nop_();_nop_();_nop_();_nop_();
  68.         _nop_();_nop_();_nop_();_nop_();
  69.         _nop_();_nop_();_nop_();_nop_();
  70.         _nop_();_nop_();_nop_();_nop_();
  71.         _nop_();_nop_();_nop_();_nop_();
  72.         _nop_();_nop_();_nop_();_nop_();
  73.         _nop_();_nop_();_nop_();_nop_();
  74.         _nop_();_nop_();_nop_();_nop_();
  75.         _nop_();_nop_();_nop_();_nop_();
  76.         _nop_();_nop_();_nop_();_nop_();
  77.         _nop_();_nop_();_nop_();_nop_();
  78. }

  79. /***************
  80.     12us延时
  81. ****************/
  82. void delay_12nop(void)
  83. {
  84.     _nop_();
  85.     _nop_();
  86.     _nop_();
  87.     _nop_();
  88.     _nop_();
  89.     _nop_();
  90.     _nop_();
  91.     _nop_();
  92.     _nop_();
  93.     _nop_();
  94.         _nop_();
  95.     _nop_();
  96. }

  97. void HC595_Data_Write( const unsigned char W_data )
  98. {
  99.         unsigned char i,Temp_Data = W_data;

  100.         for( i = 0;i < 8;i++ )
  101.         {
  102.                 SH = 0; ; //为上升沿做准备
  103.                 if( Temp_Data & 0x80 )
  104.                 {
  105.                         DS = 1 ; //最高位是否为1,是则给从设备输入1
  106.                 }
  107.                 else
  108.                 {
  109.                         DS = 0;; //否则从设备输入0
  110.                 }
  111.                 HC595_Delay();
  112.                 SH = 1; //串行时钟(SCLK)上升沿
  113.                 Temp_Data <<= 1; //下一个数据位
  114.         }
  115. }

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

  128. void Open_HC595( void )
  129. {
  130.         unsigned char i;

  131.         OE = 0 ;
  132.         MR = 0;
  133.         for(i = 0;i<100;i++ );
  134.         MR = 1;
  135. }

  136. /**********************
  137.     数码管显示函数
  138. ***********************/
  139. void display(void)
  140. {
  141.         unsigned char k;

  142.     time = time_H*256+time_L;
  143. //        if(distance > 178)
  144. //            distance = (time*speed*100/1000000)/2+20;
  145. //        else
  146.                 distance = (time*speed*100/1000000)/2;
  147.     distance2 = distance*10;
  148.     bai = distance2/1000;
  149.     shi = (distance2%1000)/100;
  150.     ge = (distance2%100)/10;
  151.     decimal = distance2%10;
  152.         for(k = 0;k < 3;k++)
  153.         {
  154.             if(bai != 0)
  155.             {
  156.                 Send_Data_Disp( bai ,~position[3] );
  157.             }
  158.                     if(bai!=0 || shi != 0)
  159.                    {
  160.                        Send_Data_Disp( shi ,~position[2] );
  161.                    }

  162.                    Send_Data_Disp( ge ,~position[1] );

  163.                 Send_Data_Disp( 10 ,~position[1] );

  164.                    Send_Data_Disp( decimal ,~position[0] );

  165.                 Send_Data_Disp( 11 ,~position[1] );
  166.         }
  167. }

  168. /**********************************************
  169. function: initialize ds18b20
  170. **********************************************/
  171. bit init_ds18b20 (void)
  172. {                                                         
  173.     unsigned char i;
  174.     bit flag;        //variable to check whether ds18b20 exists
  175.    
  176.     DQ = 1;           //P348 step 1
  177.    
  178.     for (i = 0; i < 2; i ++)
  179.         ;             //P348 step 2: delay 6us
  180.    
  181.     DQ = 0;            //P348 step 3
  182.    
  183.     display();             //P348 step 4: delay 600us
  184.    
  185.     DQ = 1;           //P348 step 5
  186.    
  187.     for (i = 0; i < 10; i ++)
  188.         ;            
  189.    
  190.     flag = DQ;       //P348 step 7

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

  192.     return (flag);
  193.            
  194. }


  195. /**********************************************
  196. function: read a byte from ds18b20
  197. **********************************************/
  198. unsigned char read (void)
  199. {
  200.     unsigned char i,j;
  201.     unsigned char dat;

  202.     for (i = 0; i < 8; i ++)
  203.     {
  204.         DQ = 1;
  205.         _nop_ ();
  206.            
  207.         DQ = 0;
  208.         _nop_ ();
  209.            
  210.         DQ = 1;
  211.            
  212.         for (j = 0; j < 2; j ++)
  213.             ;         //delay 6us
  214.         dat >>= 1;
  215.         if (DQ == 1)
  216.             dat |= 0x80;
  217.         else
  218.             dat |= 0x00;

  219.         for (j = 0; j < 8; j ++)
  220.                     ;
  221.     }
  222.     display();
  223.     return (dat);
  224. }

  225. /**********************************************
  226. function: write a byte into ds18b20
  227. **********************************************/
  228. void write (unsigned char dat)
  229. {
  230.     unsigned char i,j;
  231.    
  232.     for (i = 0; i <8; i ++)
  233.     {
  234.         DQ = 1;
  235.         _nop_ ();

  236.         DQ = 0;

  237.         DQ = dat & 0x01;

  238.         for (j = 0; j <10; j ++)
  239.                     ;

  240.         DQ = 1;
  241.            
  242.         for (j = 0; j < 1; j ++)
  243.                     ;
  244.            
  245.         dat >>= 1;
  246.     }
  247.     display();
  248. }

  249. /**********************************************
  250. function: get ready for testing a temperature
  251. **********************************************/
  252. void ready (void)
  253. {
  254.     init_ds18b20 ();       
  255.     write (0xcc);
  256.     write (0x44);
  257.    
  258.     display();
  259.    
  260.     init_ds18b20 ();
  261.     write (0xcc);
  262.     write (0xbe);

  263.     display();
  264. }

  265. /**************************
  266.       定时中断初始化
  267. ***************************/
  268. void inint(void)
  269. {
  270.     TMOD=0x01;
  271.     TH0=0;
  272.     TL0=0;
  273.     TR0=0;
  274.     IT0=0;
  275.     EX0=0;
  276.     EA=1;
  277. }

  278. /*************
  279.     主函数
  280. **************/
  281. void main(void)
  282. {
  283.    inint();
  284.    Open_HC595();
  285.    while(1)
  286.    {
  287.         flag = 0;
  288.         ready ();
  289.         display();               
  290.         TL = read ();     //read the lower position first
  291.         TH = read ();      //and then the high one
  292.         display();
  293.         TN = TH * 16 + TL / 16;
  294.         speed = 331.4+0.607*TN;
  295.         display();

  296.         Trig=1;
  297.         delay_12nop();
  298.         Trig=0;
  299.                 delay_12nop();
  300.                 Trig=1;
  301.         delay_12nop();
  302.             Trig=0;

  303.         while(!Echo);
  304.         TR0=1;          //启动定时器0
  305.                 EX0=0;
  306.                   //就是这里的延时用几百us不行要延时4ms才行
  307.                 delay_100us();
  308.                 delay_100us();
  309. //                delay_nms(4);
  310.                                    
  311.         EX0=1;          //打开外部中断
  312.         while(TH0 < 180);
  313.         TR0=0;          //关闭定时器0
  314.         TH0=0;          //定时器0清零          
  315.         TL0=0;          //定时器0清零         
  316.         display();      
  317.     }
  318. }

  319. /************************************
  320.     外部中断0,检测回波高电平时间
  321. *************************************/     
  322. void int0_routine(void)  interrupt 0     
  323. {
  324.      EX0 = 0;            //关闭外部中断  
  325.      time_H = TH0;    //取出定时器0的值   
  326.      time_L = TL0;    //取出定时器0的值            
  327. }
复制代码

一周热门 更多>