51单片机-蓝牙遥控红外循迹小车-代码+硬件连接

2021/04/28-更新工具的连接

-----------------------------------------

前几天弄了个基于51芯片的蓝牙红外小车,因为是新手也没有人教,网上的资料也不够齐全(很多都是跳过新手那一步,比如说接线),做的过程中遇到很多问题,做的比较艰难,因而写一篇记录整个过程的文章,希望能够给新手提供一些帮助同时也做一个总结。

组装完成的小车,比较丑。

效果图

 

1.材料(可以在淘宝上买得到)

  1.4wd小车一台,包含马达,两个底盘,和螺丝等(要自己组装,)

  

  2.  L298N电机驱动模块两个,用来控制马达的转速,方向,停止与否。

    

  3. 51单片机最小系统板一个和STC89C52RC芯片一个

   

  4.HC-05蓝牙模块一个(蓝牙遥控)和usb转TTL转接模块一个(用于设置和调试蓝牙模块)

  

  

   5. 4路红外循迹模块(黑白循迹)

  

   6. 18650电池四个和18650电池盒和杜邦线若干。

我用的材料就是以上这些。

2. 组装

  第二个难点就是组装,难在如何接线。

  1.先把四个马达和车轮装在一起,组装成一个小车框架。

  2.L298N电机的接线

  

   一个L298N有四个输出口(out1,out2,out3,out4)接马达,每两个输出口控制一个马达,因此可以控制两个马达,12v接口接电源正极,5v接口是给最小系统板供电,所以5v接系统板5v口。四个IO输入口(in1,in2,in3,in4)通过芯片控制输出口。两个使能端口(A,B),只有高电平时电机才有有效,低电平时电机不转

转。因为有两个电机只有一个供电源所以两个电机要并联连接在一起。

下面是电机的控制表,当使能端位低电平(0)时电机处于停止状态,当输出口为(00或11)时处于制动状态,阻止电机转动。

 代码如下

#include<reg52.h>  
#include<intrins.h>  
  
sbit LEA=P1^0;//左边轮的使能端A  
sbit LEB=P1^1;//左边轮的使能端B  
//左前轮  
sbit LIN1=P1^2;//  
sbit LIN2=P1^3;//  
//左后轮  
sbit LIN3=P1^4;  
sbit LIN4=P1^5;  
  
sbit REA=P3^2;//右边轮使能端A  
sbit REB=P3^3;//右边轮使能端B  
//右前轮  
sbit RIN1=P3^4;  
sbit RIN2=P3^5;  
//右后轮  
sbit RIN3=P3^6;  
sbit RIN4=P3^7;  
  
//方向控制  
void delay(int time);//延时函数  
void forward();//前进  
void back();//后退  
void stop();//停止  
void start();//启动  
void turnLeft();//左转  
void turnRight();//右转  
  
  
//蓝牙模块  
//定时器1用作串口发生器,用于与蓝牙通信  
void time1Init();//定时器1的初始化  
void processMsg();//处理蓝牙接收到的信息  
  
//红外模块  
//从右到左  
//in1是最右边的红外灯  
sbit in1=P2^0;  
sbit in2=P2^1;  
sbit in3=P2^2;  
sbit in4=P2^3;  
int isTrace=0;//是否开启循迹功能  
void trace();//红外循迹  
  
  
//PWM调速  
//通过控制使能端高低电平输出的时间从而控制速度  
int count=0; //用于计数  
int pwm=20;   //表示启动的时间,20表示启动20ms  
void time0Init();//定时器0的初始化.  
                //用于控制高低电平的时间  
                //定时器比较准确  
void go();//启动 使能端为高电平 1  
void pause();//停止   使能端为低电平 0  
void time0Fun();//定时器0的中断函数  
  
  
  
  
int main()  
{  
  
    EA=1;//打开总中断  
    time1Init();//定时器1初始化  
    time0Init();//定时器0初始化  
    start();//使车的方向一开始向前  
  
    while(1)  
    {  
        if(isTrace)  
            trace();  
        if(count>=100) //100ms一个周期  
            count=0;  
        if(count<pwm) //pwm表示启动的时间          
                      //pwm越大 速度越快  
            go();  
        else if(count>=pwm)  
            pause();  
    }  
    return 0;  
}  
  
  
void delay(int time)//延时函数  
{  
    int i;  
    for(i=0;i<time;i++)  
    {  
        _nop_();//在晶振12M下  
                //一个nop函数延时1us  
    }  
}  
void forward()//前进  
{  
    //前进,所有轮正转  
    LIN1=0;  
    LIN2=1;  
  
    LIN3=0;  
    LIN4=1;  
  
    RIN1=0;  
    RIN2=1;  
  
    RIN3=0;  
    RIN4=1;  
}  
void back()//后退  
{  
    //前进,所有轮反转  
    LIN1=1;  
    LIN2=0;  
  
    LIN3=1;  
    LIN4=0;  
  
    RIN1=1;  
    RIN2=0;  
  
    RIN3=1;  
    RIN4=0;  
}  
void turnLeft()//左转  
{  
    //左转  左边的轮正转,右边轮反转  
    LIN1=0;  
    LIN2=1;  
  
    LIN3=0;  
    LIN4=1;  
  
    RIN1=1;  
    RIN2=0;  
  
    RIN3=1;  
    RIN4=0;  
    delay(5000);//延时5ms 控制转弯的角度  
  
}  
void turnRight()//右转  
{  
    //右转,左边轮反转,右边轮正转  
    LIN1=1;  
    LIN2=0;  
  
    LIN3=1;  
    LIN4=0;   
  
    RIN1=1;  
    RIN2=0;  
  
    RIN3=1;  
    RIN4=0;  
    delay(5000);//延时5ms 控制转弯的角度  
}  
void stop()//停止  
{  
    //停止,全部高电平或低电平  
    LIN1=0;  
    LIN2=0;  
  
    LIN3=0;  
    LIN4=0;   
  
    RIN1=0;  
    RIN2=0;  
  
    RIN3=0;  
    RIN4=0;  
}  
  
void start()  
{  
    forward();//一开始,前进方向  
}  
  
//定时器1用作串口发生器,用于与蓝牙通信  
void time1Init()//定时器1的初始化  
{  
    TMOD=0x20;//定时器1,工作模式2,8位自动重装模式  
    TH1=0xfd;//9600波特率,要与蓝牙的一致  
    TL1=0xfd;  
    //串口通信方式1  
    SM0=0;  
    SM1=1;  
    PCON=0x00;//波特率不加倍  
    SCON=0x50;//工作方式一  
    REN=1;//允许接收  
    ES=1;//开启串口中断  
    TR1=1;//启动定时1  
  
}  
void processMsg() interrupt 4 //中断4  
//处理蓝牙接收到的信息  
{  
    char ch;  
    //等待接收完毕  
    while(!RI)//当RI为0时没有接收完毕  
        ;       //为1时接收完毕  
    //信息存存在sbuf中  
    ch=SBUF;//获取接收的信息  
    switch(ch)  
    {  
        case 'f':  //前进  
            forward();  
            break;  
        case 'b': //后退  
            back();  
            break;  
        case 'l': //左转  
            turnLeft();  
            break;  
        case 'r': //右转  
            turnRight();  
            break;  
        case 's':   //停止  
            stop();  
            break;  
        case 'o':  
            start();  
            break;//启动  
        case 't': //开启循迹功能  
            isTrace=1;  
            break;  
        case '1':  //一档  
            pwm=20;  
            break;  
        case '2':  //二档  
            pwm=60;  
            break;  
        case '3': //三档  
            pwm=100;  
            break;  
        default:  
            break;  
    }  
}  
void trace()//红外循迹  
{  
    //当红外遇到黑线时吸收红外光,输出高电平  
    //遇到白线时反射红外,输出低电平  
  
    int dir=0;//0表示直走  
                //1 代表左转  
                //2 代表右转  
    //0 0 0 0  
    if(in1==0&&in2==0&&in3==0&&in4==0)  
        dir=0;  
    //1 0 0 0  
    else if (in1==1&&in2==0&&in3==0&&in4==0)  
        dir=2;  
    //1 1 0 0  
    else if (in1==1&&in2==1&&in3==0&&in4==0)  
        dir=2;  
    //1 1 1 0  
    else if (in1==1&&in2==1&&in3==1&&in4==0)  
        dir=0;  
    //1 1 1 1  
    else if (in1==1&&in2==1&&in3==1&&in4==1)  
        dir=0;  
  
    //0 1 0 0  
    else if (in1==0&&in2==1&&in3==0&&in4==0)  
        dir=2;  
    //0 1 1 0  
    else if (in1==0&&in2==1&&in3==1&&in4==0)  
        dir=0;  
    //0 1 1 1  
    else if (in1==0&&in2==1&&in3==1&&in4==1)  
        dir=1;  
    //0 0 1 0  
    else if (in1==0&&in2==0&&in3==1&&in4==0)  
        dir=1;  
    //0 0 1 1  
    else if (in1==0&&in2==0&&in3==1&&in4==1)  
        dir=1;  
  
    //1 0 1 0  
    else if (in1==1&&in2==0&&in3==1&&in4==0)  
        dir=1;  
    //1 1 1 0  
    else if (in1==1&&in2==1&&in3==1&&in4==0)  
        dir=2;  
    //1 0 1 1  
    else if (in1==1&&in2==0&&in3==1&&in4==1)  
        dir=0;  
    //1 0 0 1  
    else if (in1==1&&in2==0&&in3==0&&in4==1)  
        dir=0;  
    //0 0 0 1  
    else if (in1==0&&in2==0&&in3==0&&in4==1)  
        dir=1;  
    //1 1 0 1  
    else if (in1==1&&in2==1&&in3==0&&in4==1)  
        dir=0;  
    switch(dir)  
    {  
        case 0:  
            forward();  
            break;  
        case 1:  
            turnLeft();  
            break;  
        case 2:  
            turnRight();  
            break;  
    }  
}  
  
void time0Init()//定时器0的初始化.  
                //用于控制高低电平的时间  
                //定时器比较准确  
{  
    TMOD|=0x01;//工作方式一  
                //用或运算是为了不改变  
                //定时器1对应位的值。  
    TH0=0xfc;  
    TL0=0x66;  //定时1ms  
  
    ET0=1;//开启定时器0的中断  
    TR0=1;//启动定时器0  
}  
  
void go()//启动 使能端为高电平 1  
{  
    LEA=1;  
    LEB=1;  
    REA=1;  
    REB=1;  
}  
  
void pause()//停止    使能端为低电平 0  
{  
    LEA=0;  
    LEB=0;  
    REA=0;  
    REB=0;  
}  
  
void time0Fun() interrupt 1  
{  
    TH0=0xfc;  
    TL0=0x66;  
    //1ms 中断一次,count加一  
    count++;  
}  

   L298N无效,无法驱动马达的原因(1.电压不够,起码要7v以上。2.使能端没有处于高电平状态 。3.L298N或马达坏了).

  3.蓝牙的接线

  蓝牙接在最小系统板,蓝牙的TXD(发送口)口接系统板的RXD(接收口)口,RXD口接TXD口也就是交叉连接,发送口对接收口。

  在接在系统板之前,要对蓝牙进行一些设置(名称,密码,波特率),这时就要用到usb转TTL模块。

  

  接在电脑上,打开串口调试助手(软件在后面的链接),进入AT模式 (进入方法,蓝牙模块上面有个按钮,在usb口插入电脑前,长按不放,插入电脑即可,如果看到蓝牙模块上的灯在快速闪烁,说明已经进入AT模式,慢闪是工作模式)。

  

  

  比如设置名字hello,密码123456

  AT+NAME=hello

  AT+PSWD=123456

  发送以上两个命令即可,之后打开手机的蓝牙试试能不能连接成功。

  4.红外的接线

  红外模块的接线很简单,按照引脚上的说明,一一对应接在系统板上即可。

3.代码

  代码大概分成三个模块,蓝牙遥控模块,红外循迹模块,PWM调速模块。

  1.蓝牙那部分还需要在手机下载一个蓝牙助手用来控制小车,我的是在小米商城下载的,有广告,并不是很好用,但又找不到好的,只好将就一下。如果会android编程的,可以自己写一个。下面那些命令都是自定义,你可以根据需要,自己定制,写代码的时候对应就行。
  

下面是要用到的软件,包括 串口调试助手,代码编写工具KEil, 烧录软件TCICP_V6.87

链接:https://pan.baidu.com/s/1NyjX8BkccG__643gwCKSTQ 
提取码:fwzr 

有任何问题可以找我

  • 146
    点赞
  • 1029
    收藏
    觉得还不错? 一键收藏
  • 59
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值