【51单片机实例】智能小车(三)-------- 小车的红外循迹
时间:2022-11-10 03:30:01
51单片机实例
- 智能汽车(1)-汽车的前进、后退和停止
 - 智能车(二)-------- 红外遥控调速
 
文章目录
- 前言
 - 一、介绍红外循环模块
 -  
       
- 1. 模块描述
 - 2. 模块参数说明
 - 3. 说明模块接口
 - 4. 模块用途
 - 5. 模块介绍
 - 6. 功能介绍
 - 7. 电路原理图
 
 - 二、硬件连接
 - 三、实现代码
 -  
       
- 1. 引脚定义,函数声明模块
 - 2. 延迟模块
 - 3. 定时器模块
 - 4. 汽车转向模块
 - 5. 主函数模块
 
 - 总结
 
前言
本节基于51单片机下的智能小车(2)-------- 在汽车红外遥控调速的基础上增加了红外循环模块,但本节不使用红外遥控模块。如果您想了解红外遥控模块,请访问智能汽车(2)-------- 车辆红外遥控调速,如果车辆硬件连接有问题,请前往智能车辆(一)-车辆前进、后退、停车,接下来,我开始介绍红外循环模块。
一、介绍红外循环模块

1. 模块描述
该传感器模块对环境光有很强的适应性。它有一对红外发射和接收管,发射管发射一定频率的红外线。当检测方向遇到障碍物(反射面)时,红外反射被连接 管道接收,经过比较器电路处理后,绿色指示灯亮起,信号输出接口输出数字信号电平信号),可通过电位器旋钮调整检测距离,有效距离范围 2~30cm,工作电压为3.3V-5V。该传感器的探测距离可通过电位器调节,具有干扰小、装配方便、使用方便等特点,可广泛应用于机器人避障 障碍车、流水线计数、黑白线跟踪等场合。
2. 说明模块参数
(1) 当模块检测到前障碍物信号时,电路板上的绿色指示灯同时点亮电平OUT端口连续输出低电平信号,模块检测距离为2~30cm,检测角度35°,可通过电位器调节检测距离,顺时针调节电位器,增加检测距离;逆时针调节电位器,减少检测距离。
 (2) 传感器主动进行红外反射检测,因此目标的反射率和形状是探测距离的关键。黑色探测距离最小,白色探测距离最大;小物体距离小,大面积距离大。
 (3) 传感器模块输出端口OUT可直接与单片机配合IO口连接也可以直接驱动5V继电器:连接方式:VCC-VCC;GND-GND;OUT-IO
 (4) 比较器采用LM三九三、工作稳定;
 (5) 可采用3-5V模块供电直流电源。当电源连接时,红色电源指示灯亮起;
 (6) 具有3mm螺孔易于固定和安装;
 (7) 电路板尺寸:3.2CM*1.4CM
3. 模块接口说明
(1) VCC 外接3.3V-5V电压(可直接与5v单片机和3.3v单片机连接)
 (2) GND 外接GND
 (3) OUT 小板数字输出接口(0和1)
4. 模块用途
(1) 电表脉冲数据采样
 (2) 传真机碎纸机纸张检测
 (3) 障碍检测
 (4) 黑白线检测
5. 模块介绍
(1) 采用TCRT红外反射传感器
 (2) 检测反射距离:1mm~25mm适用
 (3) 比较器输出,信号干净,波形好,驱动能力强,超过15mA。
 (4) 调节配电位器的灵敏度
 (5) 工作电压3.3V-5V
 (6) 输出形式 :数字开关量输出(0和1)
 (7) 固定螺栓孔安装方便
 (8) 小板PCB尺寸:3.2cm x 1.4cm
 (9) 使用宽电压LM393比较器
6. 功能介绍
TCRT5000传感器的红外发射二极管不断发射红外线。当发射的红外线没有反射或反射,但强度不够大时,红外接收管已关闭,模块的输出端为高电平,表示二极管已熄灭;当检测范围内出现检测对象时,红外线反射强度足够大,红外接收管饱和,模块的输出端为低电平,指示二极管被点亮。
7. 电路原理图
 传感器的红外发射二极管(1-2)不断发射红外线。当发射的红外线没有反射或反射,但强度不够大时,光敏三极管(3-4)已关闭。此时,模块输出端(引脚1)为低电平,表示二极管已熄灭;当检测对象出现在检测范围内时,红外线反射,强度足够大,光敏三极管饱和,此时,模块的输出端为高电平,表示二极管被点亮。
二、硬件连接
具体硬件连接请前往智能车(1)-车辆前进、后退和停止
 请前往智能车(2)相关驱动模块-------- 红外遥控调速
三、实现代码
1. 引脚定义,函数声明模块
#include     typedef unsigned int u16; typedef unsigned char u8;   u8 PWML=0,PWMR=0,t=0;                //定义PWM 占空比  u16 DE=0;                    ///判断路线是否曲折   sbit ENAL=P1^1;       //定义L298N的使能口 sbit ENBR=P1^0;        sbit IN1=P0^6;      //定义L298N的选择口
sbit IN2=P0^5;
sbit IN3=P0^4;
sbit IN4=P0^3;
sbit IRN1=P0^0;   //右 //定义红外循迹模块的端口
sbit IRN2=P0^1;   
sbit IRN3=P0^2;   //左
sbit IRN4=P2^0;   
 
 
 
void Timer0_Init();
void Turn();
void Driv_Go();
void Driv_Stop();
void Driv_Back();
void Driv_Left();
void Driv_Right();
void Driv_Left_OPP();
void Driv_Right_OPP();
void RightMotoForward();
void RightMotoBack();
void LeftMotoBack();
void LeftMotoForward();
void RightMotoStop();
void LeftMotoStop();
void Delay(u8 i);
 
    2. 延迟模块
void Delay(u8 i)
{ 
        
    while(i--);
}
 
    3. 定时器模块
void Timer0_Init()                  //设置定时器0
{ 
                                                       //通过设置定时器0来调制小车的转速
   TMOD|=0x01;              //选择16位的定时器
   TH0=(65536-100)/256;
   TL0=(65536-100)%256; 
   ET0=1;                  //开放定时器中断0
   TR0=1;
   EA=1;
}
 
void Timer0Init() interrupt 1     //中断 进入占空比的调节
{ 
        
     TH0=(65536-100)/256;
     TL0=(65536-100)%256;
     t++;
     if(t<PWML)
     { 
        
        ENAL=1;
     }
     else
     { 
        ENAL=0;}
     if(t<PWMR)
     { 
        
        ENBR=1;
     }
     else
     { 
        ENBR=0;}
    if(t>=100)       
      t=0;
}
 
 
    4. 小车转向模块
void Turn()  
{ 
        
/
    if(DE==0)             //判断路线较为平缓
    { 
        
         if(IRN1==0&&IRN2==0&&IRN3==0&&IRN4==0) //启动循迹前不要挡住小车的四个红外检测灯
     { 
        
         PWML=20;                                   //L298N同时控制两个电机时,电机转速不同
         PWMR=19;                                   //通过软件来调节,尽可能减小误差
         Driv_Back();
     }
///
         if(IRN2==0&&IRN3==1)      //小车左转
     { 
        
         Delay(100);
         if(IRN2==0&&IRN3==1)
         { 
        
       PWML=7;
         PWMR=25;
         Driv_Go();
         }
     }
///
// if(IRN1==0&&IRN2==0&&IRN3==0&&IRN4==1) //小车左转(大幅度)
// { 
        
// Delay(1000);
// if(IRN2==0&&IRN3==1)
// PWML=7;
// PWMR=25;
// Driv_Go();
// }
///
         if(IRN2==1&&IRN3==0)      //小车右转
     { 
        
            Delay(100);
        if(IRN2==1&&IRN3==0)
          { 
        
         PWML=25;
           PWMR=5;
           Driv_Go();
            }
      }
 
///
// if(IRN1==1&&IRN2==0&&IRN3==0&&IRN4==0) //小车右转(大幅度)
// { 
        
// Driv_Stop();
 if(IRN2==1&&IRN3==0)
 Delay(1000);
// PWML=25;
// PWMR=5;
// Driv_Go();
// }
///
        if(IRN2==1&&IRN3==1)       //小车直走 接收到信号就是0
    { 
        
        Delay(100);
        if(IRN2==1&&IRN3==1)
     { 
        
      PWML=20;                              
        PWMR=19;
        Driv_Go();
     }
    }
}
    else
    { 
        
        if(IRN1==0&&IRN2==0&&IRN3==0&&IRN4==0)  
    { 
        
        PWML=20;                                
        PWMR=19;                                    //小车停止
        Driv_Back();
        Delay(10000);            //延时一下
        Driv_Stop();
        DE=1;
    }
///
        if(IRN2==0&&IRN3==1)       //小车左转(左轮后转 右轮正转 产生速差)
    { 
        
        Delay(100);
        if(IRN2==0&&IRN3==1)
        Driv_Left_OPP();
    }
///
        if(IRN2==1&&IRN3==0)       //小车右转(左轮正转 右轮后转)
    { 
        
        Driv_Stop();
        if(IRN2==1&&IRN3==0)
        Driv_Right_OPP();
    }
///
        if(IRN2==1&&IRN3==1)       //小车直走 
    { 
        
        Delay(100);
        if(IRN2==1&&IRN3==1)
    { 
        
       PWML=20;                                  
       PWMR=19;
        Driv_Go();
    }
 }
        DE=0;   
}
}
 
void Driv_Go()
{ 
        RightMotoForward();LeftMotoForward();}
 
void Driv_Back()
{ 
        RightMotoBack();LeftMotoBack();}
     
void Driv_Right()
{ 
        RightMotoStop();LeftMotoForward();}
 
void Driv_Left_OPP()
{ 
        RightMotoForward();LeftMotoBack();}
     
void Driv_Right_OPP()
{ 
        RightMotoBack();LeftMotoForward();}
     
void Driv_Left()
{ 
        LeftMotoBack();RightMotoForward();}
 
void Driv_Stop()
{ 
        RightMotoStop();LeftMotoStop();}
 
void RightMotoForward()
{ 
        IN3=1; IN4=0;}
void RightMotoBack()
{ 
        IN3=0; IN4=1;}
void LeftMotoBack()
{ 
        IN1=1; IN2=0;}
void LeftMotoForward()
{ 
        IN1=0; IN2=1;}
void RightMotoStop()
{ 
        IN3=1; IN4=1;}
void LeftMotoStop()
{ 
        IN1=1; IN2=1;}
 
    5. 主函数模块
void main()
{ 
        
   Timer0_Init();
   EA=1;
   while(1)
   { 
        
      Turn();
   }              
}
 
     总结
本节是以STC89C52单片机为CPU,通过一些外围电路和软件编程实现小车红外循迹的功能。整个设计过程中最大的特点是利用简单的理论原理将红外循迹模块、L298N驱动模块、51单片机这三个模块有效的结合起来,利用红外循迹原理与pwm调节占空比的简单结合实现对小车红外循迹奠定编程理论基础,提高了效率,降低了编程的复杂度,具有很强的研究的意义,智能化的发展促使了智能小车往功能更加强大的方向发展。

