超声波模块专题(STC89C52RC芯片为例)

//以下代码适用于51单片机

一、应用场景及作用

应用场景:超声波测距

原理:发送并接收自身发送的超声波,通过计算发收时间间隔,计算与障碍物的距离。

模块:HC-SR04

二、功能实现

1、时序理解

(以HC-SR04为例)

时序图理解
在这里插入图片描述

//以下超声波模块均称为模块

原理解释:单片机通过发送引脚Tx,给超声波模块的Trig引脚发送触发信号。触发信号为10us的高电平。之后超声波模块会自动发射8个脉冲信号,并自动接收。模块会自行处理。通过Echo引脚返回给单片机一个回响信号。该信号返回的信号时长与脉冲发收的时长相同。之后,单片机的接受引脚Rx,会接收这个回响信号,并记录回响信号的持续时间。最终计算出距离。

2、计算公式

距离计算公式:S/2 = VT
超声波速度,默认为光速,V=340m/s
时间T,为定时器计算的时间,单位为微秒us
换算后:S = T/58(cm) 或者 S = T*0.017(cm)

3、代码逻辑实现

3.1距离检测代码

代码讲解://以下代码需补全调整后才可使用

int Distance_detect(void)
{
        //启动超声波模块(开始测量)
//      P2_1 = 0;//确保前面是低电平。保护性代码,可不加
//      Delay10us();//延时10us
        Tx = 1;//拉高10us
        Delay10us();//延时10us
        Tx = 0;//再拉低
        
        //等待返回信号。当单片机无返回信号时,Rx引脚为低电平
        while(!Rx);
    //补充:该代码没有添加时间溢出时的保护性代码。但实际测试中,并不影响正常使用
        
        TR1 = 1;//开始计时
        while(Rx);//高电平结束。此时单片机接收的是模块的回响信号
        TR1 = 0;//结束计时
        
        //计算距离:
        time = (TH1<<8)|TL1;//计算所用的时间
        distance = time /58;//计算出的距离(cm)
        
        //重置定时器
        TL1 = 0x00;                                //设置定时初始值
        TH1 = 0x00;                                //设置定时初始值
        
        return distance;
}
3.2定时器代码

观察上述代码,发现有TR1,TH1,TL1等变量。这是定时器的变量。接下来讲解定时器的作用。

超声波模块中定时器的作用:用于处理单片机接收到的回响信号,通过微妙级的计数记录,信号的持续时间数据。特别的,此处定时器只起到计数器的作用,且不需要启动中断。

代码讲解:

//定时器1初始化函数
void Timer1_Init(void)		//1微秒@11.0592MHz
{
//	AUXR &= 0xBF;			//定时器时钟12T模式,单片机默认12T
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x10;			//设置定时器模式
	TL1 = 0x00;				//设置定时初始值,从零开始计时
	TH1 = 0x00;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 0;				//定时器1停止计时
//	ET1 = 1;				//不需要使能定时器1中断
//	EA = 1;				//不需要使能中断,只需要计数就可以
}

此外,我们添加模块的测试代码。完成以下的完整代码

4、完整代码

#include "Ultrasound.h"

#define Tx P2_1
#define Rx P2_0

//定义全局变量表示测得的距离
int distance,time;

//定时器1初始化函数
void Timer1_Init(void)		//1微秒@11.0592MHz
{
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x10;			//设置定时器模式
	TL1 = 0x00;				//设置定时初始值,从零开始计时
	TH1 = 0x00;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 0;				//定时器1停止计时
}

//测量距离(单位:cm)
int Distance_detect(void)
{
        //启动超声波模块(开始测量)
        Tx = 1;//拉高10us
        Delay10us();//延时10us
        Tx = 0;//再拉低
        
        //等待返回信号
        while(!Rx);
        
        TR1 = 1;//开始计时
        while(Rx);//高电平结束
        TR1 = 0;//结束计时
        
        //计算距离:
        distance = (TH1<<8)|TL1;//计算所用的时间
        distance = distance /58;//计算出的距离(cm)
        
        //重置定时器
        TL1 = 0x00;                                //设置定时初始值
        TH1 = 0x00;                                //设置定时初始值
        
        return distance;
}

//测试代码
void Ultra_test()
{
	if(Distance_detect() < 30)//障碍在30cm以内
		P3_5 = 0;//该引脚可以是小灯或者蜂鸣器
	else
		P3_5 = 1;
}


三、蓝桥杯代码补充

以上讲述了HC-SR04超声波模块的功能、原理与代码实现逻辑。但在蓝桥杯单片机组的比赛中,使用官方开发板编写超声波测距代码时,却不一样。

原因是:蓝桥杯单片机组开发板的超声波模块采用CX20106A(接收)+74LS04(发送)的分体式设计,需手动发送8个40kHz脉冲并检测回波信号。这与HCSR04的自动触发机制不同。CX20106A为核心芯片,功能是作为超声波接收芯片,负责将接收到的超声波信号放大、滤波并输出电平变化。74LS04 门电路是发射电路,功能是将单片机输出的方波信号放大,驱动超声波发射探头。

这里不具体讲解硬件原理。只提供运行代码。

与HC-SR04不同的是,需要手动发送8个脉冲信号。

完整历程代码

#include "ultrasound.h"
#include "intrins.h"

sbit Tx=P1^0;
sbit Rx=P1^1;

void Delay12us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	_nop_();
	i = 38;//33~50
	while (--i);
}

//8个40kHz脉冲信号
void Ut_Wave_Init()
{
	unsigned char i;
	EA=0;
	for(i=0;i<8;i++)
	{
		Tx=1;
		Delay12us();
		Tx=0;
		Delay12us();
	}
	EA=1;
}
//计算公式
// S=VT/2
// V=340m/s=34000cm/s
// T-> 1us -> 10^(-6)s
// VT/2->0.034cm/2=0.017cm
unsigned char Ut_Wave_Data()
{
	unsigned int time;
	CMOD = 0x00;
	CH=CL=0;
	Ut_Wave_Init();
	CR=1;//开始计时
	while((Rx==1)&&(CF==0));//等待接收到返回信号或者时间溢出
	CR=0;//停止计时
	//不是溢出,而是接收到了返回信号
	if(CF==0)
	{
		time = CH<<8|CL;
		return (time*0.017);
	}
	//没有接收到返回信号,溢出
	else
	{
		CF=0;
		return 0;
	}
}
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐