找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3797|回复: 1
收起左侧

智能循迹加壁障小车程序源码,简单写写,谢谢大家。

[复制链接]
ID:250150 发表于 2017-11-16 20:29 | 显示全部楼层 |阅读模式
#include<reg52.h>#include <intrins.h>         //内部包含延时函数 _nop_();
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
unsigned char dj1=0; //左前
unsigned char dj2=0;   //右前
unsigned char dj3=0;   //左后
unsigned char dj4=0;         //右后
uchar num1=0;
uchar t=0;
uchar  n=0;

sbit HW1=P0^0;           //红外对管位定义
sbit HW2=P0^1;                                                                                               
sbit HW3=P0^2;
sbit HW4=P0^3;

sbit ENA1=P3^2;          //前PWM输入
sbit ENB1=P3^3;
sbit ENA2=P3^4;          //后PWM输入
sbit ENB2=P3^5;

sbit IN1=P2^0;          //前电机
sbit IN2=P2^1;
sbit IN3=P2^2;
sbit IN4=P2^3;

sbit IN5=P2^4;          //后电机
sbit IN6=P2^5;
sbit IN7=P2^6;
sbit IN8=P2^7;

sbit RX = P1^2;//ECHO超声波模块回响端          左
sbit TX = P1^1;//TRIG超声波模块发
sbit rx = P1^3;//ECHO超声波模块回响端
sbit tx = P1^4;//TRIG超声波模块发

unsigned int  time = 0;//传输时间
unsigned long S = 0;//距离
bit      flag = 0;//超出测量范围标志位

unsigned int  time1 = 0;//传输时间
unsigned long S1 = 0;//距离
bit      flag1 = 0;//超出测量范围标志位


void Delay10us(unsigned char i)            //10us延时函数 启动超声波模块时使用
{
   unsigned char j;
        do{
                j = 10;
                do{
                        _nop_();
                }while(--j);
        }while(--i);
}       
void Delay10us1(unsigned char i)            //10us延时函数 启动超声波模块时使用
{
   unsigned char j;
        do{
                j = 10;
                do{
                        _nop_();
                }while(--j);
        }while(--i);
}               

void  StartModule()                          //启动超声波模块
{
          TX=1;                                             //启动一次模块
      Delay10us(2);
          TX=0;
}
void  StartModule1()                          //启动超声波模块
{
          tx=1;                                             //启动一次模块
      Delay10us(2);
          tx=0;
}

/*计算超声波所测距离并显示*/
void Conut(void)
{
        time=TH0*256+TL0;
        TH0=0;
        TL0=0;
       
        S=(float)(time*1.085)*0.17;     //算出来是MM
        if((S>=700)||flag==1) //超出测量范围
        {         
                flag=0;
        }
               
}
void Conut1(void)
{
        time1=TH0*256+TL0;
        TH0=0;
        TL0=0;
       
        S=(float)(time1*1.085)*0.17;     //算出来是MM
        if((S1>=700)||flag==1) //超出测量范围
        {         
                flag1=0;
        }
               
}
void delay(uint x)         //延时1ms
{
        uint i,j;
        for(i=0;i<x;i++)
                for(j=0;j<120;j++);
}       

void qianjin()                   //小车前进
{
           IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;

        IN5=0;
        IN6=1;
        IN7=0;
        IN8=1;

        dj1=35;                  //左前
        dj2=30;                        //
        dj3=25;                          //  右后
        dj4=25;                                //
}

void weileft()                //小车前进向左微调
{         
    IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;

        IN5=0;
        IN6=1;
        IN7=0;
        IN8=1;

        dj1=40;
        dj2=50;
        dj3=45;
        dj4=45;
}


void weiright()                 //小车前进向右微调
{
    IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;

        IN5=0;
        IN6=1;
        IN7=0;
        IN8=1;

        dj1=55;
        dj2=35;
        dj3=35;
        dj4=35;
}




void daright()
{   
    IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;

        IN5=0;
        IN6=1;
        IN7=0;
        IN8=1;

        dj1=25;
        dj2=15;
        dj3=15;
        dj4=25;
}

void daleft()
{
    IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;

        IN5=0;
        IN6=1;
        IN7=0;
    IN8=1;
        dj1=15;
        dj2=25;
        dj3=25;
        dj4=15;
}
void stop()                                 //小车停止
{
        dj1=0;
        dj2=0;
        dj3=0;
        dj4=0;
}

/*超声波避障*/
void        Avoid()
{
  if(S<400||S1<400)
  {       
            stop();//停车
        delay(2500);
                do
                {
                       
                        if(S<=S1)
                                        {
                                        //        back();
                                        //        delay(100);//后退时间越长、距离越远。后退是为了留出车辆转向的空间
                                         //        stop();
                                                delay(2500);                                 //小车停止
                                                daright();
                                                delay(2500);
                                        //        qianjin();       
                                        //        delay(1000);
                                        //        daleft();
                                //                delay(500);       
                                    }

                                 if(S>S1)
                                        {
                                        //        back();
                                        //        delay(100);//后退时间越长、距离越远。后退是为了留出车辆转向的空间
                                         //        stop();                                                   //小车停止
                                        //        delay(500);                       
                                                daleft();
                                                delay(2500);
                                        //        qianjin();       
                                        //        delay(1000);
                                        //        daleft();
                                //                delay(500);
                                    }
               
          
                StartModule();        //启动模块测距,再次判断是否
                        while(!RX);                //当RX(ECHO信号回响)为零时等待
                        TR0=1;                            //开启计数
                        while(RX);                        //当RX为1计数并等待
                        TR0=0;                                //关闭计数
                        Conut();                        //计算距离

                                StartModule1();        //启动模块测距,再次判断是否
                        while(!rx);                //当RX(ECHO信号回响)为零时等待
                        TR0=1;                            //开启计数
                        while(rx);                        //当RX为1计数并等待
                        TR0=0;                                //关闭计数
                        Conut();                        //计算距离
                 }while(S < 280||S1<280);//判断前面障碍物距离
        }
        else
        {
      qianjin();

    }
}







void init()                                 //初始化
{
        TMOD|=0x01;
        TMOD |= 0x11;//定时器0工作模块1,16位定时模式。T0用测ECH0脉冲长度
        TH0        = 0;
    TL0        = 0;//T0,16位定时计数用于记录ECHO高电平时间  
        TH1=(65536-1000)/256;
        TL1=(65536-1000)%256;
        EA=1;
        ET1=1;
        ET0 = 1;//允许T0中断
        TR1=1;
        TR0=1;
}

/*定时器0中断*/
void timer0() interrupt 1        //T0中断用来计数器溢出,超过测距范围
{
        flag=1;
        flag1=1;                                                         //中断溢出标志                         
}


void timer1() interrupt 3                 //定时器1中断
{
        TH1=(65536-1000)/256;
        TL1=(65536-1000)%256;
        t++;
        if(t<dj1)        ENA1=1;
        else        ENA1=0;
        if(t<dj2)        ENB1=1;
        else        ENB1=0;
        if(t<dj3)        ENA2=1;
        else        ENA2=0;
        if(t<dj4)        ENB2=1;
        else        ENB2=0;

        if(t>=100)
        {
                t=0;
        }
}


void main()
{
            
        init();
        while(1)
        {   
                 StartModule();        //启动模块测距
                 while(!RX);                //当RX(ECHO信号回响)为零时等待
                 TR0=1;                            //开启计数
                 while(RX);                        //当RX为1计数并等待
                 TR0=0;                                //关闭计数
             Conut();                        //计算距离

                  StartModule1();        //启动模块测距
                 while(!rx);                //当RX(ECHO信号回响)为零时等待
                 TR0=1;                            //开启计数
                 while(rx);                        //当RX为1计数并等待
                 TR0=0;                                //关闭计数
             Conut1();                        //计算距离
                 Avoid();                        //避障
                 delay(65);                        //测试周期不低于60MS       
   }
}         

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:139053 发表于 2018-5-11 09:34 | 显示全部楼层
你虽然定义了红外线端口,但是好像没写循迹部分的程序。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表