久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2353|回復: 3
收起左側

51單片機循跡過程中怎么實現無干擾超聲波避障?

[復制鏈接]
ID:465205 發表于 2019-4-21 15:14 | 顯示全部樓層 |閱讀模式
100黑幣
  1. StartModule();        //啟動模塊測距
  2.                  while(!RX);                //當RX(ECHO信號回響)為零時等待
  3.                  TR1=1;                            //開啟計數
  4.                  while(RX);                        //當RX為1計數并等待
  5.                  TR1=0;                                //關閉計數
  6.              Dist();                        //計算距離
復制代碼
  1. void zd0() interrupt 1        //T0中斷用來計數器溢出,超過測距范圍
  2. {
  3.         
  4.         flag=1;        
  5.                                                          //中斷溢出標志                        
  6. }
復制代碼

上面是一段普通的超聲波避障代碼,可以實現基本避障,但是我需要在巡線過程中用超聲波識別礙物并作出動作,小車的pwm用的T0,定時1ms,如果都在T0里面中斷,超聲波發送接收信號會使T0開關,然后pwm就會亂,怎么才能在一個定時器里面同時做超聲波中斷和pwm中斷,或者說怎么在T0不單獨清零時,計算出超聲波發送和接受信號的時間。用上面代碼放在循跡代碼以前,只用超聲波計算距離不執行其他動作,小車具體表現為:搖晃幅度較大,很容易就偏離軌跡,偶爾也可以循跡但是成功率特別低。            
  1. StartModule();        //啟動模塊測距
  2.                  while(!RX);                //當RX(ECHO信號回響)為零時等待
  3.                  l=0;
  4.                  l=(TH0<<8)|TL0;                            //記錄為0的時間
  5.                  while(RX);                        //當RX為1計數并等待
  6.                  l=T*1000+l-((TH0<<8)|TL0);                //計算時間
  7.                   S=l*0.17;                  
  8.                   delay(60);
復制代碼
  1. void zd0() interrupt 1        //T1中斷用來計數器溢出,超過測距范圍
  2. {
  3.         
  4.         flag=1;           //中斷溢出標志
  5.         T++;
  6. }
復制代碼



上面是朋友給我想的計算時間的辦法,思路是這樣:每執行一次中斷,使T累加。啟動超聲波模塊記錄Rx為0時的時間,然后記錄Rx為1的時間,算出時間差,再加上中斷的時間,算出總時間,最后算距離。用這個代碼在串口S的返回值為0,s放大100倍后,出現不穩定的正負巨大值。根本無法實現超聲波測距功能,請問這個代碼思路對不對,該怎么完善?或者有沒有其他方式解決這個問題?
附上完整代碼,感謝各位大神幫助
  1. #include<AT89X52.H>                  //包含51單片機頭文件,內部有各種寄存器定義
  2. #include<8testpwm.h>                  //包含pwm等函數
  3.   /*超聲波避障*/
  4. long int l;           //時間
  5. void Avoid(void)
  6. {
  7. //這段代碼無法實現測距
  8.               StartModule();        //啟動模塊測距
  9.                  while(!RX);                //當RX(ECHO信號回響)為零時等待
  10.                  l=0;
  11.                  l=(TH0<<8)|TL0;                            //
  12.                  while(RX);                        //當RX為1計數并等待
  13.                  l=T*1000+l-((TH0<<8)|TL0);                //
  14.                   S=l*0.17;                  
  15.                   delay(60);

  16. //注解代碼能正常測距,但在巡線過程測距干擾巡線
  17.         /*         StartModule();        //啟動模塊測距
  18.                  while(!RX);                //當RX(ECHO信號回響)為零時等待
  19.                  TR1=1;                            //開啟計數
  20.                  while(RX);                        //當RX為1計數并等待
  21.                  TR1=0;                                //關閉計數
  22.              Dist();                        //計算距離         */
  23.                  
  24.                  
  25. }

  26.         void Go_line()
  27. {
  28.         if(Led_1==1&&Led_3==1)
  29.         {
  30.                 line='L';
  31.         }
  32.         else if(Led_6&&Led_8==1)
  33.         {
  34.                 line='R';
  35.         }
  36.         else if(Led_1==1)
  37.         {
  38.                 line='1';
  39.         }
  40.         else if(Led_2==1)
  41.         {
  42.                 line='2';
  43.         }
  44.         else if(Led_3==1)
  45.         {
  46.                 line='3';
  47.         }
  48.         else if(Led_4==1)
  49.         {
  50.                 line='4';
  51.         }
  52.         else if(Led_5==1)
  53.         {
  54.                 line='5';
  55.         }
  56.         else if(Led_6==1)
  57.         {
  58.                 line='6';
  59.         }
  60.         else if(Led_7==1)
  61.         {
  62.                 line='7';
  63.         }
  64.         else if(Led_8==1)
  65.         {
  66.                 line='8';
  67.         }


  68. }
  69. /**************************巡線函數**********************************************/
  70. void Go()
  71. {

  72.         switch(line)
  73.         {
  74.                 case 'L':
  75.                 {
  76.                         
  77.                         counter();
  78.                         if(Count==3||Count==4||Count==7||Count==18||Count==20||Count==21)
  79.                         {        stop();
  80.                                 leftrun();
  81.                                 stop();
  82.                                 
  83.                                 
  84.                         }
  85.                         else if(Count==9||Count==14)
  86.                         {
  87.                                 run();
  88.                         
  89.                         }
  90.                         else if(Count==12||Count==17)
  91.                         {        stop();
  92.                                 rightrun();
  93.                                 stop();
  94.                         
  95.                                 
  96.                         }
  97.                         else if(Count==2||Count==5||Count==10||Count==13||Count==15)
  98.                         {        stop();
  99.                                 Return();
  100.                                 stop();        
  101.                         }
  102.                         else if(Count==22)
  103.                         {
  104.                                 stop();
  105.                         }
  106.                 }; break;

  107.                 case 'R':
  108.                 {
  109.                         counter();
  110.                         if(Count==8||Count==11||Count==12||Count==16||Count==17||Count==19)
  111.                         {
  112.                                 stop();
  113.                                 rightrun();
  114.                                 stop();
  115.                         
  116.                                 
  117.                         }
  118.                         else if(Count<2||Count==6)
  119.                         {
  120.                                 run();
  121.                                 
  122.                         }
  123.                         else if(Count==4||Count==21)
  124.                         {
  125.                                 stop();
  126.                                 leftrun();
  127.                                 stop();
  128.                         
  129.                                 
  130.                         }
  131.                         else if(Count==2||Count==5||Count==10||Count==13||Count==15)
  132.                         {
  133.                                 stop();
  134.                                 Return();
  135.                                 stop();
  136.                         
  137.                         }
  138.                         else if(Count==22)
  139.                         {
  140.                                 stop();
  141.                         }               
  142.                 };break;                  

  143.                 case '1':
  144.                 {
  145.                         leftp_3();
  146.                 }; break;
  147.                 case '2':
  148.                 {
  149.                         leftp_2();
  150.                 }; break;
  151.                 case '3':
  152.                 {
  153.                         leftp_1();
  154.                 }; break;
  155.                 case '4':
  156.                 {
  157.                         run();
  158.                 }; break;
  159.                 case '5':
  160.                 {
  161.                         run();
  162.                 }; break;
  163.                 case '6':
  164.                 {
  165.                         rightp_1();
  166.                 }; break;
  167.                 case '7':
  168.                 {
  169.                         rightp_2();
  170.                 }; break;
  171.                 case '8':
  172.                 {
  173.                         rightp_3();
  174.                 }; break;
  175.         
  176.         }

  177. }
  178. /**************************巡線函數**********************************************/

  179. //主函數
  180.         void main(void)
  181. {        
  182.                            P1=0X00;   //關電機        
  183.                         TMOD |= 0x01;//定時器0工作模塊1,16位定時模式,測量PWM波
  184.                         TH0= 0XFc;                  //1ms定時
  185.                  TL0= 0X18;
  186.                    TR0= 1;
  187.                 ET0= 1;
  188.                         SCON=0x50;
  189.                 EA = 1;                           //開總中斷
  190.                         TI=1;
  191.                         Count=0;
  192.                         push_val_left=0;
  193.                         push_val_right=0;
  194.         while(1)        //無限循環
  195.         {
  196.          
  197.                  //有信號為0  沒有信號為1

  198.            Avoid();
  199.            Go_line();
  200.            Go();
  201.            delay(50);         
  202.         }

  203. }

  204. #include <intrins.h>   //包含nop等系統函數
  205. #ifndef _LED_H_
  206. #define _LED_H_


  207.     //定義小車驅動模塊輸入IO口
  208.    sbit L293D_IN1=P1^2;
  209.    sbit L293D_IN2=P1^3;
  210.    sbit L293D_IN3=P1^4;
  211.    sbit L293D_IN4=P1^5;
  212.    sbit L293D_EN1=P1^6;
  213.    sbit L293D_EN2=P1^7;
  214.         


  215.          #define  TX    P3_3
  216.         #define  RX    P3_2
  217.     #define ShowPort   P0          //數碼管顯示端口
  218. /****************定義傳感器端口********************/
  219.         #define Led_1               P2_7         
  220.         #define Led_2                   P2_6         
  221.         #define Led_3                   P2_5         
  222.         #define Led_4                   P2_4         
  223.         #define Led_5          P2_3           
  224.         #define Led_6          P2_2           
  225.     #define Led_7          P2_1            
  226.            #define Led_8          P2_0         
  227.          
  228.    
  229.         #define Left_moto_pwm          P1_6         //PWM信號端

  230.         #define Right_moto_pwm          P1_7         //PWM信號端
  231.         
  232.         #define Left_moto_go      {P1_2=1,P1_3=0;}  //左電機向前走
  233.         #define Left_moto_back    {P1_2=0,P1_3=1;}         //左邊電機向后轉
  234.         #define Left_moto_Stop    {P1_2=0,P1_3=0;}  //左邊電機停轉                     
  235.         #define Right_moto_go     {P1_4=1,P1_5=0;}        //右邊電機向前走
  236.         #define Right_moto_back   {P1_4=0,P1_5=1;}        //右邊電機向后走
  237.         #define Right_moto_Stop   {P1_4=0,P1_5=0;}  //右邊電機停轉   

  238.         unsigned char code  LedShowData[]={0x03,0x9F,0x25,0x0D,0x99,  //定義數碼管顯示數據
  239.                                    0x49,0x41,0x1F,0x01,0x19        };//0,1,2,3,4,5,6,7,8,9
  240.         
  241.         unsigned char voice_sign;
  242.         unsigned int T;
  243.         unsigned char line;
  244.         unsigned int Count;
  245.         unsigned char pwm_val_left  =0;//變量定義
  246.         unsigned char push_val_left ;// 左電機占空比N/20
  247.         unsigned char pwm_val_right =0;
  248.         unsigned char push_val_right ;// 右電機占空比N/20
  249.         unsigned int  time = 0;//傳輸時間
  250.         unsigned long S = 0;//距離
  251.         bit Right_moto_stop=1;
  252.         bit Left_moto_stop =1;        
  253.         bit      flag = 0;//超出測量范圍標志位

  254.    
  255. /************************************************************************/        
  256. //延時函數        
  257.    void delay(unsigned int k)        //1mm延時
  258. {   
  259.      unsigned int x,y;
  260.          for(x=0;x<k;x++)
  261.            for(y=0;y<110;y++);
  262. }
  263. void Delay10us(unsigned char i)            //10us延時函數 啟動超聲波模塊時使用
  264. {
  265.    unsigned char j;
  266.         do{
  267.                 j = 10;
  268.                 do{
  269.                         _nop_();
  270.                 }while(--j);
  271.         }while(--i);
  272. }
  273. /************************************************************************/
  274. /*定時器0中斷*/
  275. void zd0() interrupt 1        //T1中斷用來計數器溢出,超過測距范圍
  276. {
  277.         
  278.         flag=1;        
  279.         T++;                                                 //中斷溢出標志                        
  280. }
  281. void  StartModule()                          //啟動超聲波模塊
  282. {
  283.           TX=1;                                             //啟動一次模塊
  284.       Delay10us(2);
  285.           TX=0;
  286. }


  287. void Dist()           //測試距離
  288. {
  289.         time=TH1*256+TL1;
  290.         TH1=0;
  291.         TL1=0;
  292.         
  293.         S=(float)(time*1.085)*0.17;     //算出來是MM
  294.         if((S>=5000)||flag==1) //超出測量范圍
  295.         {         
  296.                 flag=0;

  297.         }
  298. }



  299. /**************************計數函數**********************************************/
  300. void counter(void)
  301. {
  302.                         
  303.                         Count++;
  304.                         ShowPort = LedShowData[Count]  ;
  305.                         delay(200);
  306. }
  307. /**************************計數函數**********************************************/






  308. //前速前進
  309.      void  run(void)
  310. {
  311.      push_val_left=12;         //速度調節變量 0-20。。。0最小,20最大
  312.          push_val_right=12;
  313.          Left_moto_go ;   //左電機往前走
  314.          Right_moto_go ;  //右電機往前走
  315. }

  316. //后退函數
  317.      void  backrun(void)
  318. {
  319.      push_val_left=12;         //速度調節變量 0-20。。。0最小,20最大
  320.          push_val_right=12;
  321.          Left_moto_back;   //左電機往后走
  322.          Right_moto_back;  //右電機往后走
  323. }

  324. //左轉
  325.      void  leftrun(void)
  326. {         
  327.          
  328.      push_val_left=12;
  329.          push_val_right=18;
  330.          Right_moto_go ;  //右電機往前走
  331.      Left_moto_back   ;  //左電機后走
  332.          delay(490);
  333. }
  334. //左小偏
  335. void  leftp_1(void)
  336. {         
  337.      push_val_left=3;
  338.          push_val_right=12;
  339.          Right_moto_go ;  //右電機往前走
  340.      Left_moto_go   ;  //左電機后走
  341.          
  342.          
  343. }
  344. //左中偏
  345. void  leftp_2(void)
  346. {         
  347.      push_val_left=1;
  348.          push_val_right=12;
  349.          Right_moto_go ;  //右電機往前走
  350.      Left_moto_back   ;  //左電機后走
  351.          
  352.          
  353. }
  354. //左大偏
  355. void  leftp_3(void)
  356. {         
  357.      push_val_left=3;
  358.          push_val_right=12;
  359.          Right_moto_go ;  //右電機往前走
  360.      Left_moto_back   ;  //左電機后走
  361.          
  362.          
  363. }
  364. //右轉
  365.      void  rightrun(void)
  366. {
  367.          
  368.          push_val_left=18;
  369.          push_val_right=12;
  370.      Left_moto_go  ;   //左電機往前走
  371.          Right_moto_back    ;  //右電機往后走
  372.          delay(490)        ;
  373. }
  374. //右小偏
  375.      void  rightp_1(void)
  376. {
  377.          push_val_left=12;
  378.          push_val_right=3;
  379.      Left_moto_go  ;   //左電機往前走
  380.          Right_moto_go    ;  //右電機往后走               
  381. }
  382. //右中偏
  383.      void  rightp_2(void)
  384. {
  385.          push_val_left=12;
  386.          push_val_right=1;
  387.      Left_moto_go  ;   //左電機往前走
  388.          Right_moto_back    ;  //右電機往后走               
  389. }
  390. //右大偏
  391.      void  rightp_3(void)
  392. {
  393.          push_val_left=12;
  394.          push_val_right=3;
  395.      Left_moto_go  ;   //左電機往前走
  396.          Right_moto_back    ;  //右電機往后走
  397.          
  398.                
  399. }

  400. //停止
  401.      void  stop(void)
  402. {         
  403.             delay(200);
  404.          Right_moto_Stop ;  //右電機停止
  405.      Left_moto_Stop  ;  //左電機停止
  406.          delay(100);
  407. }



  408. //掉頭
  409.      void  Return(void)
  410.          {
  411.          push_val_left=18;
  412.          push_val_right=18;
  413.      Left_moto_go  ;   //左電機往前走
  414.          Right_moto_back    ;  //右電機往后走
  415.          delay(700)        ;
  416.         
  417.          }

  418.    

  419. /************************************************************************/
  420. /*                    PWM調制電機轉速                                   */
  421. /************************************************************************/
  422. /*                    左電機調速                                        */
  423. /*調節push_val_left的值改變電機轉速,占空比            */
  424.                 void pwm_out_left_moto(void)
  425. {  
  426.    if(Left_moto_stop)
  427.    {
  428.     if(pwm_val_left<=push_val_left)
  429.                {
  430.                      Left_moto_pwm=1;

  431.                    }
  432.         else
  433.                {
  434.                  Left_moto_pwm=0;

  435.                    }
  436.         if(pwm_val_left>=20)
  437.                pwm_val_left=0;
  438.    }
  439.    else   
  440.           {
  441.            Left_moto_pwm=0;

  442.                   }
  443. }
  444. /******************************************************************/
  445. /*                    右電機調速                                  */  
  446.    void pwm_out_right_moto(void)
  447. {
  448.   if(Right_moto_stop)
  449.    {
  450.     if(pwm_val_right<=push_val_right)
  451.               {
  452.                Right_moto_pwm=1;

  453.                    }
  454.         else
  455.               {
  456.                    Right_moto_pwm=0;

  457.                   }
  458.         if(pwm_val_right>=20)
  459.                pwm_val_right=0;
  460.    }
  461.    else   
  462.           {
  463.            Right_moto_pwm=0;

  464.               }
  465. }
  466.       
  467. /***************************************************/
  468. ///*TIMER0中斷服務子函數產生PWM信號*/
  469.          void timer0()interrupt 1   using 2
  470. {
  471.      TH0=0XFc;          //1Ms定時
  472.          TL0=0X18;
  473.          pwm_val_left++;
  474.          pwm_val_right++;
  475.          pwm_out_left_moto();
  476.          pwm_out_right_moto();
  477. }        

  478. /*********************************************************************/        







  479. #endif
復制代碼





回復

使用道具 舉報

ID:164602 發表于 2019-4-22 08:28 | 顯示全部樓層
我是用三個定時器的。
PWM用T2,發射超聲波用T1——因為要每隔一定時間發射超聲波測距,就是不讓現在發射的超聲波影響已經發射的超聲波,超聲波測距出錯用的T0。
所以沒有你說的問題。
其實看你的程序,為什么非要用一個定時器啊,加一個不就沒事兒了?
回復

使用道具 舉報

ID:432823 發表于 2019-4-22 14:32 | 顯示全部樓層
AT89x52有三個定時器可用,PWM用一個,測距用一個,串口通訊用一個互不干擾。
回復

使用道具 舉報

ID:465205 發表于 2019-4-22 16:21 | 顯示全部樓層
HC6800-ES-V2.0 發表于 2019-4-22 08:28
我是用三個定時器的。
PWM用T2,發射超聲波用T1——因為要每隔一定時間發射超聲波測距,就是不讓現在發射 ...

我用過兩個定時器,t1和t0,這個也會有干擾
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产乱码精品一区二区三区五月婷 | 性高湖久久久久久久久aaaaa | 日韩精品一区二区三区 | 91精产国品一二三区 | 亚洲+变态+欧美+另类+精品 | 国产成人精品999在线观看 | 91精品国产综合久久久久久蜜臀 | 中文天堂在线观看 | 成人av免费播放 | 国产精品久久久久久久久久久久久 | 国产午夜精品一区二区三区嫩草 | 九九热精品视频在线观看 | 伊人伊人 | 久色网| 欧美中文一区 | 久久不卡日韩美女 | jizz中国日本 | 欧美二区在线 | 国产亚洲一区二区三区 | jizz在线免费观看 | 欧美日韩综合 | 一区二区免费看 | 中文字幕欧美日韩一区 | 中文字字幕在线中文乱码范文 | 色婷婷亚洲一区二区三区 | 国产免费自拍 | 色婷婷综合久久久中字幕精品久久 | 91成人免费观看 | 国产精品99久久久久久久久久久久 | 麻豆changesxxx国产 | 久久合久久 | 97在线观看 | 97久久精品午夜一区二区 | 日本久久网 | 91影库| 黄色毛片视频 | 男女视频在线看 | 日韩视频在线免费观看 | 国产精品91网站 | 国产精品久久久精品 | 免费一区二区三区在线视频 |