使用单片机实现 HC-SR04 超声波测距模块 的功能,通常用于测量物体与超声波传感器之间的距离。HC-SR04 模块通过发射超声波信号并测量其返回时间来计算距离。单片机(如 STM32、51 系列、Arduino 等)可用来控制该模块的工作,并处理返回的脉冲信号。
下面我会提供一个基于单片机的 HC-SR04 超声波测距实现方案,并详细阐述每个步骤的设计思路和代码实现。
1. HC-SR04 超声波模块工作原理
HC-SR04 模块通过发送一系列声波脉冲来测量与目标物体的距离。模块由两部分组成:
- 发射部分(Trigger):用来发送 10 微秒的脉冲,激发超声波信号的发送。
- 接收部分(Echo):接收从目标物体反射回来的超声波脉冲,产生一个持续高电平的信号,持续时间等于声波往返的时间。
计算公式:
距离 = (回波时间 × 声速) / 2
-
声速约为 340 m/s(即 0.034 cm/μs),所以计算的公式为:
上式中,回波时间指的是从发送脉冲到接收到返回信号的时间。
2. 硬件连接
HC-SR04 模块有四个引脚:
- VCC:电源(通常为 5V)
- GND:地线
- Trig:触发引脚(用于发射超声波脉冲)
- Echo:回声引脚(接收返回的超声波脉冲)
单片机的引脚连接方式:
- Trig:连接到单片机的一个 GPIO 引脚,用于触发超声波发射。
- Echo:连接到单片机的另一个 GPIO 引脚,用于接收回声信号。
3. 设计思路
本设计采用单片机控制 HC-SR04 模块,通过控制 Trig
引脚生成超声波触发脉冲,并通过 Echo
引脚测量回波信号的持续时间。具体的步骤包括:
- 触发超声波信号:通过向
Trig
引脚输出一个 10 微秒的高电平脉冲,激发 HC-SR04 发射超声波。 - 测量回波时间:通过读取
Echo
引脚的高电平持续时间来计算回波时间。单片机根据此时间计算距离。 - 计算距离:根据回波时间和声速公式计算物体到传感器的距离。
4. 软件设计
以 STM32 微控制器为例,介绍如何实现该功能。可以使用 STM32 的 HAL 库来实现超声波测距。
4.1 初始化 GPIO
首先需要初始化 GPIO 引脚:
Trig
引脚配置为输出模式,用于发射触发脉冲。Echo
引脚配置为输入模式,用于接收回波信号。
#include "stm32f4xx_hal.h"
#include <stdio.h>#define TRIG_PIN GPIO_PIN_0 // Trig 引脚
#define ECHO_PIN GPIO_PIN_1 // Echo 引脚
#define GPIO_PORT GPIOA // 假设使用 GPIOA 端口void SystemClock_Config(void);
void GPIO_Init(void);
void trigger_ultrasonic_pulse(void);
uint32_t read_echo_pulse(void);
float calculate_distance(uint32_t pulse_width);int main(void)
{HAL_Init(); // 初始化 HAL 库SystemClock_Config(); // 配置系统时钟GPIO_Init(); // 初始化 GPIO 引脚while (1){trigger_ultrasonic_pulse(); // 触发超声波信号uint32_t pulse_time = read_echo_pulse(); // 获取回波时间float distance = calculate_distance(pulse_time); // 计算距离// 可以通过串口输出距离值,或者在 LCD 上显示printf("Distance: %.2f cm\n", distance);HAL_Delay(500); // 每 500 毫秒测量一次}
}// 系统时钟配置函数(根据具体硬件配置)
void SystemClock_Config(void)
{// 这里可以根据需要配置时钟,一般不需要修改
}// GPIO 初始化:配置 Trig 为输出,Echo 为输入
void GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};// 启用 GPIO 时钟__HAL_RCC_GPIOA_CLK_ENABLE();// 初始化 Trig 引脚(输出)GPIO_InitStruct.Pin = TRIG_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);// 初始化 Echo 引脚(输入)GPIO_InitStruct.Pin = ECHO_PIN;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);
}// 触发超声波信号:生成 10 微秒的脉冲
void trigger_ultrasonic_pulse(void)
{HAL_GPIO_WritePin(GPIO_PORT, TRIG_PIN, GPIO_PIN_SET); // Trig 引脚置高HAL_Delay(0); // 保持高电平至少 10 微秒HAL_GPIO_WritePin(GPIO_PORT, TRIG_PIN, GPIO_PIN_RESET); // Trig 引脚置低
}// 读取 Echo 引脚的高电平持续时间(脉冲宽度)
uint32_t read_echo_pulse(void)
{uint32_t pulse_width = 0;// 等待 Echo 引脚为高电平while (HAL_GPIO_ReadPin(GPIO_PORT, ECHO_PIN) == GPIO_PIN_RESET);// 计数 Echo 引脚高电平的持续时间while (HAL_GPIO_ReadPin(GPIO_PORT, ECHO_PIN) == GPIO_PIN_SET){pulse_width++; // 每次延时 1 毫秒HAL_Delay(1); // 延时 1 毫秒,计数单位是毫秒}return pulse_width; // 返回脉冲宽度(单位:毫秒)
}// 根据回波时间计算距离(单位:cm)
float calculate_distance(uint32_t pulse_width)
{// 使用公式:距离 (cm) = (回波时间 (微秒) * 0.034) / 2// 由于我们在 read_echo_pulse 函数中每次延时 1 毫秒,pulse_width 其实已经是毫秒单位。float distance = pulse_width * 0.034 / 2.0; // 公式:距离 = 时间 * 声速 / 2return distance;
}
代码解读
-
初始化 GPIO
GPIO_Init()
函数初始化了两个 GPIO 引脚:- Trig 引脚(GPIO_PIN_0):用于触发超声波发射,配置为推挽输出模式。
- Echo 引脚(GPIO_PIN_1):用于接收超声波回波信号,配置为输入模式。
-
触发超声波发射信号
trigger_ultrasonic_pulse()
函数通过在Trig
引脚输出一个 10 微秒的高电平脉冲来激发 HC-SR04 模块发射超声波信号。
-
测量回波时间
read_echo_pulse()
函数通过读取Echo
引脚的高电平持续时间来获取回波信号的时长。通过pulse_width
计数,记录回波信号持续的时间。
-
计算距离
calculate_distance()
函数根据回波信号的时长(pulse_width
)和声速公式来计算物体与传感器的距离:
-
主循环
- 在
main()
函数中,程序会不断触发超声波信号,并读取回波时间,通过计算得到距离,最后打印出距离值。每次测量之间有 500 毫秒的延时。
- 在
5. 项目总结
5.1 硬件总结
- HC-SR04 超声波模块:通过发射和接收超声波信号来测量距离,连接到单片机的 GPIO 引脚(
Trig
和Echo
)。 - 单片机:负责控制
Trig
引脚生成脉冲,并读取Echo
引脚的高电平持续时间,计算并输出距离。
5.2 软件总结
- GPIO 初始化:配置
Trig
为输出,Echo
为输入。 - 触发超声波信号:通过给
Trig
引脚发送 10 微秒的高电平脉冲来激发 HC-SR04 发射超声波。 - 回波时间测量:通过读取
Echo
引脚的高电平持续时间,计算超声波往返所需的时间。 - 距离计算:根据回波时间和声速公式计算距离,并输出测量结果。
5.3 优化与扩展
- 更高精度:为了获得更高精度的距离,可以增加计时的精度(例如,使用定时器或更高分辨率的计时方法)。
- 多次测量平均值:可以通过多次测量距离并取平均值来提高测量的稳定性和精度。
- 串口输出:通过串口将测量的距离数据发送到 PC 或其他设备进行显示。
- 电源管理:对于电池供电的系统,可以在不需要测量时关闭超声波模块,以节省电量。
通过以上设计,我们成功实现了使用单片机控制 HC-SR04 超声波模块进行测距的功能,并能够在不同的应用场景下测量距离。