超声波模块
本文介绍了基于STC89C52RC芯片的超声波测距模块实现方法。主要内容包括:1) 超声波测距原理,通过发送接收超声波信号并计算时间差获取距离;2) 两种常见模块HC-SR04和蓝桥杯开发板专用模块的时序差异;3) 关键代码实现,包括距离检测、定时器初始化和脉冲发送等;4) 距离计算公式(S=T/58cm或S=T*0.017cm)及单位换算。文章提供了完整的示例代码,并针对不同硬件平台给出了具体实
超声波模块专题(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;
}
}
更多推荐



所有评论(0)