使用单片机实现超声波测距——蓝桥杯竞赛题目
蓝桥杯单片机之超声波测距
测距原理
基本原理
超声波发射模块向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。
计算公式
距离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();
}
}