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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2821|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)超聲波避障小車(chē)外加紅外遙控仿真程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:150530 發(fā)表于 2022-12-29 21:57 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
超聲波避障小車(chē),紅外遙控小車(chē)上下左右運(yùn)動(dòng)仿真
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #include <reg52.h> //51頭文件
  2. #include <intrins.h>   //包含nop等系統(tǒng)函數(shù)
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. /*紅外*/
  6. #define JINGZHEN 12
  7. #define TIME0TH ((65536-100*JINGZHEN/12)&0xff00)>>8   //12M晶振機(jī)械周期0.25us,100us,紅外遙控
  8. #define TIME0TL ((65536-100*JINGZHEN/12)&0xff)
  9. unsigned char count0 = 50;
  10. unsigned char count1 = 0;
  11. sbit EN = P2^5;
  12. uint IrCount=0,Show=0,Cont=0;
  13. uchar IRDATBUF[32];
  14. uchar IrDat[5]={0,0,0,0,0};
  15. uchar IrStart=0,IrDatCount=0;
  16. code uchar  BitMsk[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,};
  17. /*電機(jī)驅(qū)動(dòng)IO定義*/
  18. sbit IN1 = P1^2; //為1 左電機(jī)反轉(zhuǎn)
  19. sbit IN2 = P1^3; //為1 左電機(jī)正轉(zhuǎn)
  20. sbit IN3 = P1^6; //為1 右電機(jī)正轉(zhuǎn)
  21. sbit IN4 = P1^7; //為1 右電機(jī)反轉(zhuǎn)
  22. sbit EN1 = P1^4; //為1 左電機(jī)使能
  23. sbit EN2 = P1^5; //為1 右電機(jī)使能
  24. /*按鍵定義*/
  25. sbit key_s2 = P3^0;       
  26. sbit beep = P2^3;//蜂鳴器
  27. sbit RX = P2^0;//ECHO超聲波模塊回響端
  28. sbit TX = P2^1;//TRIG超聲波模塊觸發(fā)端
  29. sbit LCM_RW = P3^6;     //定義LCD引腳
  30. sbit LCM_RS = P3^5;
  31. sbit LCM_E = P3^4;
  32. sbit servorControl =P2^7;  //舵機(jī)的控制引腳       

  33. #define lcddata  P0   //定義液晶屏數(shù)據(jù)口
  34. #define Busy    0x80   //用于檢測(cè)LCM狀態(tài)字中的Busy標(biāo)識(shí)
  35. #define left_motor_en                EN1 = 1        //左電機(jī)使能
  36. #define right_motor_en                EN2 = 1        //右電機(jī)使能
  37. #define left_motor_stops        IN1 = 0, IN2 = 0//左電機(jī)停止
  38. #define right_motor_stops        IN3 = 0, IN4 = 0//右電機(jī)停止
  39. #define left_motor_go                IN1 = 0, IN2 = 1//左電機(jī)正傳
  40. #define left_motor_back                IN1 = 1, IN2 = 0//左電機(jī)反轉(zhuǎn)
  41. #define right_motor_go                IN3 = 1, IN4 = 0//右電機(jī)正傳
  42. #define right_motor_back        IN3 = 0, IN4 = 1//右電機(jī)反轉(zhuǎn)

  43. unsigned char pwm_left_val = 38;//左電機(jī)占空比值 取值范圍0-80,0最快
  44. unsigned char pwm_right_val = 44;//右電機(jī)
  45. unsigned char pwm_t;//周期
  46. unsigned int  time = 0;//傳輸時(shí)間
  47. unsigned long S = 0;//距離
  48. bit  flag = 0;//超出測(cè)量范圍標(biāo)志位
  49. bit flag1=0;//舵機(jī)模塊計(jì)數(shù)標(biāo)志
  50. uchar control=5; //控制舵機(jī)轉(zhuǎn)角
  51. uchar servorTime=0;        //控制舵機(jī)脈沖占空比
  52. uchar lFlag=0;//左方向是否有障礙的標(biāo)志
  53. uchar rFlag=0;//右方向是否有障礙的標(biāo)志
  54. uint ldistance=0,rdistance=0;//左右邊長(zhǎng)度

  55. unsigned char code tishi[] ="the distance is:";//LCD1602顯示格式
  56. unsigned char code ASCII[13] = "0123456789.cm";
  57. unsigned char code table[]=" howfar:000.0cm";
  58. unsigned char code table1[]=" Out of range   ";
  59. unsigned char disbuff[4] = { 0,0,0,0};//距離顯示緩存

  60. bit flagg=0; //切換正常避障模式和遙控模式
  61. void delay(unsigned int z)//毫秒級(jí)延時(shí)
  62. {
  63.         unsigned int x,y;
  64.         for(x = z; x > 0; x--)
  65.                 for(y = 114; y > 0 ; y--);
  66. }

  67. void Delay10us(unsigned char i)            //10us延時(shí)函數(shù) 啟動(dòng)超聲波模塊時(shí)使用
  68. {
  69.    unsigned char j;
  70.         do{
  71.                 j = 10;
  72.                 do{
  73.                         _nop_();
  74.                 }while(--j);
  75.         }while(--i);
  76. }

  77. /************************************LCD1602液晶屏驅(qū)動(dòng)函數(shù)************************************************/
  78. /******************讀狀態(tài)**********************/
  79. unsigned char readstatus(void)
  80. {
  81.         lcddata = 0xFF;
  82.         LCM_RS = 0;
  83.         Delay10us(1);
  84.         LCM_RW = 1;
  85.         Delay10us(1);
  86.         do{
  87.         LCM_E = 0;
  88.         Delay10us(1);
  89.         LCM_E = 0;
  90.         Delay10us(1);
  91.         LCM_E = 1;
  92.         Delay10us(1);
  93.         }
  94.         while (lcddata & Busy); //檢測(cè)忙信號(hào)
  95.         return(lcddata);
  96. }

  97. /****************寫(xiě)數(shù)據(jù)************************/
  98. void writedata(unsigned char datas)
  99. {
  100.         readstatus(); //檢測(cè)忙
  101.         lcddata = datas;
  102.         LCM_RS = 1;
  103.         Delay10us(1);
  104.         LCM_RW = 0;
  105.         Delay10us(1);
  106.         LCM_E = 0; //若晶振速度太高可以在這后加小的延時(shí)
  107.         Delay10us(1);
  108.         LCM_E = 0; //延時(shí)
  109.         Delay10us(1);
  110.         LCM_E = 1;
  111.         Delay10us(1);
  112. }

  113. /***************寫(xiě)指令*************************/
  114. void writecom(unsigned char WCLCM,BuysC) //BuysC為0時(shí)忽略忙檢測(cè)
  115. {
  116.         if (BuysC) readstatus(); //根據(jù)需要檢測(cè)忙
  117.     lcddata = WCLCM;
  118.         LCM_RS = 0;
  119.         Delay10us(1);
  120.         LCM_RW = 0;       
  121.         Delay10us(1);
  122.         LCM_E = 0;
  123.         Delay10us(1);
  124.         LCM_E = 0;
  125.         Delay10us(1);
  126.         LCM_E = 1;
  127.         Delay10us(1);
  128. }



  129. /*******************初始化******************/
  130. void lcdinition(void)
  131. {
  132.     lcddata = 0;
  133.         writecom(0x38,0); //三次顯示模式設(shè)置,不檢測(cè)忙信號(hào)
  134.         delay(5);
  135.         writecom(0x38,0);
  136.         delay(5);
  137.         writecom(0x38,0);
  138.         delay(5);

  139.         writecom(0x38,1); //顯示模式設(shè)置,開(kāi)始要求每次檢測(cè)忙信號(hào)
  140.         writecom(0x08,1); //關(guān)閉顯示
  141.         writecom(0x01,1); //顯示清屏
  142.         writecom(0x06,1); // 顯示光標(biāo)移動(dòng)設(shè)置
  143.         writecom(0x0c,1); // 顯示開(kāi)及光標(biāo)設(shè)置
  144. }

  145. /*******************按指定位置顯示一個(gè)字符*****/
  146. void DisplayOneChar(unsigned char x, unsigned char y, unsigned char data2)
  147. {
  148.         y &= 0x1;
  149.         x&= 0xF; //限制X不能大于15,Y不能大于1
  150.         if (y) x |= 0x40; //當(dāng)要顯示第二行時(shí)地址碼+0x40;
  151.         x |= 0x80; //算出指令碼
  152.         writecom(x, 1); //發(fā)命令字
  153.         writedata(data2); //發(fā)數(shù)據(jù)
  154. }

  155. /******************按指定位置顯示一串字符*******/
  156. void DisplayListChar(unsigned char x, unsigned char y, unsigned char code *DData)
  157. {
  158.   unsigned char ListLength;
  159.   ListLength = 0;
  160.         y &= 0x1;
  161.         x &= 0xF; //不能大于15,y不能大于1
  162.         while (DData[ListLength]>0x19) //若到達(dá)字串尾則退出
  163.                 {
  164.                         if (x <= 0xF) //坐標(biāo)應(yīng)小于0xF
  165.                                 {
  166.                                         DisplayOneChar(x, y, DData[ListLength]); //顯示單個(gè)字符
  167.                                         ListLength++;
  168.                                         x++;
  169.                                 }
  170.                 }
  171. }


  172. /***************************************************************************/
  173.        
  174. /*小車(chē)前進(jìn)*/
  175. void forward(uint m)
  176. {
  177.         left_motor_go; //左電機(jī)前進(jìn)
  178.         right_motor_go; //右電機(jī)前進(jìn)
  179.         delay(m);
  180. }

  181. /*PWM控制使能 小車(chē)后退*/
  182. void backward(uint m)
  183. {
  184.         left_motor_back; //左電機(jī)后退
  185.         right_motor_back; //右電機(jī)后退       
  186.         delay(m);
  187. }

  188. /*小車(chē)停止*/
  189. void stop(uint m)
  190. {
  191.         right_motor_stops;//右電機(jī)停止
  192.         left_motor_stops; //左電機(jī)停止
  193.         delay(m);       
  194. }

  195. /*小車(chē)左轉(zhuǎn)*/
  196. void left_rapidly(uint m)
  197. {
  198.         left_motor_back;
  199.         right_motor_go;
  200.         delay(m);       
  201. }
  202. /*小車(chē)右轉(zhuǎn)*/
  203. void right_rapidly(uint m)
  204. {
  205.         right_motor_back;
  206.         left_motor_go;
  207.         delay(m);       
  208. }

  209. /*判斷S2是否被按下*/
  210. void keyscan()
  211. {
  212.         for(;;)        //死循環(huán)
  213.         {
  214.                 if(key_s2 == 0)// 實(shí)時(shí)檢測(cè)S2按鍵是否被按下
  215.                 {
  216.                         delay(5); //軟件消抖
  217.                         if(key_s2 == 0)//再檢測(cè)S2是否被按下
  218.                         {
  219.                                 while(!key_s2);//松手檢測(cè)
  220.                                 beep = 0;        //使能有源蜂鳴器
  221.                                 delay(200);//200毫秒延時(shí)
  222.                                 beep = 1;        //關(guān)閉有源蜂鳴器
  223.                                 break;                //退出FOR死循環(huán)
  224.                         }
  225.                 }
  226.         }       
  227. }

  228. /*LCD顯示所測(cè)結(jié)果*/
  229. void xianshi( )
  230. {
  231.           if((S>=4000)||flag==1) //超出測(cè)量范圍
  232.         {         
  233.                 flag=0;
  234.                 DisplayListChar(0, 1, table1);
  235.         }
  236.         else
  237.         {
  238.                 disbuff[0]=S/1000; //距離數(shù)值千位
  239.                 disbuff[1]=S%1000/100;//距離數(shù)值百位
  240.                 disbuff[2]=S%100/10;//距離數(shù)值十位
  241.                 disbuff[3]=S%10; //距離數(shù)值個(gè)位
  242.          DisplayListChar(0, 1, table);
  243.          DisplayOneChar(9, 1, ASCII[disbuff[0]]);
  244.          DisplayOneChar(10, 1, ASCII[disbuff[1]]);       
  245.          DisplayOneChar(11, 1, ASCII[disbuff[2]]);
  246. DisplayOneChar(12, 1, ASCII[10]);                       
  247.          DisplayOneChar(13, 1, ASCII[disbuff[3]]);
  248.                 DisplayOneChar(14, 1, ASCII[11]);
  249.                 DisplayOneChar(15, 1, ASCII[12]);
  250.         }
  251. }
  252. void  qidongceju()                           //啟動(dòng)超聲波模塊
  253. {
  254.           TX=1;                                      //啟動(dòng)一次模塊
  255.       Delay10us(2);                                 //延時(shí)20us
  256.           TX=0;
  257. }
  258. /*計(jì)算超聲波所測(cè)距離并顯示*/
  259. uint ceju()
  260. {
  261.         TH0=0;
  262.         TL0=0;
  263.         qidongceju();
  264.         while(!RX);                //當(dāng)RX(ECHO信號(hào)回響)為零時(shí)等待
  265.         TR0=1;                            //開(kāi)啟計(jì)數(shù)
  266.         while(RX);                        //當(dāng)RX為1計(jì)數(shù)并等待
  267.         TR0=0;                                //關(guān)閉計(jì)數(shù)
  268.         time=TH0*256+TL0;
  269.         S=(float)(time*1.085)*0.16; //單位為MM
  270.         if(S<=400)
  271.         return 1;        //距離小于400mm時(shí)返回1
  272.         else
  273.         return 0;
  274. }
  275. void duoji(uchar m)         //舵機(jī)轉(zhuǎn)向定義
  276. {
  277.     control=m;
  278.     servorTime=0;
  279.     flag1=1;
  280.     delay(100);
  281.     flag1=0;
  282.         delay(100);        //延時(shí),降低轉(zhuǎn)向速度
  283. }

  284. /*超聲波避障*/
  285. void avoid()
  286. {
  287. if(S < 400)//設(shè)置避障距離 ,單位毫米        剎車(chē)距離
  288. {
  289.         beep = 0;//使能蜂鳴器
  290.         stop();//停車(chē)
  291.     do{
  292.                  xianshi();  
  293.              duoji(18); //使舵機(jī)向左擺動(dòng)                                  
  294.                  lFlag=ceju();
  295.                  xianshi();
  296.                  ldistance=S;
  297.                  duoji(8);       //使舵機(jī)向右擺動(dòng)
  298.                  rFlag=ceju();
  299.                  xianshi();
  300.                  rdistance=S;
  301.                  duoji(13);//控制舵機(jī)使超聲波模塊正對(duì)前方
  302.                  backward(200);
  303.                  if(rdistance>ldistance)
  304.                 {
  305.                 right_rapidly(10);
  306.                 }
  307.                 if(ldistance>rdistance)
  308.                 {
  309.                 left_rapidly(10);
  310.                 }
  311.         }while(lFlag==1&&rFlag==1);//當(dāng)前方、左右側(cè)都有障礙物
  312.         if(lFlag==0&&rFlag==1) //左側(cè)沒(méi)有障礙物,右側(cè)有
  313.         {
  314.         left_rapidly(80);         
  315.         }
  316.         else if(rFlag==0&&lFlag==1)//右側(cè)沒(méi)有障礙物,左側(cè)有
  317.         {
  318.         right_rapidly(80);
  319.         }
  320.          else if(rFlag==0&&lFlag==0)//兩側(cè)都沒(méi)有障礙物,默認(rèn)向前走
  321.         {
  322.         forward();
  323.         }
  324.   }
  325.   else{
  326.               forward();
  327.                 beep=1;
  328.       }
  329. }
  330. void inition1()
  331. {
  332.     TMOD = 0x21;//定時(shí)器1工作模式2,8位自動(dòng)重裝;
  333.     TH0        = 0;//定時(shí)器0工作模式1,16位定時(shí)用于產(chǎn)生PWM,T0用測(cè)ECH0脈沖長(zhǎng)度
  334.     TL0        = 0;//T0,16位定時(shí)計(jì)數(shù)用于記錄ECHO高電平時(shí)間  
  335.         ET0 = 1;
  336.         TH1 = 155;
  337.         TL1 = 155; //100HZ T1
  338.     ET1        = 1;
  339.         TR1 = 1;
  340.         EA  = 1;
  341. }
  342. void inition2()
  343. {
  344.    TMOD  |= 0x011;
  345.         TH0 = TIME0TH;
  346.         TL0 = TIME0TL;
  347.         ET0=1;
  348.         TR0=1;                               
  349.         ET1=1;
  350.         TR1=1;                               
  351.         IT0 = 1;                                //下降沿
  352.         EX0 = 1;
  353.         EA=1;
  354. }
  355. void scan()
  356. {
  357.         if(Show==1)
  358.                 {
  359.                         Show=0;
  360.                         Cont=0;
  361.                         switch (IrDat[3])
  362.                         {
  363.                       case 0x12://go
  364.                                     forward(1);
  365.                                   break;
  366.                       case 0x0b://back
  367.                                     backward(1);
  368.                                   break;
  369.                           case 0x1a://right
  370.                                     right_rapidly(1);
  371.                                   break;
  372.                           case 0x1e://left
  373.                                   right_rapidly(1);
  374.                                   break;
  375.                           
  376.                         }
  377.                 }       
  378. }
  379. void main()
  380. {
  381.         lcdinition();
  382.         delay(5);
  383.         DisplayListChar(0, 0, tishi);//1602第一行顯示tishi數(shù)組內(nèi)容
  384.         DisplayListChar(0, 1, table);//1602第二行顯示table數(shù)組內(nèi)容
  385.         keyscan();//等待按下S2啟動(dòng)小車(chē)       
  386.         TX = 0;
  387.         if(flagg==0)
  388.         inition1();
  389.         else
  390.         {
  391.          inition2();
  392.         }

  393.         while(1)
  394.         {
  395.          if(flagg==0){               
  396.       duoji(13);//控制舵機(jī)使超聲波模塊正對(duì)前方
  397.            ceju();
  398.            xianshi();         
  399.        avoid();  }
  400.           else
  401.           {
  402.                   scan();
  403.           }             
  404.         }
  405. }
  406. /*定時(shí)器1中斷輸出PWM信號(hào)*/
  407. ……………………

  408. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

Keil代碼與Proteus8.13仿真下載:
紅外超聲波舵機(jī)避障小車(chē)仿真和代碼.zip (145.18 KB, 下載次數(shù): 90)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:316613 發(fā)表于 2024-3-30 13:27 | 只看該作者
電機(jī)不轉(zhuǎn)噢 仿真
回復(fù)

使用道具 舉報(bào)

板凳
ID:1140513 發(fā)表于 2024-12-19 18:26 | 只看該作者
發(fā)表于 2024-3-30 13:27
電機(jī)不轉(zhuǎn)噢 仿真

修復(fù)好了嗎
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 在线欧美小视频 | 中文字幕高清 | 成人亚洲 | av在线免费不卡 | 亚洲精品乱码久久久久久9色 | 免费在线观看一区二区三区 | 成人免费看黄 | 午夜丰满少妇一级毛片 | 国产一区中文字幕 | 国产欧美一区二区三区在线播放 | 欧美日韩在线免费观看 | 亚洲精品一区二区网址 | 一区二区中文字幕 | 国产成人免费视频 | 成人免费小视频 | 国产成人精品一区二 | 91精品国产高清一区二区三区 | 中文字幕第二区 | 中文字幕丁香5月 | 天天躁日日躁性色aⅴ电影 免费在线观看成年人视频 国产欧美精品 | a在线观看免费 | 日韩亚洲视频 | 亚洲欧美日韩国产综合 | 欧美日韩最新 | 特级特黄特色的免费大片 | 国产成人精品综合 | 啪啪av | 激情福利视频 | 一级毛片免费看 | 亚洲综合无码一区二区 | 国产日韩一区二区三区 | 91久久精品国产 | 成人av网站在线观看 | 我爱操 | 午夜a级理论片915影院 | jizz亚洲人 | 中文字幕一区二区三区四区 | 青青久久| a级黄色网| 欧美a区 | 久久国产婷婷国产香蕉 |