智能小车(四轮)制作

wuchangjian2021-11-14 20:34:21编程学习

 智能小车的制作是学习51单片机中一个很重要的过程,下面是自己完成小车的一点心得,在这里和大家分享。

代码如下:

#include <reg51.h>      //IO引脚定义:
sbit key1 = P3^7;    //定义按键1
sbit key2 = P3^6;    //定义按键2
sbit key3 = P3^5;    //定义按键3
sbit key4 = P3^4;    //定义按键4

sbit L_WXJ=P2^1;             //四路寻迹模块接口第四路,左外录迹             
sbit R_WXJ=P2^3;             //四路寻迹模块接口第一路,右外寻迹

sbit IN1=P3^0;        
sbit IN2=P3^1;
sbit IN3=P1^2;
sbit IN4=P1^3;
sbit IN11=P2^6;                                            
sbit IN22=P2^7;
sbit IN33=P0^2;
sbit IN44=P0^3;

sbit L_PWM=P1^4;       //左轮调速,接驱动模块ENA使能端,在这里输入PWM信号
sbit R_PWM=P1^6;       //右轮调速,接驱动模块ENB使能端,在这里输入PWM信号
sbit L_PWM1=P0^4;       //左轮调速,接驱动模块ENA使能端,在这里输入PWM信号
sbit R_PWM1=P0^5;       //右轮调速,接驱动模块ENB使能端,在这里输入PWM信号

//宏定义
#define L_go      IN1=0;IN2=1; //左轮前进
#define L1_go      IN33=0;IN44=1; //左轮前进
#define L_back    IN1=1;IN2=0; //左轮后退
#define L1_back    IN33=1;IN44=0; //左轮后退    
#define R_go        IN3=0;IN4=1; //右轮前进
#define R1_go        IN11=0;IN22=1; //右轮前进
#define R_back      IN3=1;IN4=0; //右轮后退
#define R1_back      IN11=1;IN22=0; //右轮后退

#define car_go                L_go;R_go;        //小车前进
#define car_go1                L1_go;R1_go;                 
#define car_back            L_back;R_back    //小车后退
#define car_back1            L1_back;R1_back;
#define car_left            R_go;L_back
#define car_left1            R1_go;L1_back        //小车左转弯
#define car_right            L_go;R_back        //小车右转弯
#define car_right1            L1_go;R1_back
#define car_stop            L_stop;R_stop;L_stop;R_stop;    //小车停车


//数据定义
unsigned char l_tt=0;    //定时器计数用

unsigned char l_Lpwm=0;    //左轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速
unsigned char l_Rpwm=0;    //右轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速
unsigned char l_Lpwm1=0;    //左轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速
unsigned char l_Rpwm1=0;    //右轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速

//TIMER0中断服务子函数产生PWM信号
void timer0()interrupt 1   using 2
{
    TH0=0XFC;      //定时1毫秒,10格调速,为100HZ频率,此频率下效果比较好,过大有噪声,过小振动大
    TL0=0X17;
    l_tt++;
    if(l_tt>3)l_tt=0;    //比较用,3格调速
    
    if((l_tt)<=l_Lpwm){//左调速,占空比数值越大,输出高电平时间越宽,电机转速越高,我们设计3个格,0-2,0为停止,2为全速
         L_PWM=1;
        L_PWM1=1;

    }
    else{
        L_PWM=0;
        L_PWM1=0;
    }
    if(l_tt<=l_Rpwm){//右调速,同上
        R_PWM=1;
        R_PWM1=1;
    }
    else{
        R_PWM=0;
        R_PWM1=0;
    }
}

void XJmoto(void)
{    
    while(1){        //循环探测
            if((R_WXJ == 0)&&(L_WXJ == 0))
            {
            car_go;
            car_go1;
            }
            else if((R_WXJ ==0)&&(L_WXJ == 1)) 
            {
            car_right;
            car_right1;
            }
            else if((R_WXJ == 1)&&(L_WXJ == 0))
            {
            car_left;
            car_left1;
            }
            else {                                
            car_go;
            car_go1;   
//如果写成后退,易出现问题
                            
            }
        }
}

/***********主函数开始********************************************************/    
void main(void)
{
    TMOD=0x01;  //定时器0方式1,16位计数器,用来计数时间,定时器1做为波特率发生器
     TH0=(65536-100)/256;      
    TL0=(65536-100)%256;
    TR0= 1;
    ET0= 1;
    EA=1; 
    
    l_Lpwm=0;
    l_Rpwm=0;
    l_Lpwm1=0;
    l_Rpwm1=0;

    while(1){        //按键选择不同车速,以适应不同的赛道
        if(key1==0){        //按下按钮S1启动寻迹功能
            l_Lpwm=1;//设置速度
            l_Rpwm=1;
            l_Lpwm1=1;//设置速度
            l_Rpwm1=1;
            XJmoto();
        }
        if(key2==0){        //按下按钮S2启动寻迹功能
            l_Lpwm=6;//设置速度
            l_Rpwm=6;
            l_Lpwm1=6;//设置速度
            l_Rpwm1=6;
            XJmoto();
        }
        if(key3==0){        //按下按钮S3启动寻迹功能
            l_Lpwm=8;//设置速度
            l_Rpwm=8;
            l_Lpwm1=8;//设置速度
            l_Rpwm1=8;
            XJmoto();
        }
        if(key4==0){        //按下按钮S4启动寻迹功能
            l_Lpwm=10;//设置速度
            l_Rpwm=10;
            l_Lpwm1=10;//设置速度
            l_Rpwm1=10;
            XJmoto();
        }
    }        

}

上面的代码可以实现按键调速,但因为自己只利用key1,所以占空比没改,5:5和1:1,占空比都是50%,但因为5:5加速时间更长,所以速度可能是更快的。

还有一个关于占空比设置的小细节,格数多会有个问题,就是如果你把运动时间设置的比较短,因为每个电机的灵敏性不同,容易导致轮子有的转,有的不转,就算都转动了,也容易有快有慢,导致小车转圈。

在连线时要注意L298N要和单片机共地,通过L298N的5V输出端给单片机供电,L298N的12V输入可由锂电池供电。

红外检测模块的高度设置是一个很重要的问题,通过实践总结的经验是可以在走的路线上实测,当红外模块在黑线上信号灯灭,在白板上信号灯亮时,说明高度合适。并不是很多人说的越低越好,这点很重要。 

当车轮打滑时,可以通过增加负重或减慢车速来有效规避。

以上是自己的一点拙见,希望对大家有用。

相关文章

Android编译命令m、mm、mmm区别及工程搭建示例

要使用m、mm、mmm命令对Android代码进行模块编译,需要先执行如下...

[react-router] React-Router怎么获取历史对象?

[react-router] React-Router怎么获取历史对象?...

前端开发之JS规范

一般规范 使用严格等=== 总是使用 ==&...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。