• 1.jpg
  • 3.jpg
  • 5.jpg

第5步坦克主程序

   我们说硬件是载体软件是灵魂,前面已经介绍了遥控坦克的硬件部分接下来我们该去实现它的软件部分了,说简单就是写程序控制我们的坦克完成预计功能。看过前面文字的朋友知道我们的硬件系统分为两部分,它们是坦克系统和手柄系统,我们要分别为这两个系统编写程序。首先我们先设计一下坦克一端的软件架构,如图6-1。

从图中我们能看出坦克一端在不断的接收命令,如果有命令发来就解析命令然后执行命令,如果没有命令那么继续下一次接

收命令,总之坦克一旦上电就在不停的接收命令直到关闭电源。这里给出部分源程序作为参考,考虑到有些朋友不太熟悉程

序设计为不影响大家对原理的理解,在代码中使用了很多注释和伪代码甚至插入很多中文信息,如下:

//程序入口
void main(){
    //初始化硬件
    //初始化串口
    //初始化数据传输模块
    //初始化定时器
    while(1)    //不停的循环
    {
        if(收到数据){   //如果收到数据,进行命令的解析
            switch(命令){ //根据不同命令,控制电机的不同行为
                case 向前:
                //控制左侧马达向前滚动 AND 控制右侧马达向前滚动
                break;
                case 向后:
                //控制左侧马达向后滚动 AND 控制右侧马达向后滚动
                break;
                case 左转:
                //控制做侧马达向后滚动 AND 控制右侧马达向前滚动
                break;
                case 右转:
                //控制做侧马达向前滚动 AND 控制右侧马达向后滚动
                break;
                default:    //无法识别的命令
                //停车
                break;
            }
        }else{
            //没有收到数据
        }
    }
}

从上述代码中我们可以清晰的看出程序的执行过程,系统在无止境的循环接收命令、解析命令、执行命令。其中while代码块部分(while(1){……})是这段程序的主体,我们会发现它的核心就是控制电机的旋转,那么如何通过程序来控制电机的旋转呢,这就要回忆一下前面介绍的硬件电路了(《遥控坦克DIY过程解密(02)——电机控制电路》),如上图中6-3所示。

   根据L9110的工作时序图以及我们的硬件原理图,我们可以清楚的看出要想让电机旋转我们只要让单片机的两个IO引脚P10、P11输出反相就可以了,如果转化成代码如下所示。

//nMotorNum:马达编号
//     eDir:旋转方向
void SetMotor(int nMotorNum, int eDir)
{
    if(nMotorNum == 0)
    {
        //控制第一个马达旋转
        if(eDir == 正向)
        {
            //点击正向旋转
            P10 = 1;P11=0;
        }
        else if(eDir == 反向)
        {
            //电机逆向旋转
            P10 = 0;P11 = 1;
        }
        else
        {
            //停机
            P10 = 0;P11 = 0;
        }
    }
    else if(nMotorNum == 1)
    {
        /*控制第二个马达旋转或停机*/
    }
    else if(nMotorNum == 2)
    {
        /*控制第三个马达旋转或停机*/
    }
    else{
        /*所有马达停机*/
    }
}

上图中nMotorNum == 0的if代码块表示的是对一个马达的控制,对另外2个马达的控制方法也是一样的,进行到这里我们已经可以通过程序来控制电机的旋转了,只要正确的协调3个马达的旋转方向,我们就可以让我们的坦克完成前进、后退、左转、右转、炮塔顺时针旋转以及炮塔逆时针旋转这几个功能。

那么系统是如何知道已经接收到数据的呢?只要有两种方法,一种方法是对NRF24L01的状态不断进行查询,另一种方法是当NRF24L01接收到数据以后主动通知MCU,根据我们的硬件原理图同时为了提高系统执行效率,我们采用第二种方法,电路图如上图第三张6-5所示,代码如下:

void ISR_Int0(void) interrupt0
{
    //读取NRF24L01的状态
    if(接收到数据){
        //设置标志,表示接收到数据
        //把接收到的数据放入命令缓冲区
    }
    //清除中断信号
}

当接收到数据传输模块触发的中断后,我们去读取传输模块的状态,如果接收到数据我们就设置一个标志,图6-2的程序会不断查询这个标志,一旦发现有数据发送来,就可以对数据进行解析了。


当然这里面我们省略了初始化硬件、定时器以及传输模块的详细步骤,如果大家在DIY过程中也遇到到了具体技术问题,可以随时翻阅资料或学习,当然也可以与“ZiShi”(qq:275074722)进行交流。


如果要让坦克正常解析接收到的命令,我们可以定义一些简单的协议,如下所示:

//命令列表
#define Go          0X00
#define Bank        0X01
#define TurnLeft    0X02
#define TurnRight   0X03
//...
//...
//...
#define NOP         0XFF

有了命令列表,通信双方就可以根据这个“协议”进行通信了,假如坦克一端接收到0X00,那么坦克就全速向前冲,如果坦克一端接收到0X02,那么坦克就会左转,大家还可以自己扩充这个命令列表,让自己的坦克完成更多的功能。

坦克一端的程序原理已经介绍完毕了,后面我们还会继续介绍遥控手柄一端的程序原理。




下一步上一步

评 论

e

选择昵称后请轻按空格键

    提 交

    请勿进行人身攻击,谩骂以及任何违法国家相关法律法规的言论。

    信息

    65535

    浏览
    5
    oydean

    作者:oydean

    分享:42

    高骚不止.>>

    关键词:单片机遥控

    猜你会喜欢

    WIFI小车

    我制作的用WIFI控制的小车,原理很简单...

    牛人自制的极光雾状LED灯

    这是DIY牛人制作的一款极光9x18的L...

    世界上最小的DS18B20温度计

    DS18B20不少朋友都用过吧,不过似乎...

    简单实用的稳压直流稳压电源(用89C51做)

    直流稳压电源采用了89C51,配合D/A...

    数码管显示STC89C54RD+DB18B20测温板

    主要元件用到了单片机STC89C54RD...