深入了解HC-SR04超声波模块,一文全解析
一,引脚定义与工作特性
VCC:电源电压3.3V-5V
Trig:信号发送控制引脚
Echo:信号接收控制引脚
GND:电源地、电源负
测量距离:2cm-400cm(3.3v)、2cm-450cm(5V)
探测角度:<15°
工作温度:-20℃~80℃
二,工作原理与驱动方式
工作原理:
超声波的工作原理很简单,就是声音遇到障碍物会反弹,我们只需要计算超声波从发送到反弹回来的时间间隔,就可以根据速度与位移的公式,计算距离。
时序分析:
Trig置高电平至少10us之后置低电平,成功激活之后,发送探头会向外发送40kHz的超声波信号,当发送结束时候,Echo引脚从低电平开始置高电平,直到接收探头收到反弹回来的超声波信号之后,Echo引脚从高电平变成低电平,Echo高电平的时间就是超声波经过障碍物反弹回来的时候,通过声速即可计算距离。
距离=[Echo高电平时间*声速(340m/s)] / 2
这里除与2是因为时间包括发送和接收,我们只需要其中一个就可以了,又因为发送与接收的时间是相等的,所以除于2取其中一个即可。
三,51单片机的程序代码
这里使用的是STC15F2K60S的芯片,如果是ST89C51的芯片也可以使用,不过需要修改一下晶振于计算公式。
Length=(TH0<<8 | TL0)*0.034/2.0; //12Mhz晶振
Length=(TH0<<8 | TL0)*0.034/4.0; //24Mhz晶振
其他的晶振可以按照我下面的注释中介绍,有疑问的话,可以在评论区讨论。
HC-SR04.C
距离的具体计算公式可以看代码的注释。
#include "csb/csb.h"
/*
定时器初始化函数
返回:无
*/
void Timer0_Init(void) //STC15@24.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //16位不自动重装初始值
TMOD |= 0x01;
TL0 = 0; //设置定时初始值
TH0 = 0; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0停止计时
ET0 = 0; //禁止定时器0中断
}
/*
10us延时函数
*/
void Delay10us() //STC15@24.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 57;
while (--i);
}
/*
超声波测量函数
单位:厘米
返回:距离的浮点数
*/
float CSB_Mesure(void)
{
float temp;
TH0=TL0=0; //计数值寄存器清零
Trig_Pin=1; //发送端口拉高20us
Delay10us();
Delay10us();
Trig_Pin=0; //发送端口拉低
while(Echo_Pin==0); //接收引脚等待置1
TR0=1; //开始定时器
while(Echo_Pin==1 && TF0==0); //接收完成
TR0=0; //关闭定时器
temp=(TH0<<8 | TL0)*0.034/4.0;//计算距离,对于(12T定时器,24Mhz晶振)
//定时器一个计数的时间长度t=1/(24Mhz/12)=0.5us
//s=T*v/2=x*0.5(us)*340(m/s)/2,其中x为定时器的计数值
//T=x*t、x=(TH0<<8 | TL0),8个八位组成16位
//所以:Length=(TH0<<8 | TL0)*0.034/4.0
if(TF0) //如果定时器溢出,返回999
{
TF0=0;
return 999.0;
}
return temp;
}
/*
超声波测量函数
单位:厘米
返回:距离的整数
*/
unsigned int CSB_Mesure_Byte()
{
unsigned int temp;
TH0=TL0=0;
TX=0;
TX=1;
Delay10us();
Delay10us();
TX=0;
while(!RX);
TR0=1;
while(RX && !TF0);
TR0=0;
temp=(TH0<<8 | TL0)*0.034/4;
if(TF0)
{
TF0=0;
temp=999;
}
return temp;
}
HC-SR04.h
#ifndef _CSB_H_
#define _CSB_H_
#include <STC15F2K60S2.H>
#include "intrins.h"
sbit Trig_Pin=P1^4;//引脚定义
sbit Echo_Pin=P1^5;
void Delay10us(); //@24MHz
float CSB_Mesure(void);//厘米
unsigned int CSB_Mesure_Byte();
void Timer0_Init(void);
#endif
改代码可以直接复制到自己新建的文件里面使用即可。
作者:佛科院小迷弟