找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1369|回復(fù): 2
收起左側(cè)

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

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

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

  4. char code  Roadshow[]={0x03,0x9F,0x25,0x0D,0x99,  //定義數(shù)碼管顯示數(shù)據(jù)
  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;                         //定義閃動頻率計數(shù)變量

  9. unsigned char Run Flag=0;                              //定義運行標(biāo)志位
  10. bit Enable Light=0;                                    //定義指示燈使能位
  11. /***********完成基本數(shù)據(jù)變量定義**************/
  12. bit S1State=P1^0;                                    //定義S1狀態(tài)標(biāo)志位
  13. bit S2State=P1^1;                                    //定義S2狀態(tài)標(biāo)志位
  14. bit B1State=P1^2;                                    //定義B1狀態(tài)標(biāo)志位
  15. bit Instate=P1^3;                                    //定義IR狀態(tài)標(biāo)志位
  16. bit Understate=P1^4;                               //定義運行停止標(biāo)志位
  17. bit Attestation=P1^5;                                //定義Frontier狀態(tài)標(biāo)志位
  18. bit Interstate=P1^6;                                //定義Lefter狀態(tài)標(biāo)志位
  19. bit Rightist=P1^7;                               //定義Rightist狀態(tài)標(biāo)志位
  20. /*************完成狀態(tài)指示燈定義*************/
  21. bit S1=P3^2;                                         //定義S1按鍵端口
  22. bit S2=P3^4;                                         //定義S2按鍵端口
  23. /*************完成按鍵端口的定義*************/      
  24. bit Left Led=P2^0;                                    //定義前方左側(cè)指示燈端口
  25. bit Right Led=P0^7;                                   //定義前方右側(cè)指示燈端口
  26. /*************完成前方指示燈端口定義*********/
  27. bit Lefter=P3^5;                                     //定義前方左側(cè)紅外探頭
  28. bit Right=P3^6;                                    //定義前主右側(cè)紅外探頭
  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                                   //定義數(shù)碼管顯示端口

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

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

  52. void Delay()                                          //定義延時子程序
  53. { bint Daytime=30000;                               //定義延時時間變量
  54.   while(Daytime--);                                 //開始進(jìn)行延時循環(huán)
  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;                                           //關(guān)閉前方左側(cè)指示燈
  64. Right Led=1;                                          //關(guān)閉前方右側(cè)指示燈
  65. Delay();                                             //將此狀態(tài)延時一段時間
  66. switch(Archetype)                                      //判斷小車控制指令類型
  67. {  case 1: //前進(jìn)                                    //判斷是否是前進(jìn)
  68.     { M1A=1;                                          //將電機1正向端口置高
  69.       M2A=1;                                          //將電機2正向端口置高
  70.       Shortstop=Roadshow[1];                        //數(shù)碼管顯示前進(jìn)狀態(tài)
  71.       break;                                          //退出判斷
  72.     }
  73.     case 2: //后退                                    //判斷是否是后退
  74.     { M1B=1;                                          //將電機1反向端口置高
  75.       M2B=1;                                          //將電機2反向端口置高                                 
  76.       Shortstop=Roadshow[2];                        //數(shù)碼管顯示后退狀態(tài)
  77.       Right Led=0;                                     //將前方右側(cè)指示燈置低(亮)
  78.       Left Led=0;                                      //將前方左側(cè)指示燈置低(亮)
  79.       break;                                          //退出判斷
  80.     }
  81.     case 3: //左轉(zhuǎn)                                    //判斷是否是左轉(zhuǎn)
  82.     { M1B=1;                                          //將電機1反向端口置高
  83.       M2A=1;                                          //將電機2正向端口置高
  84.       Shortstop=Roadshow[3];                        //數(shù)碼管顯示左轉(zhuǎn)狀態(tài)
  85.       Left Led=0;                                      //將前方左側(cè)指示燈置低(亮)
  86.       break;                                          //退出判斷
  87.     }
  88.     case 4: //右轉(zhuǎn)                                    //判斷是否是右轉(zhuǎn)
  89.     { M1A=1;                                          //將電機1正向端口置高
  90.       M2B=1;                                          //將電機2反向端口置高
  91.       Shortstop=Roadshow[4];                        //數(shù)碼管顯示右轉(zhuǎn)狀態(tài)
  92.       Right Led=0;                                     //將前方右側(cè)指示燈置低(亮)
  93.       break;                                          //退出判斷
  94.     }
  95.     default:                                          //默認(rèn)情況下的判斷
  96.     {
  97.      break;                                           //直接退出判斷
  98.     }
  99. }
  100. }

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

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

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

  174.   for(j=0;j<10;j++)                                   //循環(huán)進(jìn)行鍵碼解析
  175.    {
  176.       if(IRCOM[2]==Recitative[j])                       //進(jìn)行鍵位對應(yīng)
  177.       {
  178.         P2=Roadshow[j];                            //數(shù)碼管顯示相應(yīng)數(shù)碼
  179.       }
  180.    }
  181.    
  182.    switch(IRCOM[2])
  183.    {
  184.       case 0x1A:                                      //前進(jìn)
  185.       {
  186.          Control(1);                               //小車前進(jìn)
  187.          break;
  188.       }
  189.       case 0x05:                                      //后退
  190.       {
  191.          Control(2);                               //小車后退
  192.          break;
  193.       }
  194.       case 0x01:                                      //左轉(zhuǎn)
  195.       {
  196.          Control(3);                               //小車左轉(zhuǎn)
  197.          break;
  198.       }
  199.       case 0x03:                                      //右轉(zhuǎn)
  200.       {
  201.          Control(4);                               //小車右轉(zhuǎn)
  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;                                       //定義可執(zhí)行位變量

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

  312.    Understate=!Understate;                        //改變小車運行停止?fàn)顟B(tài)標(biāo)志位
  313.                   
  314. }
  315. }

復(fù)制代碼


回復(fù)

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表