找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3101|回复: 3
收起左侧

想在避障模块多完善一些 就是让小车停止一会儿然后向后转再向左转,怎么改写比较好?

[复制链接]
回帖奖励 50 黑币 回复本帖可获得 5 黑币奖励! 每人限 1 次
ID:229453 发表于 2017-9-2 23:35 | 显示全部楼层 |阅读模式
#include <reg52.h>
#include " LCD1602.h "
sbit zuo = P1^0;
sbit you = P1^1;
sbit zhong = P1^2;
sbit IN1 = P2^1;           //P2.0到P2.3是电机驱动输出控制端
sbit IN2 = P2^2;
sbit IN3 = P2^3;
sbit IN4 = P2^4;
sbit Trig = P2^0;      //产生脉冲引脚
sbit Echo = P3^3;      //回波引脚
uint distance[4];      //测距接收缓冲区
unsigned char code ASCII[16]  = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
unsigned char disbuff[4]= { 0,0,0,0,};
uint distance1;
bit succeed_flag;      //测量成功标志

void chaoshengbo();
void delay_20us();
void delay_ms(uint x);
void delay(uint t);
void Tracking();
void shunback();
//延时程序1
void delay(uint t)     
{
        uchar j;
    while(t--)
        {for(j=5;j>0;j--);}
}
//微妙延时程序
void delay_us(uint x)          
{
do {
     x--;
   }

while(x>1);
}
//毫秒延时
void delay_ms(uint x)
{
        while(x!=0)
        {
                delay_us(500);
                x--;
        }

}
//20微妙延时
void delay_20us()
{  
        uchar bt ;
    for(bt=0;bt<100;bt++);
}
void Init()                          
{

    Trig=0;
        TMOD = 0x11;        //T/C1采用16位定时器/计数器
        ET1  = 1;                //定时器1开中断
    ET0  = 1;
        TH0 = 0x00;
    TL0 = 0x00;
        TH1 = 0xff;
    TL1 = 0xce;
        TR1=1;
    TR0        = 1;                //定时计数器启动计数
        EX0         = 1;                //外部中断0关中断
        PT1  = 1;
        EA         = 1;                //CPU开中断
}
//超声波测距
void chaoshengbo()
{           
        uint distance_data,S;
        Trig=1;
    delay_20us();
    Trig=0;         //产生一个20us的脉冲,在Trig引脚  

    while(!Echo);   //等待Echo回波引脚变高电平                  
    TR0=1;          //启动定时器1
        while(Echo);
        TR0=0;
       
        delay_ms(7);
        distance_data=TH0*256+TL0;
        TH0=0;
        TL0=0;
        S=(distance_data*1.7)/100;

        if(succeed_flag==1)
        {        
                distance1=S;
    }
                 
        disbuff[0]=((S/100)%10);
          disbuff[1]=((S/10)%10);
          disbuff[2]=(S%10);
          DisplayOneChar(9, 0, ASCII[disbuff[0]]);
          DisplayOneChar(10, 0, ASCII[10]);               //显示点
          DisplayOneChar(11, 0, ASCII[disbuff[1]]);
          DisplayOneChar(12, 0, ASCII[disbuff[2]]);
          DisplayOneChar(13, 0, ASCII[12]);               //显示M

}
//左转
void comeleft()
{
        IN1=0;
        IN2=1;
        IN3=1;
        IN4=1;
}
//右转
void comeright ()
{
        IN1=1;
        IN2=1;
        IN3=1;
        IN4=0;
}
//前进加速;
void comeon()
{         
        IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;
}
void stop()                  
{       
                   IN1=0;
                IN2=0;
                IN3=0;
                IN4=0;
}
void backward()
{
                IN1=1;
                IN2=0;
                IN3=1;
                IN4=0;
}
//红外寻迹
void Tracking()                  
{       
     if(zuo==1&&zhong==1&&you==1)   //0是接受到黑线,1是白线
     {
                comeon();
         }
         else if(zuo==1&&zhong==0&&you==1)
         {
              comeon();
         }

         else if(zuo==0&&zhong==1&&you==1)
         {
                  comeleft();

         }
         else if(zuo==0&&zhong==0&&you==1)
         {
              comeleft();
         }
         else if(zuo==1&&zhong==1&&you==0)
         {
             comeright();
         }
         else if(zuo==1&&zhong==0&&you==0)
         {
             comeright();
         }
                  else
         {
                stop();
        }   
}
//避障
void shunback()
{       
        chaoshengbo();
        delay_ms(50);
    Tracking();// 避障运行
        if(distance1<8)                //当超声波测距距离小于8则
        {
                stop();                        //小车停止运动
                delay_ms(50);
//                backward();
//                delay_ms(100);
//                comeleft();
//                delay_ms(60);
                 TR1=1;
                 delay_ms(50);
                 TR1=0;
        }
        else
        {

            Tracking();       
          
        }     //否则小车直走
}


//主函数
void main(void)
{

    Init();                   //初始化
        LCMInit();             //LCM初始化
        TMOD=0x01;
        TH0=0;          //定时器1清零
    TL0=0;          //定时器1清零
        ET0=1;                        //打开外部中断
        EA=1;
        succeed_flag=0; //清测量成功标志        
       
        while(1)
        {
        displayfun();
        chaoshengbo();
        shunback();                  //循环调用超声波测距
        Tracking();
}
}

//外部中断0,用做判断回波电平
INTO_()  interrupt 0  // 外部中断是0号
{   
    succeed_flag=1;   //至成功测量的标志
}







#ifndef __lcd1602__
#define __lcd1602__
//定义引脚
sbit LCM_RS = P2^6;
sbit LCM_RW = P2^5;     
sbit LCM_E  = P2^7;
//数据口定义
#define LCM_Data P0
sbit BF=LCM_Data^7;                //忙信号线
//数组变量
unsigned char code  yuyiny[18]={
        0x00,0x10,0x18,0x20,0x28,0x30,0x38,0x40,
        0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x98};
unsigned char inittime[7]={0x00,0x00,0x12,0x03,0x04,0x06,0x10};         //初始化时间

//变量
#define uchar unsigned char
#define uint  unsigned int                

/********************************************************************
函 数 名:unsigned char ReadStatusLCM(void)
功    能:忙检测
说    明:
入口参数:无
返 回 值:无  
***********************************************************************/
unsigned char ReadStatusLCM(void)
{
        bit busy =0;
        LCM_Data = 0xFF;
        LCM_RS   = 0;
        LCM_RW   = 1;
        LCM_E    = 1;
        LCM_E    = 1;
        busy     = BF;
        LCM_E    = 0;
        return(busy);
}

/********************************************************************
函 数 名:void WriteCommandLCM(unsigned char WCLCM,BuysC)
功    能:写命令
说    明:
入口参数:WCLCM
                   BuysC 需要忙检测
返 回 值:无  
***********************************************************************/
void WriteCommandLCM(unsigned char WCLCM,BuysC)  //BuysC为0时忽略忙检测
{
        if (BuysC) ReadStatusLCM();                  //根据需要检测忙

        while (ReadStatusLCM());
        LCM_RS = 0;
        LCM_RW = 0;
        LCM_Data = WCLCM;
        LCM_E = 1;
        LCM_E = 0;
}

/********************************************************************
函 数 名:void WriteDataLCM(unsigned char WDLCM
功    能:写数据
说    明:
入口参数:WDLCM
返 回 值:无  
***********************************************************************/
void WriteDataLCM(unsigned char WDLCM)
{
        while(ReadStatusLCM());                      //检测忙
        LCM_RS = 1;
        LCM_RW = 0;
        LCM_Data = WDLCM;
        LCM_E = 1;
        LCM_E = 0;
}
/********************************************************************
函 数 名:void LCMInit(void)
功    能:LCM初始化
说    明:
入口参数:无
返 回 值:无  
***********************************************************************/
void LCMInit(void)
{
        WriteCommandLCM(0x38,1);                     //显示模式设置,开始要求每次检测忙信号
        WriteCommandLCM(0x0C,1);                     //显示开及光标设置
        WriteCommandLCM(0x06,1);                     //显示光标移动设置
        WriteCommandLCM(0x01,1);                     //显示清屏
}

/********************************************************************
函 数 名:void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
功    能:按指定位置显示一个字符
说    明:
入口参数:X 一行显示个数限制
           Y 上下行限制
                   DData 数据
返 回 值:无  
***********************************************************************/
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;
        X &= 0xF;                         //限制X不能大于15,Y不能大于1
        if (Y) X |= 0x40;                 //当要显示第二行时地址码 0x40;
        X |= 0x80;                        // 算出指令码
        WriteCommandLCM(X, 0);            //这里不检测忙信号,发送地址码
        WriteDataLCM(DData);
}

/********************************************************************
函 数 名:void displayfun(void)
功    能:界面显示
说    明:
入口参数:无
返 回 值:无  
***********************************************************************/
void displayfun(void)
{
        WriteCommandLCM(0x0c,1);                                    //显示屏打开,光标不显示,不闪烁,检测忙信号

        /*显示 闹钟 设置*/   
        DisplayOneChar(0,0,'D');
        DisplayOneChar(1,0,'i');
        DisplayOneChar(2,0,'s');
        DisplayOneChar(3,0,'t');
        DisplayOneChar(4,0,'a');
        DisplayOneChar(5,0,'n');
        DisplayOneChar(6,0,'c');
        DisplayOneChar(7,0,'e');
        DisplayOneChar(8,0,':');
       
}


#endif





回复

使用道具 举报

ID:198530 发表于 2017-9-3 11:16 | 显示全部楼层
可以判断超声波距离小于一定大小时小车停止延时一定时间在执行其他操作
回复

使用道具 举报

ID:229453 发表于 2017-9-3 13:14 | 显示全部楼层
king_zxt 发表于 2017-9-3 11:16
可以判断超声波距离小于一定大小时小车停止延时一定时间在执行其他操作

我也是这样想的不过当我在避障模块加入其它指令,实测小车就一直执行我加的命令,比如先停止,然后后退最后左转,就一直这样循环执行,超声波测的显示的数据变化不准,如果不加直stop,就会执行寻迹指令...
回复

使用道具 举报

ID:219796 发表于 2017-9-6 01:43 来自手机 | 显示全部楼层
转弯前加个延迟
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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