HY_SRF05工作原理
引脚封装
电气参数
工作原理
解释:
第一步:由单片机控制TRIG产生10us的高电平
第二步:HY_SRF05会向外发射8个40kHz的脉冲进行探测
第三步:HY_SRF05对反射回来的脉冲进行处理,并将ECHO引脚电平拉高(高电平持续的时间与探测的距离成正比)
第四步:单片机对ECHO引脚高电平持续的时间进行记录并处理,算出探测距离,距离=(高电平持续时间×声速340m/s)/2
数码管模块
源文件部分
位码部分使用了74HC138译码器
//共阴极数码管显示 0~F 的段码数据
uchar CNDT_display[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*******************************************************************************
* 函 数 名 : smg_display
* 函数功能 : 动态数码管显示
* 输 入 : dat:要显示的数据
pos:从左开始第几个位置开始显示,范围1-8
* 输 出 : 无
*******************************************************************************/
void smg_display(uchar dat[],uchar pos)
{
uchar i=0;
uchar pos_temp=pos-1;
for(i=pos_temp;i<8;i++)
{
switch(i)//位选
{
case 0:A2=1,A1=1,A0=1;break;
case 1:A2=1,A1=1,A0=0;break;
case 2:A2=1,A1=0,A0=1;break;
case 3:A2=1,A1=0,A0=0;break;
case 4:A2=0,A1=1,A0=1;break;
case 5:A2=0,A1=1,A0=0;break;
case 6:A2=0,A1=0,A0=1;break;
case 7:A2=0,A1=0,A0=0;break;
}
segmentCodePort=dat[i-pos_temp];//传送段选数据
delay10us(100);//延时一段时间,等待显示稳定
segmentCodePort=0x00;//消影
}
}
头文件部分
#ifndef LEDdigitalTube_h
#define LEDdigitalTube_h
#include<reg52.h>
#include"Delay.h"
#include"keyword_rename.h"
/* 74HC138译码器脚口定义 */
sbit A2=P2^4;
sbit A1=P2^3;
sbit A0=P2^2;
/* 函数声明 */
void smg_display(uchar dat[],uchar pos);
/* 段码声明 */
extern uchar CNDT_display[17];
/* 段码连接脚口定义 */
sfr segmentCodePort = 0x80;
#endif
超声波模块
源文件部分
#include"HY_SRF05.h"
float HY_SRF05_distance_data;
/*
函 数 名:HY_SRF05Delay10us
函数功能:用于HY_SRF05触发控制产生10us高电平
输 入:无
输 出:无
*/
void HY_SRF05Delay10us() //@11.0592MHz
{
unsigned char i;
i = 4;
while (--i);
}
/*
函 数 名:HY_SRF05Init
函数功能:初始化HY_SRF05
输 入:无
输 出:无
*/
void HY_SRF05Init()
{
TMOD|=0x01;//定时器初始化
TH0=0x00;
TL0=0x00;;
TR0=0;
EA=1;//中断初始化
EX0=1;
IT0=1;
HY_SRF05_TRIG=1;//触发信号线拉低
HY_SRF05_ECHO=0;//回响信号线拉低
}
/*
函 数 名:HY_SRF05Tigger
函数功能:发送10us的触发控制信号
输 入:无
输 出:无
*/
void HY_SRF05Tigger()
{
uint wait_ECHO_time=200; //等待回响时间,需不断调适,找到合适的等待时间
/*
等待时间过长会影响单片机的工作效率
等待时间过短会导致回响信号来不及建立
*/
HY_SRF05_ECHO=0; //释放回响输出线
HY_SRF05_TRIG=0; //释放触发控制线
HY_SRF05_TRIG=1;
HY_SRF05Delay10us();//产生10us高电平
HY_SRF05_TRIG=0;
while(!HY_SRF05_ECHO)
{
if(!wait_ECHO_time--) return; //若无回响信号则退出函数
}
TR0=1; //接收到回响信号后开始计时(一次约1us)
}
/*
函 数 名:RecordTime
函数功能:用于记录回响信号持续的时间并计算距离(单位:cm)
输 入:无
输 出:无
*/
void RecordTime() interrupt 0
{
uchar time_H,time_L;
uint time_all;
TR0=0;
time_H=TH0;
time_L=TL0;
time_all=time_H*256+time_L;
HY_SRF05_distance_data=(float)(time_all*0.017);
/*
距离(cm)=[时间(us)*10^(-6)]*[340*(10^2)(cm/s)]/2
=时间(us)*0.017
*/
TH0=0,TL0=0; //计时清零
}
头文件部分
#ifndef HY_SRF05_h
#define HY_SRF05_h
#include"keyword_rename.h"
#include"LEDdigitalTube.h"#include<reg52.h>
#include"Delay.h"
/* 引脚定义 */
sbit HY_SRF05_TRIG=P1^1; //触发控制,信号输入引脚
sbit HY_SRF05_ECHO=P3^2; //信号回响,信号输出引脚
/* 函数声明 */
void HY_SRF05Init();
void HY_SRF05Tigger();
/* 变量声明 */
extern float HY_SRF05_distance_data; //测量的距离数据
#endif
主函数部分
#include<reg52.h>
#include"Delay.h"
#include"HY_SRF05.h"
#include"keyword_rename.h"
#include"LEDdigitalTube.h"
/* 数码管显示距离(单位:cm,精确到小数点后一位) */
void DataDisplay()
{
uchar per_data[4]; //保存距离的每位数据
uint data_change;
uchar i=0;
data_change=(unsigned int)(HY_SRF05_distance_data*10);
per_data[0]=CNDT_display[data_change/1000];//百位
per_data[1]=CNDT_display[data_change%1000/100];//十位
per_data[2]=CNDT_display[data_change%100/10]|0x80;//
per_data[3]=CNDT_display[data_change%10];//小数点后一位
smg_display(per_data,5); //显示距离
}
void main()
{
uchar time=0; //用于每次探测的时间间隔
HY_SRF05Init();
while(1)
{
time++;
if(time>=25) //time的值需要不断调试,找到最合适的时间间隔
{
time=0;
HY_SRF05Tigger();
}
/*
探测频率过快会导致数据处理异常(第一次数据返回还没完成,
第二次探测开始强行把回响信号线拉低,导致计时小于实际时间)
探测频率过慢会导致距离信息更新不及时
*/
DataDisplay();
}
}
正常现象演示
HY_SRF05超声波测距模块
探测频率过快现象演示
探测时间过短现象演示
探测频率过慢现象演示
探测时间间隔过长现象演示