新闻  |   论坛  |   博客  |   在线研讨会
基于51单片机超声波测距器设计 倒车雷达
0750long | 2009-04-04 20:39:43    阅读:1675   发布文章

基于51单片机超声波测距器设计 倒车雷达

 

点击开大图

超声波倒车控制器的技术要求(暂定)


1:在现有样品只能显示测试距离功能的基础上增加继电器用来控制电机断电(串励系统)或者启动它励(它励系统)同时有声光报警。数位显示可以保留作为选装件。
2:控制器应在离障碍物99~5cm时启动(感应探头至障碍物的距离)。应该做到出厂可调以适应客户需求。
3:产品工作电压12V,主机应独立封装,做到防尘防水抗电磁干扰。
4:每套系统有2或者3只探头,所有附件与主机的连接均采用插接器,以便维护保养。
5:以上要求为暂时定制,有问题双方协商解决。
补充:欠压继电器12v断电电路;距离<5CM,继电器12v切断电机,软件C语言代码,硬件制作成品电路板

  
//超声波测距系统,2008.5.5//
//89s51,数显,99CM-5CM,声光报警,继电器欠压保护,继电器5CM继电器控制电机断电//
//工作电压12v输入,3路数码管显示距离//


#include "reg51.h"
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

 


sbit transfer="P1"^0;
sbit receiver="P3"^2;
sbit speak="P1"^1;
sbit relay="P3"^1;  //继电器控制接口
/*数码管位选控制*/
sbit ledwei0=P2^4;
sbit ledwei1=P2^5;
sbit ledwei2=P2^6;

uchar TimerH,TimerL;            //读取测量定时器的值
ulong  realTimer;               //存放真测量时间
ulong   real_dis;               //存放测量距离
uint  dis_flag;                 //距离计算标志位
uint  alarm_flag100=0;             //用于报警
uint  alarm_flag50=0;
uint  alarm_flag20=0;
uint  alarm_flag10=0;

uint wei0,wei1,wei2,wei3;
uchar ledflag="0";                //数码管标志位,用于刷新
uchar send_flag=0;
uchar count="0";                  //定时器T0计数
uchar ledcode[11]={0x18, 0x7B, 0x2C, 0x29, 0x4B, 0x89, 0x88, 0x3B, 0x08, 0x09,0xff};//结合硬件译码

/*延时函数*/
void delay(uint count) //延时

 while(count--);
}

/*超声波发送函数--40KHZ*/
void CLK40K()
{ uchar i="4";         //发送的波形数量=(i/2)
// ET1=0;
 TR0=1;    //START TIME0,同时发送40KHZ方波
do
 {
 transfer=~transfer;
  _nop_ ();
  _nop_ ();
  _nop_ ();
   _nop_ ();
  _nop_ ();
  _nop_ ();
  _nop_ ();
  _nop_ ();
  _nop_ ();
  }
   while(--i);
}

/*距离测量函数*/
void distance(void)
{
 realTimer=TimerH*256+TimerL;
 real_dis=realTimer*164/10000;              //单位cm
//if(real_dis<=10)
 //real_dis=10;
 //real_dis=103;
 wei0=real_dis%10;
 wei1=(real_dis/10)%10;
 wei2=(real_dis/100)%10;
 //wei3=real_dis/1000;
}

/*显示刷新函数函数*/
void display(void)
{

switch(ledflag)
      {
    case 0:P0=ledcode[wei0];ledwei0=0;ledwei1=1;ledwei2=1;break;
    case 1:P0=ledcode[wei1];ledwei0=1;ledwei1=0;ledwei2=1;break;
    case 2:P0=ledcode[wei2];
   
    if(wei2<=0)
    {
    ledwei0=1;ledwei1=1;ledwei2=1;
    }
   
    else
    {
       ledwei0=1;ledwei1=1;ledwei2=0;
     }
    break;
    //case 3:P0=ledcode[wei3];break;
   }
 
 ledflag++;
 if(ledflag==3)
 ledflag=0;
 
 
 
 delay(0x80);
}

 

/*报警处理函数*/
void alarm_light(void)
{
 if(real_dis<=10)
 {
          relay="0";           //关闭电机
    speak="1";

  
 }
 else if(real_dis<20)
        {
   if(alarm_flag20>=1)
   {
    speak^=1;
    alarm_flag20=0;
    }
  }
 else if(real_dis<50)
        {
   if(alarm_flag50>=2)
   {
    speak^=1;
    alarm_flag50=0;
    }
  }
 else if(real_dis<100)
        {
   if(alarm_flag100>=4)
   {
    speak^=1;
    alarm_flag100=0;
    }
  }
  else
  {
   speak="1";
  }
}


/*系统初始化程序*/
void init()//系统初始化
{
 TMOD=0X11; //初始化定时器T0,T1用于产生40hz发射波
 TH0=0x00;
 TL0=0x00;
 TH1=0x00;
 TL1=0x00;
 TF1=0;
 PX0=1;
 ET1=1;
 EA=1;
 TR1=1;  //启动定时器1
 IT0=0;  //外部低电平触发方式

}


void int0(void) interrupt 0  //关闭计数器,存计数值,置标志
{
 
  EA="0";       //关闭中断
  EX0=0;         //关外部中断
  TimerL="TL0";    //读取数值
  TimerH="TH0";
  TR0=0;         //关闭定时器0
  TH0=0x00;
  TL0=0x00;
  dis_flag=1;    //距离计算标志
  //speak=1;
 // distance();   //调用距离计算函数

}

void time1(void) interrupt 3

 TF1=0;
 TH0=0x00;
 TL0=0x00;
 TH1=0x00;
 TL1=0x00;
 
 send_flag=1;     //开启接收回波中断
 
 
}
/*系统主函数*/
void main()

 init();       //系统初始化
 real_dis=150;//y预设初值,防止开机未发射超声波,电机锁死
 delay(0x40);
 while(1)
 {
  if(send_flag==1)
  {
           /* 报警级别计数*/
        alarm_flag100++;
   alarm_flag50++;
   alarm_flag20++;
   alarm_flag10++;


     /* 报警级别计数*/

     
   send_flag=0;
   count++;
   if(count==5)
   {
    count=0;
    CLK40K();
    //TR1=1;              //??? 
    delay(0x40);  //延时,避开发射的直达声波信号,可以调节测量的最小距离
       EX0=1;
   }
  }
  if(dis_flag==1)
  {
     dis_flag=0;
    //speak=0;
    distance();
    EA="1";
  }
    display();    //调用显示函数  
    alarm_light();
 }
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客