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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1333|回復: 2
收起左側

注釋很詳細的單片機紅外循跡智能小車程序

[復制鏈接]
ID:1078833 發表于 2023-5-21 09:07 | 顯示全部樓層 |閱讀模式
  1. #include <reg52.h>                                  //包含51單片機相關的頭文件

  2. #define bint    unsigned int                          //重定義無符號整數類型
  3. #define char   unsigned char                         //重定義無符號字符類型

  4. char code  Roadshow[]={0x03,0x9F,0x25,0x0D,0x99,  //定義數碼管顯示數據
  5.                             0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9

  6. char code  Recitative[]={0x07,0x0A,0x1B,0x1F,0x0C,0x0D,0x0E,0x00,0x0F,0x19};

  7. char IRCOM[7];

  8. static unsigned int Led Flash;                         //定義閃動頻率計數變量

  9. unsigned char Run Flag=0;                              //定義運行標志位
  10. bit Enable Light=0;                                    //定義指示燈使能位
  11. /***********完成基本數據變量定義**************/
  12. bit S1State=P1^0;                                    //定義S1狀態標志位
  13. bit S2State=P1^1;                                    //定義S2狀態標志位
  14. bit B1State=P1^2;                                    //定義B1狀態標志位
  15. bit Instate=P1^3;                                    //定義IR狀態標志位
  16. bit Understate=P1^4;                               //定義運行停止標志位
  17. bit Attestation=P1^5;                                //定義Frontier狀態標志位
  18. bit Interstate=P1^6;                                //定義Lefter狀態標志位
  19. bit Rightist=P1^7;                               //定義Rightist狀態標志位
  20. /*************完成狀態指示燈定義*************/
  21. bit S1=P3^2;                                         //定義S1按鍵端口
  22. bit S2=P3^4;                                         //定義S2按鍵端口
  23. /*************完成按鍵端口的定義*************/      
  24. bit Left Led=P2^0;                                    //定義前方左側指示燈端口
  25. bit Right Led=P0^7;                                   //定義前方右側指示燈端口
  26. /*************完成前方指示燈端口定義*********/
  27. bit Lefter=P3^5;                                     //定義前方左側紅外探頭
  28. bit Right=P3^6;                                    //定義前主右側紅外探頭
  29. bit Frontier=P3^7;                                     //定義正前方紅外探頭
  30. /*************完成紅外探頭端口定義***********/
  31. bit M1A=P0^0;                                        //定義電機1正向端口
  32. bit M1B=P0^1;                                        //定義電機1反向端口
  33. bit M2A=P0^2;                                        //定義電機2正向端口
  34. bit M2B=P0^3;                                        //定義電機2反向端口
  35. /*************完成電機端口定義***************/
  36. bit B1=P0^4;                                         //定義話筒傳感器端口
  37. bit RL1=P0^5;                                        //定義光敏電阻端口
  38. bit SB1=P0^6;                                        //定義蜂鳴端口
  39. /*********完成話筒,光敏電阻,蜂鳴器.端口定義**/
  40. bit IRIN=P3^3;                                       //定義紅外接收端口
  41. /*********完成紅外接收端口的定義*************/
  42. #define Shortstop P2                                   //定義數碼管顯示端口

  43. extern void Control(char Archetype);                //聲明小車控制子程序

  44. void delay(unsigned char x)                           //0.14mS延時程序
  45. {
  46.   unsigned char i;                                    //定義臨時變量
  47.   while(x--)                                          //延時時間循環
  48.   {
  49.     for (i = 0; i<13; i++) {}                         //14mS延時
  50.   }
  51. }

  52. void Delay()                                          //定義延時子程序
  53. { bint Daytime=30000;                               //定義延時時間變量
  54.   while(Daytime--);                                 //開始進行延時循環
  55.   return;                                             //子程序返回
  56. }


  57. void Control(char Archetype)                        //定義小車控制子程序
  58. {
  59. M1A=0;                                               //將電機1正向電平置低
  60. M1B=0;                                               //將電機1反向電平置低
  61. M2A=0;                                               //將電機2正向電平置低
  62. M2B=0;                                               //將電機2反向電平置低
  63. Left Led=1;                                           //關閉前方左側指示燈
  64. Right Led=1;                                          //關閉前方右側指示燈
  65. Delay();                                             //將此狀態延時一段時間
  66. switch(Archetype)                                      //判斷小車控制指令類型
  67. {  case 1: //前進                                    //判斷是否是前進
  68.     { M1A=1;                                          //將電機1正向端口置高
  69.       M2A=1;                                          //將電機2正向端口置高
  70.       Shortstop=Roadshow[1];                        //數碼管顯示前進狀態
  71.       break;                                          //退出判斷
  72.     }
  73.     case 2: //后退                                    //判斷是否是后退
  74.     { M1B=1;                                          //將電機1反向端口置高
  75.       M2B=1;                                          //將電機2反向端口置高                                 
  76.       Shortstop=Roadshow[2];                        //數碼管顯示后退狀態
  77.       Right Led=0;                                     //將前方右側指示燈置低(亮)
  78.       Left Led=0;                                      //將前方左側指示燈置低(亮)
  79.       break;                                          //退出判斷
  80.     }
  81.     case 3: //左轉                                    //判斷是否是左轉
  82.     { M1B=1;                                          //將電機1反向端口置高
  83.       M2A=1;                                          //將電機2正向端口置高
  84.       Shortstop=Roadshow[3];                        //數碼管顯示左轉狀態
  85.       Left Led=0;                                      //將前方左側指示燈置低(亮)
  86.       break;                                          //退出判斷
  87.     }
  88.     case 4: //右轉                                    //判斷是否是右轉
  89.     { M1A=1;                                          //將電機1正向端口置高
  90.       M2B=1;                                          //將電機2反向端口置高
  91.       Shortstop=Roadshow[4];                        //數碼管顯示右轉狀態
  92.       Right Led=0;                                     //將前方右側指示燈置低(亮)
  93.       break;                                          //退出判斷
  94.     }
  95.     default:                                          //默認情況下的判斷
  96.     {
  97.      break;                                           //直接退出判斷
  98.     }
  99. }
  100. }

  101. void Biobreak() interrupt 4                           //定義串口通信子程序
  102. {unsigned char Recitative;                              //定義串口數據接收變量
  103. if(RI==1)                                            //判斷是否接收數據
  104. { Recitative=SBUF;                                     //將接收到的數據放入暫時變量
  105.    if(Recitative<10)                                    //判斷接收到的數據是否小于10
  106.    {
  107.     Shortstop=Roadshow[Recitative];                   //將接收到的數據通過數碼管顯示出來
  108.     Control(Recitative);                             //將串口數據置于小于狀態
  109.    }
  110.    SBUF=Recitative;                                     //向電腦返回當前接收到的數據
  111.    RI=0;                                              //清除接收中斷標志位
  112. }
  113. if(TI==1)                                            //判斷是否是發送中斷
  114. {
  115.    TI=0;                                              //清除發送中斷標志位
  116. }
  117. }

  118. void IR_IN() interrupt 2 using 0                      //定義INT2外部中斷函數
  119. {
  120.   unsigned char j,k,N=0;                              //定義臨時接收變量
  121.    
  122.   EX1 = 0;                                            //關閉外部中斷,防止再有信號到達   
  123.   delay(15);                                          //延時時間,進行紅外消抖
  124.   if (IRIN==1)                                        //判斷紅外信號是否消失
  125.   {  
  126.      EX1 =1;                                          //外部中斷開
  127.          return;                                          //返回
  128.   }
  129.                            
  130.   while (!IRIN)                                       //等IR變為高電平,跳過9ms的前導低電平信號。
  131.   {
  132.       delay(1);                                       //延時等待
  133.   }

  134.   for (j=0;j<4;j++)                                   //采集紅外遙控器數據
  135.   {
  136.     for (k=0;k<8;k++)                                 //分次采集8位數據
  137.     {
  138.        while (IRIN)                                   //等 IR 變為低電平,跳過4.5ms的前導高電平信號。
  139.        {
  140.          delay(1);                                    //延時等待
  141.        }
  142.       
  143.        while (!IRIN)                                  //等 IR 變為高電平
  144.        {
  145.          delay(1);                                    //延時等待
  146.        }
  147.    
  148.        while (IRIN)                                   //計算IR高電平時長
  149.        {
  150.          delay(1);                                    //延時等待
  151.          N++;                                         //計數器加加
  152.          if (N>=30)                                   //判斷計數器累加值
  153.              {
  154.            EX1=1;                                     //打開外部中斷功能
  155.                return;                                    //返回
  156.          }                  
  157.        }
  158.                                        
  159.       IRCOM[j]=IRCOM[j] >> 1;                         //進行數據位移操作并自動補零
  160.      
  161.       if (N>=8)                                       //判斷數據長度
  162.       {
  163.          IRCOM[j] = IRCOM[j] | 0x80;                  //數據最高位補1
  164.       }
  165.       N=0;                                            //清零位數計錄器
  166.     }
  167.   }
  168.    
  169.   if (IRCOM[2]!=~IRCOM[3])                            //判斷地址碼是否相同
  170.   {
  171.      EX1=1;                                           //打開外部中斷
  172.      return;                                          //返回
  173.   }

  174.   for(j=0;j<10;j++)                                   //循環進行鍵碼解析
  175.    {
  176.       if(IRCOM[2]==Recitative[j])                       //進行鍵位對應
  177.       {
  178.         P2=Roadshow[j];                            //數碼管顯示相應數碼
  179.       }
  180.    }
  181.    
  182.    switch(IRCOM[2])
  183.    {
  184.       case 0x1A:                                      //前進
  185.       {
  186.          Control(1);                               //小車前進
  187.          break;
  188.       }
  189.       case 0x05:                                      //后退
  190.       {
  191.          Control(2);                               //小車后退
  192.          break;
  193.       }
  194.       case 0x01:                                      //左轉
  195.       {
  196.          Control(3);                               //小車左轉
  197.          break;
  198.       }
  199.       case 0x03:                                      //右轉
  200.       {
  201.          Control(4);                               //小車右轉
  202.          break;
  203.       }
  204.       case 0x12:                                      //電源
  205.       {
  206.          Control(5);                               //停止
  207.          break;
  208.       }
  209.    
  210.    }
  211.    
  212.    EX1 = 1;                                           //外部中斷開
  213. }



  214. void main(void)                                       //主程序入口
  215. {
  216. bit Flagella=0;                                       //定義可執行位變量

  217. Led Flash=3000;                                       //對閃燈數據進行初始化
  218. TMOD=0x01;                                           //選擇定時器0為兩個16位定時器
  219. TH0=0xFF;                                            //對定時器進行計數值進行初始化
  220. TL0=0x49;                                            //同上,時間大約為25uS
  221. TR0=1;                                               //同意開始定時器0
  222. EX1=1;                                               //同意開啟外部中斷1
  223. IT1=1;                                               //設定外部中斷1為低邊緣觸發類型
  224. ET0=0;
  225. SCON=80;                                             //設置串口模式為8位數據
  226. TMOD=33;                                             //設置定時/計數器模式
  227. TH1=0xFD;                                            //給定時器1高八位初始化初值
  228. TL1=0xFD;                                            //給定時器1低八位初始化初值
  229. TR1=1;                                               //開啟定時器1
  230. ES=1;                                                //開啟串口通信功能
  231. REN=1;                                               //開啟接收中斷標志
  232. EA=1;                                                //總中斷開啟
  233. Control(1);                                       //將小車置于前進狀態
  234. Shortstop=Roadshow[0];                             //數碼管顯示數字0
  235. while(1)                                              //程序主循環
  236. {
  237.    
  238.     while(Led Flash--)                                 //閃燈總延時
  239.     {
  240.      if(RL1==0)                                       //判斷光敏電阻的狀態
  241.          { Right Led=1;                                    //將前方右側指示燈點亮
  242.            Left Led=1;                                     //將前方左側指示燈點亮
  243.          }
  244.          else                                             //在光敏電阻為不通的狀態下
  245.          {
  246.            Right Led=0;                                    //將前方右側指示燈熄滅
  247.            Left Led=0;                                     //將前方左側指示燈熄滅
  248.          }
  249.          if(IRIN==0)                                      //判斷延時期間是否有紅外信號輸入
  250.      {Flagella=1;                                      //將可執行標志位置1
  251.      }
  252.          if(S1==0)                                        //判斷是否有S1按下
  253.          {
  254.           Control(8);                                  //將小車置于停止狀態
  255.           Run Flag=1;                                      //改變小車運行狀態標志位
  256.           S1State=!S1State;                               //改變S1按鍵標志位
  257.           Soto Extrusion;                                   //跳轉到Extrusion標簽
  258.          }
  259.          if(S2==0)                                        //判斷是否有S2按下
  260.          {
  261.           Control(1);                                  //將小車置于前進狀態
  262.           Run Flag=0;                                      //改變小車運行狀態標志位
  263.           S2State=!S2State;                               //改變S2按鍵標志位
  264.           Soto Extrusion;                                   //跳轉到Extrusion標簽
  265.          }
  266.          Attestation=Frontier;                              //前方紅外指示燈顯示正前方紅外探頭狀態
  267.          Interstate=Lefter;                              //左側紅外指示燈顯示前方左側紅外探頭狀態
  268.          Rightist=Right;                            //右側紅外指示燈顯示前主右側紅外探頭狀態
  269.      if(Frontier==0  || Lefter==1 || Right==1)        //判斷正前方,前左側,前右側紅外探頭狀態
  270.      {Control(2);                                  //改變小車狀態為后退
  271.       SB1=!SB1;                                       //將蜂鳴器取反
  272.       Delay();                                        //調用延時子程序
  273.       SB1=!SB1;                                       //將蜂鳴器取反
  274.           Delay();                                        //調用延時子程序
  275.           SB1=!SB1;                                       //將蜂鳴器取反
  276.              Delay();                                        //調用延時子程序
  277.           SB1=!SB1;                                       //將蜂鳴器取反
  278.           Delay();                                        //調用延時子程序
  279.           SB1=!SB1;                                       //將蜂鳴器取反
  280.           Delay();                                        //調用延時子程序
  281.           SB1=!SB1;                                       //將蜂鳴器取反
  282.           Delay();                                        //調用延時子程序
  283.           SB1=!SB1;                                       //將蜂鳴器取反
  284.           Control(3);                                  //改變小車左轉狀態
  285.           Delay();                                        //調用延時子程序
  286.           SB1=!SB1;                                       //將蜂鳴器取反
  287.           Delay();                                        //調用延時子程序
  288.           SB1=!SB1;                                       //將蜂鳴器取反
  289.           Delay();                                        //調用延時子程序
  290.           SB1=!SB1;                                       //將蜂鳴器取反
  291.           Delay();                                        //調用延時子程序
  292.           SB1=!SB1;                                       //將蜂鳴器取反
  293.           Delay();                                        //調用延時子程序
  294.           SB1=!SB1;                                       //將蜂鳴器取反
  295.           Control(1);                                  //改變小車為前進狀態
  296.           SB1=1;                                          //關閉蜂鳴器聲音
  297.      }
  298.    
  299.     if(B1==0)                                         //判斷是否有話筒信號輸入
  300.     { if(Run Flag==0)                                  //判斷小車當前的運行標志位
  301.       { Control(8);                                //將小車置于停止狀態
  302.             Run Flag=1;                                    //改變小車運行標志位
  303.           }
  304.           else
  305.           { Control(1);                                //將小車置于前進狀態
  306.             Run Flag=0;                                    //改變小車運行標志位
  307.           }
  308.           B1State=!B1State;                               //將話筒信號指示燈取反
  309.     }
  310.   }
  311. Extrusion:                                              //跳轉標簽

  312.    Understate=!Understate;                        //改變小車運行停止狀態標志位
  313.                   
  314. }
  315. }

復制代碼


回復

使用道具 舉報

ID:161164 發表于 2023-5-22 10:46 | 顯示全部樓層
在中斷內延時,小白代碼
回復

使用道具 舉報

ID:1040201 發表于 2023-5-26 15:12 | 顯示全部樓層
為啥 在中斷中delay,中斷中要快進快出
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区二区中文字幕 | 国产成人在线一区二区 | 欧美精品久久久久久久久久 | 日韩精品成人av | 五月婷婷激情 | 久亚州在线播放 | 91av久久久 | 日韩欧美亚洲 | 中文字幕视频在线 | 日韩在线免费视频 | 一二三四在线视频观看社区 | 日韩精品在线观看网站 | 欧美黄色一级毛片 | 亚洲日韩中文字幕一区 | 天天干成人网 | 国产精品久久av | 成人免费看片 | 国产欧美在线视频 | 精品国产一区二区三区日日嗨 | 一级做受毛片免费大片 | 久久99精品久久 | 国产欧美精品区一区二区三区 | 夜夜久久 | 国产一区二区在线观看视频 | 国产精品美女一区二区 | 在线一区视频 | 精品久久久久久中文字幕 | 成人午夜免费网站 | 97精品久久 | 国产高清视频一区 | 国产欧美性成人精品午夜 | 亚洲精品乱码 | 国产日产精品一区二区三区四区 | 日本精品一区二区三区在线观看 | 伊人看片| 激情欧美一区二区三区中文字幕 | 久久国产精品视频免费看 | 国产精品久久久久久久久久不蜜臀 | 久在线视频播放免费视频 | 久久精品视频一区二区三区 | 久久成人免费视频 |