目录
【HC-SR04】
HC-HR04超声波测距可提供2cm-400cm的非接触式距离感测功能,测距精度可达3mm。
基本工作原理
1、采用IO口TRIG触发测距,给最少10us的高电平信呈。
2、模块自动发送8个40KHz的方波,自动检测是否有信号返回。
3、有信号返回,通过IO口ECHO输出一个高电平,高电平持续时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340m/s))/2.
时序图
以上时序图表明你只需要提供一个10uS以上脉冲触发信号,该模块内部将:发出8个40kHz周期电平并检测回波。一.旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式: uS/58=厘米或者uS/148=英寸;或是:距离=高电平时间*声速(340M/S) /2;建议测量周期为60ms以上,以防止发射信号对回响信号的影响。
【程序】
我使用的是STC15F2K60S2单片机,内部晶振设置12M。以下程序省略管脚定义等无关语句,仅提供程序思路供参考。
uchar Flag_hypertelorism = 0; //超声波距离过远标志
float distance = 0;
uchar Flag_Fucker = 0; //超声波开启标志
void main()
{
Time0_Init();
Time1_Init();
while(1)
{
if(Flag_Fucker == 1)
Ultrasonic();
}
}
/*初始化定时器0*/
void Time0_Init(void)
{
// AUXR |= 0x80; //定时器0为1T模式
AUXR &= 0x7f; //定时器0为12T模式
TMOD = 0x00; //设置定时器为16位自动重装载
TL0 = 0x60; //初始化计时值 4ms
TH0 = 0xF0;
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
//定时器1初始化
void Time1_Init()
{
// AUXR |= 0x40; //定时器1为1T模式
AUXR &= 0xdf; //定时器1为12T模式
TMOD = 0x00; //设置定时器1为16位自动重装载
TL1 = 0x60; //初始化计时值 4ms
TH1 = 0xF0;
// TR1 = 1; //暂时不开启定时器1计时
ET1 = 1; //使能定时器1中断
EA = 1;
}
/*定时器0中断*/
void Time0 () interrupt 1
{
static uchar time = 0;
// 自动装载模式下可省略
// TL0 = T0MS;
// TH0 = T0MS >> 8;
time++;
if(time == 25) //100ms测距一次
{
time = 0;
Flag_Fucker = 1;
}
}
//定时器1溢出中断
void Time1() interrupt 3
{
Flag_hypertelorism = 1; //超声波距离过远
}
//超声波测距
void Ultrasonic()
{
uchar i;
Trig = 1; //超声波触发信号开启
_nop_(); //延时10us以上
i = 30;
while(--i);
Trig = 0; //超声波触发信号关闭
while(!Echo); //Echo为0时等待
TR1 = 1; //开启定时器1计时
while(Echo == 1 && TF1 == 0); //Echo为1时等待
TR1 = 0; //关闭定时器1计时
Distance_Count(); //计算距离
Flag_Fucker = 0; //关闭超声波测距
}
//距离值计算
void Distance_Count()
{
float Text_time = 0;
if(Flag_hypertelorism == 0)
{
Text_time = ((TH1 - temp_TH) * 256 + (TL1 - temp_TL)) / 2.0;
TL1 = 0x60; //初始化计时值 4ms
TH1 = 0xF0;
distance = Text_time * 0.34; //单位mm
}
else
{
distance = 9999;
Flag_hypertelorism = 0;
}
}