找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2002|回复: 0
收起左侧

单片机循迹、避障、遥控综合小车程序

[复制链接]
ID:560735 发表于 2019-6-24 10:58 | 显示全部楼层 |阅读模式
智能小车可以完成循迹避障等功能

单片机源程序如下:
  1.     #include<AT89x51.H>
  2.     #include<intrins.h>
  3.         #include<HJ-4WD_PWM.H>                  //定义函数
  4.     #define Left_1_led        P3_7         //左循迹   
  5.        
  6.     #define Right_1_led       P3_6         //右循迹
  7.        
  8.     #define LeftIRBZ          P3_5         //左避障          
  9.        
  10.         #define RightIRBZ         P3_4         //右避障

  11.         //#define Left_led                  p2_2   //左光传感器
  12.        
  13.         //#define Right_led         p2_4         //右光传感器   

  14. sbit SB1=P2^3;                            //定义蜂鸣器
  15. sbit IRIN=P3^3;                                       //定义红外接收端口

  16. unsigned char code  LedShowData[]={0x03,0x9F,0x25,0x0D,0x99,  //定义数码管显示数据
  17.                                    0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9
  18. unsigned char code  RecvData[]={0x19,0x46,0x15,0x43,0x44,0x40,0x0D,0x0E,0x00,0x0F};
  19. unsigned char IRCOM[7];

  20. #define ShowPort P0                                   //定义数码管显示端口
  21. unsigned char temp = 1;

  22. void Delay1ms(unsigned int i)
  23. {
  24. unsigned char j,k;
  25. do{
  26.   j = 10;
  27.   do{
  28.    k = 50;
  29.    do{
  30.     _nop_();
  31.    }while(--k);     
  32.   }while(--j);
  33. }while(--i);
  34. }

  35. void delay_nus(unsigned int i)  //延时:i>=12 ,i的最小延时单12 us
  36. {
  37.   i=i/10;
  38.   while(--i);
  39. }   
  40. void delay_nms(unsigned int n)  //延时n ms
  41. {
  42.   n=n+1;
  43.   while(--n)  
  44.   delay_nus(900);         //延时 1ms
  45.   
  46. }  

  47. void delayms(unsigned char x)                         //0.14mS延时
  48. {
  49.   unsigned char i;                                 
  50.   while(x--)                                          
  51.   {
  52.     for (i = 0; i<13; i++) {}                         //14mS延时
  53.   }
  54. }

  55. void Delay()                                          //定义延时子程序
  56. {
  57.   unsigned int DelayTime=30000;                     
  58.   while(DelayTime--);                                 //开始进行延时循环
  59.   return;                                            
  60. }

  61. void ControlCar_yaokong(unsigned char ConType)    //定义电机控制子程序       
  62. {

  63.   stop();
  64. switch(ConType)                          //判断设定电机形式
  65. {
  66.   case 1:  //前进                         //判断是否选择形式1
  67.   {
  68.     stop();                                                     
  69.         Delay1ms(150);
  70. //        LeftLed = 0 ;
  71.         run();
  72.     break;
  73.   }
  74.   case 2: //后退                          //判断是否选择形式2
  75.   {
  76.     stop();                                                                     
  77.     Delay1ms(150);
  78.   //  LeftLed = 1 ;          
  79.         back();                                 //M2电机反转
  80.     break;
  81.   }
  82.   case 3: //右转                          //判断是否选择形式3
  83.   {
  84.      stop();                                                                  
  85.          Delay1ms(150);
  86.          rightrun();                                //M2电机正转
  87.          break;
  88.   }
  89.   case 4: //左转                          //判断是否选择形式4
  90.   {
  91.      stop();                                                                  
  92.          Delay1ms(150);
  93.      leftrun();                                  //M1电机正转  M2电机反转
  94.          break;
  95.   }
  96.   case 8: //停止                          //判断是否选择形式8
  97.   {
  98.     stop();
  99.         break;                                //退出当前选择
  100.   }
  101. }
  102. }
  103. void Robot_Avoidance()                   //避障子程序
  104. {
  105.             
  106.               if(LeftIRBZ==1&&RightIRBZ ==1)          //LeftIRBZ RightIRBZ

  107.                     {         
  108.                       run();
  109.               delay_nms (10);
  110.                            SB1=1;
  111.                           }
  112.                           else
  113.                          {                          
  114.                                       if(LeftIRBZ==1&&RightIRBZ ==0)            //右边检测到红外信号
  115.                                   {
  116.                                           rightrun();                          
  117.                      delay_nms (300);                                          

  118.                              }
  119.                           
  120.                                            if(RightIRBZ ==1&&LeftIRBZ==0)               
  121.                                   {          
  122.                                      
  123.                                           leftrun();                     
  124.                      delay_nms (300);                                          

  125.                                   }
  126.                                   if(RightIRBZ==0&&LeftIRBZ==0)                //两边传感器同时检测到红外
  127.                                   {          
  128.                                      SB1=0;
  129.                                          stop();                     //停止
  130.                      delay_nms (300);                       
  131.                                          back();                         //调用电机后退函数
  132.                                          delay_nms (300);                //后退50毫秒
  133.                                          rightrun();                     //调用电机右转函数
  134.                                         delay_nms (400);
  135.                                   }
  136.                         }
  137.        
  138.                         run();
  139.                   
  140. }

  141. void Robot_Traction()                     //循迹子程序
  142. {
  143.   
  144.    //SB1=1;
  145.    if(Left_1_led  == 0 && Right_1_led == 0)    //三个红外检测到黑线,就前进         Left_1_led           Right_1_led
  146.    {
  147.       run();                     //左侧没有信号时,开始向右转一定的角度
  148.       delay_nms (10);
  149.           SB1=0;
  150.    }
  151.    
  152.    else if(Left_1_led  == 0 && Right_1_led == 1)
  153.    {
  154.       rightrun();                       //右侧检测到黑线,开始向右转一定的角度
  155.       delay_nms (10);
  156.    }

  157.    else if(Left_1_led  == 1 &&  Right_1_led == 0)
  158.    {
  159.       leftrun();                         //左侧检测到黑线,开始向左转一定的角度
  160.           
  161.       delay_nms (10);
  162.    }
  163.    else if(Left_1_led  == 1 &&  Right_1_led == 1)
  164.    {
  165.       SB1=1;
  166.           stop();                         //左侧检测到黑线,开始向左转一定的角度
  167.           
  168.       delay_nms (10);
  169.    }
  170.      
  171. }

  172. //----------红外遥控-------------------------------------------------------------
  173. void IR_IN() interrupt 2 using 0                      //定义INT2外部中断函数
  174. {
  175.   unsigned char j,k,N=0;                              //定义临时接收变量
  176.   
  177.   EX1 = 0;                                            //关闭外部中断,防止再有信号到达   
  178.   delayms(15);                                        //延时时间,进行红外消抖
  179.   if (IRIN==1)                                        //判断红外信号是否消失
  180.   {  
  181.      EX1 =1;                                          //外部中断开
  182.          return;                                          //返回
  183.   }
  184.                            
  185.   while (!IRIN)                                       //等IR变为高电平,跳过9ms的前导低电平信号。
  186.   {
  187.       delayms(1);                                     //延时等待
  188.   }

  189.   for (j=0;j<4;j++)                                   //采集红外遥控器数据
  190.   {
  191.     for (k=0;k<8;k++)                                 //分次采集8位数据
  192.     {
  193.        while (IRIN)                                   //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
  194.        {
  195.          delayms(1);                                  //延时等待
  196.        }
  197.       
  198.        while (!IRIN)                                  //等 IR 变为高电平
  199.        {
  200.          delayms(1);                                  //延时等待
  201.        }
  202.    
  203.        while (IRIN)                                   //计算IR高电平时长
  204.        {
  205.          delayms(1);                                  //延时等待
  206.          N++;                                         //计数器加加
  207.          if (N>=30)                                   //判断计数器累加值
  208.              {
  209.            EX1=1;                                     //打开外部中断功能
  210.                return;                                    //返回
  211.          }                  
  212.        }
  213.                                        
  214.       IRCOM[j]=IRCOM[j] >> 1;                         //进行数据位移操作并自动补零
  215.      
  216.       if (N>=8)                                       //判断数据长度
  217.       {
  218.          IRCOM[j] = IRCOM[j] | 0x80;                  //数据最高位补1
  219.       }
  220.       N=0;                                            //清零位数计录器
  221.     }
  222.   }
  223.    
  224.   if (IRCOM[2]!=~IRCOM[3])                            //判断地址码是否相同
  225.   {
  226.      EX1=1;                                           //打开外部中断
  227.      return;                                          //返回
  228.   }

  229.   for(j=0;j<10;j++)                                   //循环进行键码解析
  230.    {
  231.       if(IRCOM[2]==RecvData[j])                       //进行键位对应
  232.       {
  233.        // ControlCar(j);
  234.                 ControlCar_yaokong(j);                               //数码管显示相应数码
  235.       }
  236.    }
  237.    EX1 = 1;                                           //外部中断开
  238. }
  239. //----------寻光子程序-------------------------------------------------------------
  240. void Robot_Lightseek()
  241. {       

  242.         //unsigned char i;
  243.     P1=0X00; //关电车电机       

  244.                          /*TMOD=0X01;
  245.                 TH0= 0XFc;                  //1ms定时
  246.                  TL0= 0X18;
  247.                    TR0= 1;
  248.                 ET0= 1;
  249.                 EA = 1;        */             //开总中断
  250.         while(1)        //无限循环
  251.         {
  252.          
  253.                          //有信号为0  没有信号为1

  254.               if(Left_led==0&&Right_led==0)

  255.                           run();         //调用前进函数

  256.                           else
  257.                          {                          
  258.                                       if(Left_led==1&&Right_led==0)            //右边检测到红外信号
  259.                                   {
  260.                                            rightrun();         //调用小车右转函数
  261.                                           delay(40);

  262.                              }
  263.                           
  264.                                            if(Right_led==1&&Left_led==0)                //左边检测到红外信号
  265.                                   {          
  266.                                      
  267.                                           leftrun();          //调用小车左转函数
  268.                                           delay(40);

  269.                                   }
  270.                                                                   if(Right_led==1&&Left_led==1)                //两边传感器没有检测到光
  271.                                   {          
  272.                                     stop();                    //调用电机停止函数
  273.                                         delay(40);
  274.                                   }
  275.                         }         
  276.          }
  277. }

  278. //------------------------------超声波避障、测距---------------------------------------------------------



  279. //-------------------------------------------------------------------------------------------------------
  280. void main()                               //主程序入口
  281. {
  282.   TMOD=0X01;
  283.   TH0= 0XFc;                  //1ms定时
  284.   TL0= 0X18;
  285.   TR0= 1;
  286.   ET0= 1;
  287.   EA = 1;                           //开总中断
  288.   //EX1=1;                                               //同意开启外部中断1
  289.   IT1=1;   
  290.                                               //设定外部中断1为低边缘触发类型
  291.   while(1)                                //程序主循环
  292.   {
  293.            if(P3_2 == 0)
  294.            {
  295.                    if(temp<=4)
  296.                 {
  297.                      temp=temp+1;
  298.                   while(!P3_2);
  299.                 }
  300.            }                  
  301.        
  302.             if(temp>4)
  303.             {
  304.                      temp=1;
  305.                 }
  306.           switch(temp)
  307.           {
  308.                    case 1:        ShowPort = LedShowData[1];Robot_Traction();EX1 = 0;break;
  309.                 case 2: ShowPort = LedShowData[2];Robot_Avoidance();EX1 = 0;break;
  310.                 case 3: ShowPort = LedShowData[3];SB1 = 1; EX1 = 1;break;
  311.                 case 4:        ShowPort = LedShowData[4];Robot_Lightseek();EX1 = 0;break;

  312.           }
  313.   }
  314. }
复制代码

所有资料51hei提供下载:
循迹、避障、遥控综合.zip (49.75 KB, 下载次数: 11)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表