51循迹小车过程总结

学习51单片机后,想要对学习成果加以实践检验的同学一般都会做一个循迹小车来检验学习成果。

下面我来讲述一下我做循迹小车的过程吧。

硬件方面

购买好小车车架,注意车架车体不要买铁质板,一般而言,在网上买的小车车架均为塑料车架或者树脂材料的车架,由于借用了铁质车架,在刚开始安装小车通电时,就发现L298N电机驱动模块不断发热(芯片电容烫手,显示灯不亮。)我这个原因是红外模块贴合铁的车架子,导致短路才使L298N模块发热,无法正常上电。

材料清单:小车车架(双驱的两个轮子两电机,一个万向轮,四驱的四个轮子四电机,至于需不需要串联电机看具体情况。),两个电机或四个电机,5v稳压模块,一个L298或两个L298N(四驱一定用两个L298N是最好的,没有两个用一个也行,控制效果没差,但是得注意电机电流与驱动的负载能力应当适配。)红外循迹模块(四路,五路都行),12v电源电池(建议买电池包,并且是可充电式的。)

接通正常时红外模块亮灯,51单片机亮灯,L298N亮灯,则电路正常,注意接线不要因为粗心短接(会烧51芯片的),其他地方都比较好操作的。

注:一些工具需要自己购买的,焊枪锡丝用于焊接电机,螺丝固定,螺丝刀,胶布,杜邦线。

下面是接线正常亮灯图:

软件方面:

下面是51单片机上引脚接口,L298n通过P10,P11使能,通过7654口控制转速,转向是通过左右轮差速转向。20,21,22,23是红外循迹端口,后面是定时器初始化以及一些函数声明。

#include <reg51.h>//通用51头文件
  sbit ENA=P1^0;  //定义L298N的使能口
  sbit ENB=P1^1;  
  sbit IN1=P0^7;      //定义L298N的选择口
  sbit IN2=P0^6;
  sbit IN3=P0^5;
  sbit IN4=P0^4;
  sbit RIGHT_IR2= P2^0; //最右   //定义红外循迹模块的端口
  sbit RIGHT_IR= P2^1; //右
  sbit LEFT_IR= P2^2;  //左
  sbit LEFT_IR2= P2^3;  //最左
unsigned char PWMA,PWMB;//左电机占空比,有电机占空比
  void xunji();//循迹函数
  void turnleft();//左转函数
  void turnleft2();//左转函数2:大角度转弯
  void turnright();//右转函数
  void turnright2();//右转函数2:大角度转弯
  void straight();          //直行函数
  void straight2();         //直行函数二用于解决小车卡顿
  void stop();//停车函数
  void Timer0Init(void)
{
    TMOD |= 0x01;//设置定时器模式
    TL0 = (65536-100)%256;//设置定时初始值
    TH0 = (65536-100)/256;//设置定时初始值
    TR0 = 1;//定时器0开始计时
    ET0 = 1;//定时器0中断使能
    EA = 1;//中断使能
}
void main()
{
  Timer0Init();//定时器0初始化
  while(1)
{
xunji();//循环执行循迹函数
}
}
void T0isp() interrupt 1
{
unsigned char i,j;
TL0 = (65536-100)%256;//设置定时初始值
TH0 = (65536-100)/256;//设置定时初始值
i++;//变量i用于控制PWMA占空比
j++;//变量j用于控制PWMB占空比
if(i < PWMA)//PWMA值以下,输出高电平
{
ENA = 1;
}
else //PWMA-100范围,输出低电平
{
ENA = 0;
//if(i >= 100)
if(i > 100)
{
i = 0;
}
}
if(j < PWMB)//PWMB值以下,输出高电平
{
ENB = 1;
}
else //PWMB-100范围,输出低电平
{
ENB = 0;
//if(j >= 100)
if(j > 100)
{
j = 0;
}
}
}

循迹程序,我用的是四路循迹,将

转弯情况分为四种,有两种是小幅左转以及小幅右转,后两种是大幅右转以及大幅左转。具体情况就看代码注释。

void xunji()
{
    unsigned char jiaodu;                        //转向标志
    if(LEFT_IR == 0 && RIGHT_IR == 0    && LEFT_IR2 == 0 && RIGHT_IR2 == 0) //4个探头均未压线
    {        
        //straight();
        switch(jiaodu)
        {
            case 0:straight();break;
            case 1:turnleft();break;   
            case 2:turnleft2();break;
            case 3:turnleft();break;
            case 4:turnright2();break;
            case 5:straight2();break;
            default:stop();break;
        }    
    }
    if(LEFT_IR == 1 && RIGHT_IR == 0 && LEFT_IR2 == 0 && RIGHT_IR2 == 0) //左内探头压线,车子轻微右倾,缓慢左转
    {
        straight();                                        //直走
        jiaodu = 5;
    }
    if(LEFT_IR == 0 && RIGHT_IR == 0 && LEFT_IR2 == 1 && RIGHT_IR2 == 0) //左外探头压线,车子右倾,大角度左转
    {
        turnleft2();                                        //大角度左转
    //    jiaodu = 1;
        jiaodu = 2;
    }
    if(LEFT_IR == 1 && RIGHT_IR == 0 && LEFT_IR2 == 1 && RIGHT_IR2 == 0) //左内外探头压线,左90度弯,大角度左转
    {
        turnleft2();                                        //左转
    //    jiaodu = 1;
        jiaodu = 1;
    }
    if(LEFT_IR == 1 && RIGHT_IR == 1 && LEFT_IR2 == 1 && RIGHT_IR2 == 0) //左内外探头压线,左90度弯,大角度左转
    {
        turnleft2();                                        //左转
    //    jiaodu = 1;
        jiaodu = 1;
    }
    if(LEFT_IR == 0 && RIGHT_IR == 1 && LEFT_IR2 == 0 && RIGHT_IR2 == 0) //右内探头压线,车子轻微左倾,缓慢右转
    {
        straight();                                        //直走
        jiaodu = 5;
    }
    if(LEFT_IR == 0 && RIGHT_IR == 1 && LEFT_IR2 == 0 && RIGHT_IR2 == 1) //右外探头压线,车子左倾,大角度右转
    {
        turnright2();                                    //大角度右转
    //    jiaodu = 2;
        jiaodu = 3;
    }
    if(LEFT_IR == 0 && RIGHT_IR == 0 && LEFT_IR2 == 0 && RIGHT_IR2 == 1) //右外探头压线,车子左倾,大角度右转
    {
        turnright2();                                    //大角度右转
    //    jiaodu = 2;
        jiaodu = 4;
    }
    
    if(LEFT_IR == 1 && RIGHT_IR == 1 && LEFT_IR2 == 0 && RIGHT_IR2 == 1) //右内外探头压线,左90度弯,大角度左转
    {
        turnleft2();                                    //大角度右转
        //jiaodu = 2;
        jiaodu = 3;
    }
    if(LEFT_IR == 1 && RIGHT_IR == 1 && LEFT_IR2 == 0 && RIGHT_IR2 == 0) //右内外探头压线,左90度弯,大角度左转
    {
        straight();                                    //直走
        //jiaodu = 2;
        jiaodu = 0;
    }
    if(LEFT_IR == 1 && RIGHT_IR == 1 && LEFT_IR2 == 1 && RIGHT_IR2 == 1) //4个探头均压线,停车
    {    
        stop();
     // jiaodu = 3;
        jiaodu = 6    ;
    }
}

下面就是PWM调速:

左右轮调速注意一致,相对称的速度有利于小车行驶稳定。

源码不建议复用,框架可以用但是不同车型车况,数据是必须要改动调试的。

我多设置了直走程序的执行情况是因为正在行驶过程中会无故停下不能走动,通过不同情况不同配速的方法,解决了行驶过程卡顿停止。稳定变得更好了。但是这种情况只是因为我的电机和轮子可能不适配,导致行驶过程不流畅,统一购买的电机与车轮应该不会出现这类问题。


void straight()                                            
{
    IN1 = 0;
    IN2 = 1;
    PWMA =17;                                        
    IN3 = 1;
    IN4 = 0;
    PWMB = 17;        
}
void straight2()                                
{
  
    IN1 = 0;
    IN2 = 1;
    PWMA =17;                                        
    IN3 = 1;
    IN4 = 0;
    PWMB = 18;        
}
void turnleft()                                        
{
    IN1 = 0; //IN1 为0,IN2为1,右轮正转
    IN2 = 1;
    PWMA =20;                                                
    IN3 = 0;//IN3为1,IN4为0,左轮正转
    IN4 = 0;
    PWMB = 0;                                            
}
void turnleft2()                                
{
    IN1 = 0;
    IN2 = 1;
    PWMA = 20;                                            
    IN3 = 0;
    IN4 = 0;
    PWMB = 0;                                            
}
void turnright()                                    
{
    IN1     = 0;//IN1 为0,IN2为1,右轮正转
    IN2     = 0;
    PWMA     = 20;                                    
    IN3     = 1;//IN3为1,IN4为0,左轮正转
    IN4 = 0;
    PWMB     = 0;                                            
}
void turnright2()                                    
{
    IN1    = 0;
    IN2 = 0;
    PWMA = 0;                                                
    IN3 = 1;
    IN4 = 0;
    PWMB = 20;                                                
}
void stop()                                                    
{
    IN1 = 0;
    IN2 = 0;
    PWMA = 0;                                                
    IN3 = 0;
    IN4 = 0;
    PWMB = 0;                                                
}

经历总结

小车最后行驶效果可以循迹,但是再走直线过程中无法平稳行驶,会左右摇摆,通过红外反馈调节车速达到平衡就可以解决。调节PID即可让小车稳定循迹,这方面可以找相关视频学习一下。

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值