基本介绍
HC-SR04超声波测距模块是一种常用的测距传感器。该模块通过发射一定频率的超声波脉冲,然后接收反射回来的超声波脉冲,从而测量出目标物体与模块之间的距离。
其测距原理基于声速在空气中传播的速度以及声波的发射和反射时间计算得出。首先,MCU向超声波测距模块发送一个高电平脉冲来触发发射器,发射器就会发射超声波。当超声波遇到障碍物后,会发生反射。接受器就会收到这些反射波,然后把信号传回到MCU,并计算出来传播时间。通过时间和声速的乘积,就可以得到目标物体与超声波测距模块之间的距离。
HC-SR04超声波测距模块一般需要至少四个引脚进行连接。其中,VCC和GND引脚分别连接到电源正负极,而Trig和Echo引脚则需要连接到控制器的数字输入输出引脚上。
具体来说,Trig引脚接收到高电平的触发信号后,触发超声波发射器开始发射超声波,在发射后10微秒内,Echo引脚会返回一个高电平信号,表示已经收到了反射波。然后,控制器就会记录下Echo引脚的高电平持续时间就可以计算出距离。
本模块有一个接口:4 Pin
供电及通信接口。为
2.54mm
间距的弯排针,如图
4所示:
从左到右依次编号1,2,3,4。它们的定义如下:
1号
Pin
:接
VCC
电源(直流
3V-5.5V)。
2号
Pin
:接外部电路的
Trig
端,向此管脚输入一个
10uS以上的高电平,可触发模块测距。
3号
Pin
:接外部电路的
Echo端,当测距结束时,此管脚会输出一个高电平,电平宽度为超声波往返时间之和。
4号
Pin:接外部电路的地。
需要注意的是,需要在代码中加入一定的延时来等待信号的传输和回传,从而准确计算出距离。同时,在进行超声波测距时,应避免在靠近模块的距离内进行测试,以免信号干扰引起精度变化,并且需要在测试时按照实际情况进行多次测量并取平均值,以提高测量的准确度。
测距工作原理
模块测距的时序如图 5 所示:
图 5 表明:只需要在 Trig 管脚输入一个10US以上的高电平,系统便可发出8个40KHZ的超声波脉冲,然后检测回波信号。当检测到回波信号后,通过 Echo 管脚输出。
根据 Echo 管脚输出高电平的持续时间可以计算距离值。即距离值为:(高电平时间*340m/s)/2。
当测量距离超过 HC-SR04 的测量范围时,仍会通过 Echo 管脚输出高电平的信号,高电平的宽度约为 66ms。如图 6 所示:
测量周期:当接收到 HC-SR04 通过 Echo 管脚输出的高电平脉冲后,便可进行下一次测量,所以测量周期取决于测量距离,当距离被测物体很近时,Echo 返回的脉冲宽度较窄,测量周期就短;当距离被测物体比较远时,Echo 返回的脉冲宽度较宽,测量周期也就相应的变长。
最坏情况下,被测物体超出超声波模块的测量范围,此时返回的脉冲宽度最长,约为 66ms,所以最坏情况下的测量周期稍大于 66ms 即可(取 70ms 足够)。
实现的程序
实现的功能是使用stm32f103实现超声波传感器前方10cm内有障碍物时,蜂鸣器会响,并且随着距离变小,蜂鸣器声音频率会变快,同时在0.96寸oled显示屏上显示距离参数。
主函数模块:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
#include "HCSR04.h"
#include "Buzzer.H"
uint64_t numlen(uint64_t num)//计算数字的长度
{
uint64_t len = 1; // 初始长度为1
for(; num > 9; ++len) // 判断num是否大于9,否则长度+1
num /= 10; // 使用除法进行运算,直到num小于1
return len; // 返回长度的值
}
int main(void)
{
OLED_Init(); //初始化OLED屏
Timer_Init(); //初始化定时器
HC_SR04_Init(); //初始化超声波测距模块
Buzzer_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 打开 GPIOA 时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // PA0 引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits (GPIOA,GPIO_Pin_3);
OLED_ShowString(1, 1, "Distance:"); //OLED屏输出字符串
while (1)