测距原理

基本原理

在这里插入图片描述

超声波发射模块向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。

计算公式

距离L = 声速V × 发出到接收的时间T/2

电路分析

发射电路:
在这里插入图片描述
接收电路:
在这里插入图片描述
超声波测距与红外线测距模式调整跳帽:
在这里插入图片描述

超声波传感器的谐振频率(中心频率)有23kHz、40kHz、75kHz、200kHz、400kHz等,蓝桥杯CT107D使用谐振为40KHZ的超声波。
使用超声波模块前需要将跳帽的1-3 , 2-4连接!!!
其中发送端N_A1连接单片机的P10引脚,接收端N_B1连接单片机的P11引脚。

所以我们只要控制发送端P10发送信号并开启定时器定时,然后监听接收端P11是否接收到信号(改变成低电平),从而得到我们需要的时间参数。

代码设计

基本步骤

1-产生8个40KHz的超声波信号,通过TX引脚发射出去。

2-启动定时器,计算计数脉冲。

3-监听接收端引脚,如果接收到反射回来的信号,RX引脚变为低电平。

4-停止定时器,读取脉冲个数,即获得时间T。

5-根据公式,L = V * T /2m,进行距离的计算。

代码编写:

#include "reg52.h"
#include "intrins.h"
 
sbit TX = P1^0;
sbit RX = P1^1;
 
unsigned int distance = 0;
 
unsigned char SMG_NoDot[19] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0xff}; //0-9、A-F、'-'、'.'
 
void Delay500us()		//@12.000MHz
{
	unsigned char i, j;

	i = 6;
	j = 211;
	do
	{
		while (--j);
	} while (--i);
}

void Digital_Tube(unsigned char Position,unsigned char Typeface)    //Position是数码管第几位(从左到右,0开始),Typeface是显示的字样
{   
    unsigned char Bit[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};       
		P2 = P2 & 0x1f | 0xc0;
		P0=Bit[Position];
		P2 = P2 & 0x1f | 0xe0;
		P0=SMG_NoDot[Typeface];
		Delay500us();
		P0=0XFF;
		P2 = P2 & 0x1f ;	//数码管消影
}
 
void Display_right(long int number)
{
    long int i,a,b;
    for(i=0;i<8;i++)
    {
        a=number%10;
        Digital_Tube(7-i,a);
        b=number/10;
        if(b==0) break;
        number=b;
    }
}

void Display_Sonic()
{
	if(distance == 500)
	{
			P2 = P2 & 0x1f | 0xc0;
			P0=0x01;
			P2 = P2 & 0x1f | 0xe0;
			P0=0x8e;
	}
	else
	{
		Display_right(distance);
	}
}
 
void Delay14us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 39;
	while (--i);
}

 
void Send_Wave()                 //产生8个40KHx超声波信号
{
	unsigned char i;
	for(i = 0; i < 8; i++)
	{
		TX = 1;
		Delay14us();	
		TX = 0;
		Delay14us();
	}
}
 
void Measure_Sonic()	        //超声波测距
{
	unsigned int time = 0;
	
	TMOD &= 0x0f;	            //定时器1模式0,16位,最大85535个计数脉冲《stc15系列!!!》								
	TL1 = 0x00;										
	TH1 = 0x00;		
	
	Send_Wave();		        //发送超声波信号							
	TR1 = 1;            //启动定时器						
	while((RX == 1) && (TF1 == 0));    //等待超声波信号返回或者等到测量超出范围
	TR1 = 0;            //停止定时器				
	
	if(TF1 == 0)	            //正常测量范围,根据定时器溢出标志位来判断是否有效						
	{
		time=TH1;		
		time = (time << 8) | TL1;		
		distance =(time*17/1000 )  + 3;	//需要根据实际的情况进行微调;(time/2/1000 000 * 340 ) *100 + 3;因为distance为unsigned int型,所以计算机计算时不能超过范围
	}
	else          //超出测量范围:当定时器溢出时,也就是定时器计数了85535次,相当于0.085535秒,得到的距离为29.4米,远远超出测量范围
	{
		TF1 = 0;
		distance = 500;
	}
}
 
void main()
{
	while(1)
	{
		Measure_Sonic();
		Display_Sonic();
	}
}
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐