单片机——蝙蝠超声思想避物小车

目录

1、图片

2、代码 


1、图片

              

2、代码 

#include <reg52.h>     //52芯片配置文件
#include <intrins.h>   //包含nop等系统函数
#include "bst_car.h"   


unsigned char disbuff[4]={0,0,0,0};//用于分别存放距离的值0.1mm、mm、cm和m的值

unsigned int  time=0;//用于存放定时器时间值
unsigned long S=0;//用于存放距离的值
bit  flag =0; //量程溢出标志位
char a=0;

//延时函数
void delay(unsigned int xms)        
{
    unsigned int i,j;
  for(i=xms;i>0;i--)          //i=xms即延时约xms毫秒
    for(j=112;j>0;j--);
}

void Delay10us(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 Forward(void)//前进
{

   IN2=1;
   IN3=1;
   IN1=0;
   IN4=0;
}

void Stop(void)  //停车
{

   IN1=0; 
   IN2=0;
   IN3=0;
   IN4=0;
}

void back(void)  //后退
{

   IN1=1; 
   IN2=0;
   IN3=0;
   IN4=1;
}    
void Turn_Right(void)   //向右旋转
{
    IN1=0; 
  IN2=1;
  IN3=0;
  IN4=1;

}


/********距离计算程序***************/
void conut1(void)
{
  time=TH1*256+TL1;
  TH1=0;
  TL1=0;
                    //此时time的时间单位决定于晶振的频率,外接晶振为11.0592MHZ
                    //那么1us声波能走多远的距离呢?1s=1000ms=1000000us 
                    // 340/1000000=0.00034米
                    //0.00034米/1000=0.34毫米  也就是1us能走0.34毫米
                    //但是,我们现在计算的是从超声波发射到反射接收的双路程,
                    //所以我们将计算的结果除以2才是实际的路程
  S=time*0.17+10;    //此时计算到的结果为毫米,并且是精确到毫米的后两位了,有两个小数点 
}

void Conut(void)
{
   
    conut1();
  if((S>=5000)||flag==1) //超出测量范围
  {
      a=0;  
      flag=0;
  }
  else
  {
        disbuff[0]=S%10;
      disbuff[1]=S/10%10;
      disbuff[2]=S/100%10;
      disbuff[3]=S/1000;
   }
   //========避障部分===========================================
   if(S<=240)     刹车障碍物距离  跟车速有关 可更改
   {  
        a++;
        if(a>=2)
        {
            a=0;
          Stop();
          back();  //后退缓冲
          delay(230);//  后退缓冲时间 跟车速有关 可更改

            B:Turn_Right();
            delay(50);      ///  旋转角度 跟环境复杂程度有关 可更改
            Stop();
            delay(100);       旋转顿挫时间 视觉效果 可更改
            StartModule();         
            while(RX==0);
            TR1=1;          //开启计数
              while(RX);      //当RX为1计数并等待
              TR1=0;        //关闭计数
            conut1();


            if(S>340)      可直行方向无障碍物距离 跟环境有关 可更改
            {
  
                Turn_Right();
                delay(90);  
                  Stop();          //微调前进方向 避免车宽对前进影响
                delay(200);       
                Forward();
            }    
            else
           {
               goto B;        //若没转到空旷方向 回到B点 继续旋转一次
           }
    
         }
         else
       {
             Forward();  //无障碍物 直行
         }
  
   }

   else
   {
        a=0;
       Forward();     //无障碍物 直行
   }
   //=======================================
   
}

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

/********超声波高电平脉冲宽度计算程序***************/
void Timer_Count(void)
{
  TR1=1;          //开启计数
  while(RX);      //当RX为1计数并等待
  TR1=0;        //关闭计数
    Conut();      //计算

}
/********************************************************/
void keyscan(void)              //按键扫描函数
{
    A:    if(K4==0)      //判断是否有按下信号
    {
        delay(10);      //延时10ms
      if(K4==0)      //再次判断是否按下
       {
          FM=0;               //蜂鸣器响      
          while(K4==0);  //判断是否松开按键
          FM=1;               //蜂鸣器停止  
        }
        else
         {
           goto A;        //跳转到A重新检测
                }
    }
    else
    {
      goto A;             //跳转到A重新检测
    }
} 
/********************************************************/ 

/*************主程序********************/
void main(void)
{
    
  unsigned int a;
  delay(400); //启动等待,等LCM讲入工作状态
  delay(5);//延时片刻
    TMOD=TMOD|0x10;//设T0为方式1,GATE=1;
    EA=1;             //开启总中断
    TH1=0;
    TL1=0;          
    ET1=1;             //允许T0中断
    keyscan() ;  //按键扫描

    
   while(1)
  {
    RX=1;
      StartModule();         //启动模块
        for(a=951;a>0;a--)
      {
       
         if(RX==1)
       {
              Timer_Count();     //超声波高电平脉冲宽度计算函数
       }
       }
     }
} 



bst_car.h 文件

#ifndef __BSTCAR_H__
#define __BSTCAR_H__

//小车驱动模块的IO设置
sbit IN1=P2^2;
sbit IN2=P2^3;
sbit IN3=P2^5;
sbit IN4=P2^6;
sbit EN1=P2^4;
sbit EN2=P2^7;

//按键IO
sbit K4=P3^4;
sbit K3=P3^6;

//蜂鸣器IO
sbit FM=P1^3;

//红外循迹IO设置
sbit Left_1_led=P3^3;   //循迹-左红外IO       
sbit Right_1_led=P3^2;   //循迹-右红外IO     

//红外避障  
sbit Left_2_led=P3^4;   //避障-左红外IO 
sbit Right_2_led=P3^5;   //避障-右红外IO 

//超声波IO定义
sbit TX=P3^0;     //Trig 控制端
sbit RX=P3^1;     //Echo 接收端


#define Left_moto_go      {IN1=0,IN2=1;}   //左电机向前走
#define Left_moto_back    {IN1=1,IN2=0;}   //右电机向后走
#define Left_moto_Stop    {EN1=0;}         //左电机停止                  
#define Right_moto_go     {IN3=1,IN4=0;}   //右电机向前走
#define Right_moto_back   {IN3=0,IN4=1;}   //右电机向后走
#define Right_moto_Stop   {EN2=0;}         //右电机停止

#endif

#include <reg52.h>     //52芯片配置文件
#include <intrins.h>   //包含nop等系统函数
#include "bst_car.h"   


unsigned char disbuff[4]={0,0,0,0};//用于分别存放距离的值0.1mm、mm、cm和m的值

unsigned int  time=0;//用于存放定时器时间值
unsigned long S=0;//用于存放距离的值
bit  flag =0; //量程溢出标志位
char a=0;

//延时函数
void delay(unsigned int xms)        
{
    unsigned int i,j;
  for(i=xms;i>0;i--)          //i=xms即延时约xms毫秒
    for(j=112;j>0;j--);
}

扫描二维码关注公众号,回复: 16275147 查看本文章

void Delay10us(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 Forward(void)//前进
{

   IN2=1;
   IN3=1;
   IN1=0;
   IN4=0;
}

void Stop(void)  //停车
{

   IN1=0; 
   IN2=0;
   IN3=0;
   IN4=0;
}

void back(void)  //后退
{

   IN1=1; 
   IN2=0;
   IN3=0;
   IN4=1;
}    
void Turn_Right(void)   //向右旋转
{
    IN1=0; 
  IN2=1;
  IN3=0;
  IN4=1;

}


/********距离计算程序***************/
void conut1(void)
{
  time=TH1*256+TL1;
  TH1=0;
  TL1=0;
                    //此时time的时间单位决定于晶振的频率,外接晶振为11.0592MHZ
                    //那么1us声波能走多远的距离呢?1s=1000ms=1000000us 
                    // 340/1000000=0.00034米
                    //0.00034米/1000=0.34毫米  也就是1us能走0.34毫米
                    //但是,我们现在计算的是从超声波发射到反射接收的双路程,
                    //所以我们将计算的结果除以2才是实际的路程
  S=time*0.17+10;    //此时计算到的结果为毫米,并且是精确到毫米的后两位了,有两个小数点 
}

void Conut(void)
{
   
    conut1();
  if((S>=5000)||flag==1) //超出测量范围
  {
      a=0;  
      flag=0;
  }
  else
  {
        disbuff[0]=S%10;
      disbuff[1]=S/10%10;
      disbuff[2]=S/100%10;
      disbuff[3]=S/1000;
   }
   //========避障部分===========================================
   if(S<=240)    刹车障碍物距离  跟车速有关 可更改
   {  
        a++;
        if(a>=2)
        {
            a=0;
          Stop();
          back();  //后退缓冲
          delay(230);//  后退缓冲时间 跟车速有关 可更改

            B:Turn_Right();
            delay(50);      ///  旋转角度 跟环境复杂程度有关 可更改
            Stop();
            delay(100);       旋转顿挫时间 视觉效果 可更改
            StartModule();         
            while(RX==0);
            TR1=1;          //开启计数
              while(RX);      //当RX为1计数并等待
              TR1=0;        //关闭计数
            conut1();


            if(S>340)     可直行方向无障碍物距离 跟环境有关 可更改
            {
  
                Turn_Right();
                delay(90);  
                  Stop();          //微调前进方向 避免车宽对前进影响
                delay(200);       
                Forward();
            }    
            else
           {
               goto B;        //若没转到空旷方向 回到B点 继续旋转一次
           }
    
         }
         else
       {
             Forward();  //无障碍物 直行
         }
  
   }

   else
   {
        a=0;
       Forward();     //无障碍物 直行
   }
   //=======================================
   
}

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

/********超声波高电平脉冲宽度计算程序***************/
void Timer_Count(void)
{
  TR1=1;          //开启计数
  while(RX);      //当RX为1计数并等待
  TR1=0;        //关闭计数
    Conut();      //计算

}
/********************************************************/
void keyscan(void)              //按键扫描函数
{
    A:    if(K4==0)      //判断是否有按下信号
    {
        delay(10);      //延时10ms
      if(K4==0)      //再次判断是否按下
       {
          FM=0;               //蜂鸣器响      
          while(K4==0);  //判断是否松开按键
          FM=1;               //蜂鸣器停止  
        }
        else
         {
           goto A;        //跳转到A重新检测
                }
    }
    else
    {
      goto A;             //跳转到A重新检测
    }

/********************************************************/ 

/*************主程序********************/
void main(void)
{
    
  unsigned int a;
  delay(400); //启动等待,等LCM讲入工作状态
  delay(5);//延时片刻
    TMOD=TMOD|0x10;//设T0为方式1,GATE=1;
    EA=1;             //开启总中断
    TH1=0;
    TL1=0;          
    ET1=1;             //允许T0中断
    keyscan() ;  //按键扫描

    
   while(1)
  {
    RX=1;
      StartModule();         //启动模块
        for(a=951;a>0;a--)
      {
       
         if(RX==1)
       {
              Timer_Count();     //超声波高电平脉冲宽度计算函数
       }
       }
     }

bst_car.h 文件

#ifndef __BSTCAR_H__
#define __BSTCAR_H__

//小车驱动模块的IO设置
sbit IN1=P2^2;
sbit IN2=P2^3;
sbit IN3=P2^5;
sbit IN4=P2^6;
sbit EN1=P2^4;
sbit EN2=P2^7;

//按键IO
sbit K4=P3^4;
sbit K3=P3^6;

//蜂鸣器IO
sbit FM=P1^3;

//红外循迹IO设置
sbit Left_1_led=P3^3;   //循迹-左红外IO       
sbit Right_1_led=P3^2;   //循迹-右红外IO     

//红外避障  
sbit Left_2_led=P3^4;   //避障-左红外IO 
sbit Right_2_led=P3^5;   //避障-右红外IO 

//超声波IO定义
sbit TX=P3^0;     //Trig 控制端
sbit RX=P3^1;     //Echo 接收端


#define Left_moto_go      {IN1=0,IN2=1;}   //左电机向前走
#define Left_moto_back    {IN1=1,IN2=0;}   //右电机向后走
#define Left_moto_Stop    {EN1=0;}         //左电机停止                  
#define Right_moto_go     {IN3=1,IN4=0;}   //右电机向前走
#define Right_moto_back   {IN3=0,IN4=1;}   //右电机向后走
#define Right_moto_Stop   {EN2=0;}         //右电机停止

#endif

猜你喜欢

转载自blog.csdn.net/weixin_61181717/article/details/127957635
今日推荐