超声波测距·数码管显示

HC-SR04超声波模块工作原理:

1)采用 IO TRIG 触发测距,给最少10us 的高电平信号。

2)模块自动发送 8 40khz 的方波,自动检测是否有信号返回;

3)有信号返回,通过 IO ECHO 输出一个高电平,一有输出就打开定时器计时,此口变为低电平时停止计时,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;

  

应用领域:

机器人、避障物体测距、液位检测、公共安防、停车场检测

 

传感器内部电路图:

 

时序图说明:





/*


hc-sr04 超声波测距模块 DEMO 程序

晶振:11.0592

接线:模块TRIG接 P1.2  ECH0 接P1.1

数码管:共阳数码管P0接数据口,P2.2 P2.1 P2.0接选通数码


*/	    
#include <AT89x51.H>		//器件配置文件
#include <intrins.h>        //51基本运算(包括_nop_空函数)

#define  ECHO  P1_1           //接收引脚
#define  TRIG  P1_2           //Trig触发引脚

unsigned int  time=0;               //存放定时器时间
unsigned int  timer=0;              //计时器
unsigned char posit=0;              //定义是数码管显示
unsigned long S=0;

bit flag =0;                        //量程溢出标志位


unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff};

unsigned char const positon[3]={ 0xfe,0xfd,0xfb};           //P2口位选动态扫描

unsigned char disbuff[4]  ={ 0,0,0,0,};

void Display(void);
void Conut(void);






/*************主函数********************************************/
void  main(  void  )

  {  
      //初始化
    TMOD=0x11;		   //设T0为方式1,GATE=1;
	TH0=0;
	TL0=0;          
	TH1=0xf8;		   //2MS定时
	TL1=0x30;
	ET0=1;             //允许T0中断
	ET1=1;			   //允许T1中断
	TR1=1;			   //开启定时器
	EA=1;			   //开启总中断

	while(1)
	{
	 while(!ECHO);		//当ECHO为零时等待
	 TR0=1;			    //开启计数
	 while(ECHO);		//当ECHO为1计数并等待
	 TR0=0;				//关闭计数
     Conut();			//计算
	}

  }
                




/**********************扫描数码管*********************************/
  
    void Display(void)				 //扫描数码管
	{
	 if(posit==0)                    //如果是第一个位置那么显示小数点
         
	 {P0 = (discode[disbuff[posit]]) & 0x7f;}  //清除Bit7位   //&按位与,&&逻辑与即全真为真
     
	 else                                     //不是第一个位置就不显示小数点
         
	 {P0 = discode[disbuff[posit]];}                //赋段码的值                
     
	  P2 = positon[posit];              //赋位码的值
     
	  if(++posit>=3)                    //动态扫描,位置的值在0~3之间循环
                                        //++posit:使用posit之前先递增它
	  posit = 0;
	}
    
    
    
/********************************************************/
    void Conut(void)
	{
	 time=TH0*256+TL0;              //这个就是你的定时器的初值是零,然后你的ECHO=1后就开启定时器
	 TH0=0;                         //等待接收信号,ECHO=0时,计时结束
	 TL0=0;
	
	 S=(time*1.7)/100;     //算出来是CM
        
	 if((S>=700)||flag==1) //超出测量范围显示“-”
	 {	 
	  flag=0;
	  disbuff[0]=10;	   //显示横杠
	  disbuff[1]=10;	   //  "  -  "
	  disbuff[2]=10;	   //  "  -  "
	 }
	 else
	 {
	  disbuff[0]=S%1000/100;
	  disbuff[1]=S%1000%100/10;
	  disbuff[2]=S%1000%10 %10;
	 }
	}
    
    
    
    
/********************* T0中断用来计数器溢出,超过测距范围***********************************/
     void zd0() interrupt 1 		
  {
    flag=1;							 //中断溢出标志
  }
  
  
  
  
/******************* T1中断用来扫描数码管和计800MS启动模块*************************************/
   void  zd3()  interrupt 3 		
  {
      
	 TH1=0xf8;
	 TL1=0x30;
	 Display();
      
	 timer++;
	 if(timer>=400)                 //计数超过400次,即800ms,启动模块
	 {
	  timer=0;
         
	  TRIG=1;			                
	  _nop_();                      //空函数,发送10us以上高电平给Trig
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_();
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_();
	  TRIG=0;
	 } 
  }





猜你喜欢

转载自blog.csdn.net/qq_36192043/article/details/80961758
今日推荐