HC-SR04超声波传感器模块的原理核心在于其工作时序,具体使用方法则依赖于主控芯片(如STM32)的GPIO控制与定时器输入捕获功能。以下是其详细解析与实现方案。
一、 HC-SR04 模块工作原理与时序
HC-SR04模块通过Trig引脚接收触发信号,内部电路产生超声波脉冲,并通过Echo引脚返回一个高电平脉冲,其宽度与超声波往返时间成正比。
工作时序是理解其原理的关键,具体步骤如下:
- 触发阶段:主控芯片向Trig引脚发送一个至少10μs的高电平脉冲信号。
- 模块响应:模块内部自动发射8个40kHz的超声波脉冲。
- 回波检测:模块检测回波,并将Echo引脚拉高。
- 结果输出:Echo引脚高电平的持续时间(即脉冲宽度)即为超声波从发射到返回的时间
t。 - 距离计算:根据公式
距离 = (t * 声速) / 2计算。常温下声速约为340m/s,因此距离(cm) ≈ (t(us) / 58)或距离(cm) ≈ (t(us) * 0.034) / 2。
其工作时序可概括为下表:
| 步骤 | Trig引脚 | Echo引脚 | 模块内部动作 |
|---|---|---|---|
| 1. 初始化 | 低电平 | 低电平 | 空闲状态 |
| 2. 触发 | ≥10μs高电平 | 低电平 | 收到触发信号,发射8个40kHz超声波 |
| 3. 回波等待 | 恢复低电平 | 由低变高 | 开始计时,等待回波 |
| 4. 回波返回 | 保持低电平 | 保持高电平 | 接收到回波 |
| 5. 输出结果 | 保持低电平 | 由高变低 | 输出结束,高电平持续时间即为超声波往返时间 t |
二、 基于STM32与HAL库的驱动实现
以下以STM32F103C8T6为例,使用HAL库演示完整的驱动流程,包含GPIO初始化、触发信号发送和通过输入捕获模式测量Echo高电平时间。
1. 硬件连接
| HC-SR04引脚 | STM32引脚 | 功能说明 |
|---|---|---|
| VCC | 5V | 供电 |
| Trig | PA0 (GPIO输出) | 触发信号输出 |
| Echo | PA1 (GPIO输入/定时器通道) | 回波信号输入 |
| GND | GND | 共地 |
2. 代码实现
步骤一:GPIO与定时器初始化
配置Trig为推挽输出,Echo为上拉输入。同时配置一个定时器(如TIM2)用于输入捕获。
// HC_SR04.h
#ifndef __HC_SR04_H
#define __HC_SR04_H
#include "main.h"
#define TRIG_PIN GPIO_PIN_0
#define TRIG_PORT GPIOA
#define ECHO_PIN GPIO_PIN_1
#define ECHO_PORT GPIOA
void HC_SR04_Init(void);
float HC_SR04_Get_Distance(void);
#endif
// HC_SR04.c
#include "hc_sr04.h"
#include "tim.h" // 假设已配置TIM2用于输入捕获
// 初始化函数
void HC_SR04_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 配置Trig引脚为输出
GPIO_InitStruct.Pin = TRIG_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(TRIG_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET); // 初始化为低电平
// 配置Echo引脚为输入(也可配置为定时器输入捕获通道,见下文)
GPIO_InitStruct.Pin = ECHO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉,确保空闲时为高电平
HAL_GPIO_Init(ECHO_PORT, &GPIO_InitStruct);
// 启动定时器(以TIM2为例,1MHz计数频率,即1us计数一次)
HAL_TIM_Base_Start(&htim2);
}
步骤二:发送触发信号与测量脉冲宽度(查询法)
一种简单的方法是使用查询方式测量Echo高电平时间。
// HC_SR04.c (续)
float HC_SR04_Get_Distance(void) {
uint32_t start_time = 0, end_time = 0, pulse_width = 0;
float distance_cm = 0.0;
// 1. 发送至少10us的Trig高电平脉冲
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);
delay_us(12); // 延时12微秒,略大于最小值
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);
// 2. 等待Echo变为高电平(超声波发射开始)
while(HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_RESET);
start_time = __HAL_TIM_GET_COUNTER(&htim2); // 记录开始时间戳
// 3. 等待Echo变为低电平(回波接收结束)
while(HAL_GPIO_ReadPin(CHO_PORT, ECHO_PIN) == GPIO_PIN_SET);
end_time = __HAL_TIM_GET_COUNTER(&htim2); // 记录结束时间戳
// 4. 处理定时器溢出(如果定时器是16位,如65ms溢出一次)
if(end_time < start_time) {
pulse_width = (0xFFFF - start_time) + end_time + 1;
} else {
pulse_width = end_time - start_time;
}
// 5. 计算距离:距离(cm) = 时间(us) / 58
distance_cm = pulse_width / 58.0;
// 6. 增加简单的滤波(例如,只接受2cm-400cm范围内的值)
if(distance_cm > 400.0 || distance_cm < 2.0) {
distance_cm = 0.0;
}
return distance_cm;
}
步骤三:主循环调用
// main.c
#include "hc_sr04.h"
int main(void) {
HAL_Init();
SystemClock_Config();
HC_SR04_Init();
while (1) {
float dist = HC_SR04_Get_Distance();
// 通过串口打印距离信息
printf("Distance: %.2f cm
", dist);
HAL_Delay(100); // 每100ms测量一次
}
}
3. 进阶:使用输入捕获模式提高精度
查询法会占用CPU。更高效、精确的方法是使用定时器的输入捕获功能。配置定时器的一个通道(如TIM2_CH1)连接到Echo引脚,在上升沿和下降沿触发捕获中断,自动记录时间戳。
关键配置与代码逻辑如下:
- 定时器配置:将TIM2通道1配置为输入捕获模式,双边沿触发。
- 中断处理:在捕获回调函数中,计算两次捕获(上升沿和下降沿)的时间差。
// 在输入捕获中断回调函数中的示例逻辑
uint32_t ic_val1, ic_val2;
uint32_t difference;
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
if(is_first_capture == 0) { // 第一次捕获,上升沿
ic_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);
is_first_capture = 1;
} else if(is_first_capture == 1) { // 第二次捕获,下降沿
ic_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
if(ic_val2 > ic_val1) {
difference = ic_val2 - ic_val1;
} else {
difference = (0xFFFF - ic_val1) + ic_val2;
}
distance_cm = difference / 58.0;
is_first_capture = 0;
}
}
三、 应用注意事项与优化
- 测量周期:两次测量之间需间隔至少60ms,以防止信号干扰。
- 温度补偿:声速受温度影响。为提高精度,可集成温度传感器(如DS18B20),使用公式
V = 331.4 + 0.6 * T(m/s) 动态计算声速,其中T为摄氏温度。 - 滤波处理:实际应用中需加入软件滤波(如中值滤波、均值滤波)以消除偶然误差。
- 测量范围:HC-SR04的有效测距通常为2cm至400cm,超出此范围的回波信号可能不可靠。
- 硬件连接:若测量不稳定,可在VCC和GND之间并联一个100uF的电解电容以稳定电源,并在Trig和Echo信号线上串联一个100-200欧姆的电阻以抑制过冲。
参考来源
- HC-SR04 超声波原理图讲解与时序分析与arduino使用
- 【STM32】超声波传感器HC-SR04知识
- STM32_超声波测距(HC_SR04)超详细讲解!!!
- STM32驱动HC-SR04超声波模块
- 基于STM32F103C8T6的超声波测距应用
- STM32+HAL库驱动超声波测距传感器(HC-SR04)

3万+

被折叠的 条评论
为什么被折叠?



