51循迹小车

给女朋友调的循迹车。。。


/*
*******************************************************************************
* 文件名:main.c
* 描  述:寻迹小车
* 作  者:刘悦
* 版本号:v1.2
* 日  期: 2018年5月11日
* 备  注:注意了,所有的左右都是传感器位于自己前方看的!
*******************************************************************************
*/
#include <stc12.h>

//关于寻迹、蓝牙,取消哪个宏定义表示选择哪项模式
#define TRACE
#define BLUETOOTH

//电机引脚定义
sbit MotorRight_P = P1^0;//右电机正相
sbit MotorRight_N = P1^1;//右电机反相
sbit MotorLeft_P  = P1^2;//左电机正相
sbit MotorLeft_N  = P1^3;//左电机反相

//红外传感器检测引脚定义
//左右的序号分别从中间往两边开始1.2
sbit Left1   = P1^7;
sbit Left2   = P1^4;
sbit Right1  = P1^6;    
sbit Right2  = P1^5;

//数据类型定义
typedef unsigned char u8;
typedef unsigned int  u16;
typedef unsigned long u32;

//电机运动相关的宏定义
#define MotorLeft_Go()    {MotorLeft_P =1; MotorLeft_N =0;}//左电机正转
#define MotorLeft_Back()  {MotorLeft_P =0; MotorLeft_N =1;}//左电机反转
#define MotorLeft_Stop()  {MotorLeft_P =0; MotorLeft_N =0;}//左电机停止
#define MotorRight_Go()   {MotorRight_P=1; MotorRight_N=0;}//右电机正转
#define MotorRight_Back() {MotorRight_P=0; MotorRight_N=1;}//右电机反转
#define MotorRight_Stop() {MotorRight_P=0; MotorRight_N=0;}//右电机停止

//函数声明
void GoStaright();
void Back();
void TurnAdvanceLeft();
void TurnAdvanceRight();
void TurnNormalLeft();
void TurnNormalRight();
void Stop();
void Timer0Init(void);
void UartInit(void);

void main()
{
    u8 TypeFlag=2; //左强拐-0 左普拐-1 直走-2 右普拐-3 右强拐-4
    char ch;

    EA = 1;
    Timer0Init();
    UartInit();

    while(1)
    {       

//蓝牙模式      
#ifdef BLUETOOTH//蓝牙
        if(RI)
        {
            RI = 0;
            ch = SBUF;
        }

        if(ch == 'g') GoStaright();
        else if(ch == 'b') Back();
        else if(ch == 'l') TurnNormalLeft();
        else if(ch == 'r') TurnNormalRight();
//      else Stop(); 
#endif

//寻迹模式
#ifdef TRACE

        //另一种方案

        else if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==1))
        //if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==1))
        {
            TurnNormalRight();
            TypeFlag = 3;
        }

        //直行
        else if((Left2==0)&&(Left1==1)&&(Right1==1)&&(Right2==0))
        {
            GoStaright();
            TypeFlag = 2;
        }
        else if((Left2==0)&&(Left1==0)&&(Right1==1)&&(Right2==0))
        {
            GoStaright();
            TypeFlag = 2;
        }
        else if((Left2==0)&&(Left1==1)&&(Right1==0)&&(Right2==0))
        {
            GoStaright();
            TypeFlag = 2;
        }

        //左转
        else if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==0))
        {
            TurnAdvanceLeft();
            TypeFlag = 0;
        }
        else if((Left2==1)&&(Left1==0)&&(Right1==0)&&(Right2==0))
        {       
            TurnAdvanceLeft();
            TypeFlag = 0;
        }
        else if((Left2==1)&&(Left1==1)&&(Right1==0)&&(Right2==0))
        {
            TurnNormalLeft();
            TypeFlag = 1; 
        }
        else if((Left2==1)&&(Left1==0)&&(Right1==1)&&(Right2==0))
        {
            TurnAdvanceLeft();
            TypeFlag = 0;
        }

        //右转
        else if((Left2==0)&&(Left1==1)&&(Right1==1)&&(Right2==1))
        {
            TurnAdvanceRight();
            TypeFlag = 4;
        }
        else if((Left2==0)&&(Left1==0)&&(Right1==0)&&(Right2==1))
        {
            TurnAdvanceRight();
            TypeFlag = 4;
        }
        else if((Left2==0)&&(Left1==1)&&(Right1==0)&&(Right2==1))
        {
            TurnAdvanceRight();
            TypeFlag = 4;
        }
        else if((Left2==0)&&(Left1==0)&&(Right1==1)&&(Right2==1))
        {
            TurnNormalRight();
            TypeFlag = 3;
        }

        //都没检测到时,为防止车抖动,可继续执行上次的动作
        else if((Left2==0)&&(Left1==0)&&(Right1==0)&&(Right2==0))
        {
            if(TypeFlag == 0)
            {
                TurnAdvanceLeft();
            }
            else if(TypeFlag == 1)
            {
                TurnNormalLeft();
            }
            else if(TypeFlag == 2)
            {
                GoStaright();
            }
            else if(TypeFlag == 3)
            {
                TurnNormalRight();
            }
            else if(TypeFlag == 4)
            {
                TurnAdvanceRight();
            }
        }

        //其余所有情况均直行
        else
        {
            GoStaright();
        }
#endif

    }
}

void UartInit(void)     //[email protected]
{
    PCON |= 0x80;       //使能波特率倍速位SMOD
    SCON = 0x50;        //8位数据,可变波特率
//  AUXR &= 0xBF;       //定时器1时钟为Fosc/12,即12T
//  AUXR &= 0xFE;       //串口1选择定时器1为波特率发生器
    TMOD &= 0x0F;       //清除定时器1模式位
    TMOD |= 0x20;       //设定定时器1为8位自动重装方式
    TL1 = 0xF3;     //设定定时初值
    TH1 = 0xF3;     //设定定时器重装值
    ET1 = 0;        //禁止定时器1中断
    TR1 = 1;        //启动定时器1
}

void Timer0Init(void)       //10微秒@12.000MHz
{
//  AUXR &= 0x7F;       //定时器时钟12T模式
    TMOD &= 0xF0;       //设置定时器模式
    TMOD |= 0x01;       //设置定时器模式
    TL0 = 0xF6;     //设置定时初值
    TH0 = 0xFF;     //设置定时初值
    TF0 = 0;        //清除TF0标志
    ET0 = 1;  //关闭定时器0中断
    TR0 = 1;        //定时器0开始计时
}

void GoStaright()
{
    static unsigned char Clck = 0;
    u16  OutPWM_L=12,OutPWM_R=15;

    TL0 = 0xF6;     //设置定时初值
    TH0 = 0xFF;     //设置定时初值       
    if(Clck++ >= 100) Clck = 0;//100us   +1   1ms清零一次
    if(Clck<OutPWM_L)
    {   
        MotorLeft_Go();
    }
    else
    {
        MotorLeft_Stop();
    }
    if(Clck<OutPWM_R)
    {
        MotorRight_Go();    
    }
    else 
    {
        MotorRight_Stop();  
    }   
}

void Back()
{
    static unsigned char Clck = 0;
    u16  OutPWM_L=12,OutPWM_R=15;
    TL0 = 0xF6;     //设置定时初值
    TH0 = 0xFF;     //设置定时初值       
    if(Clck++ >= 100) Clck = 0;//100us   +1   1ms清零一次
    if(Clck<OutPWM_L)
    {   
        MotorLeft_Back();
    }
    else
    {
        MotorLeft_Stop();
    }
    if(Clck<OutPWM_R)
    {
        MotorRight_Back();  
    }
    else 
    {
        MotorRight_Stop();  
    }       
}

void TurnAdvanceRight()
{
    static unsigned char Clck = 0;
    u16  OutPWM_L=15,OutPWM_R=15;
    TL0 = 0xF6;     //设置定时初值
    TH0 = 0xFF;     //设置定时初值       
    if(Clck++ >= 100) Clck = 0;//100us   +1   1ms清零一次
    if(Clck<OutPWM_L)
    {   
        MotorLeft_Go();
    }
    else
    {
        MotorLeft_Stop();
    }
    if(Clck<OutPWM_R)
    {
        MotorRight_Back();  
    }
    else 
    {
        MotorRight_Stop();  
    }
}

void TurnAdvanceLeft()
{
    static unsigned char Clck = 0;
    u16  OutPWM_L=15,OutPWM_R=15;
    TL0 = 0xF6;     //设置定时初值
    TH0 = 0xFF;     //设置定时初值       
    if(Clck++ >= 100) Clck = 0;//100us   +1   1ms清零一次
    if(Clck<OutPWM_L)
    {   
        MotorLeft_Back();
    }
    else
    {
        MotorLeft_Stop();
    }
    if(Clck<OutPWM_R)
    {
        MotorRight_Go();    
    }
    else 
    {
        MotorRight_Stop();  
    }
}

void TurnNormalRight()
{
    static unsigned char Clck = 0;
    u16  OutPWM_L=15,OutPWM_R=15;
    TL0 = 0xF6;     //设置定时初值
    TH0 = 0xFF;     //设置定时初值       
    if(Clck++ >= 100) Clck = 0;//100us   +1   1ms清零一次
    if(Clck<OutPWM_L)
    {   
        MotorLeft_Go();
    }
    else
    {
        MotorLeft_Stop();
    }   
    MotorRight_Stop();  
}

void TurnNormalLeft()
{
    static unsigned char Clck = 0;
    u16  OutPWM_L=15,OutPWM_R=15;
    TL0 = 0xF6;     //设置定时初值
    TH0 = 0xFF;     //设置定时初值       
    if(Clck++ >= 100) Clck = 0;//100us   +1   1ms清零一次

    MotorLeft_Stop();
    if(Clck<OutPWM_R)
    {
        MotorRight_Go();    
    }
    else 
    {
        MotorRight_Stop();  
    }
}

void Stop()
{
    MotorLeft_Stop();
    MotorRight_Stop();
}

猜你喜欢

转载自blog.csdn.net/ReCclay/article/details/80290266
今日推荐