SR05超声波测距原理与中断式实现方案(附数据手册)
本文介绍了HC-SR05超声波测距模块的工作原理与中断式实现方案。该模块通过发射40kHz超声波并检测回波时间来计算距离,核心原理包括声速校准(受温度显著影响)和模块工作流程(触发-发射-接收-计算)。文章详细分析了模块参数、测量限制及环境影响因素,并提供了基于STM32的中断式实现方案,包括硬件配置要求和完整代码示例(HAL库)。该方案利用外部中断检测回波信号,结合定时器精确计时,可有效释放CP
SR05超声波测距原理与中断式实现方案
SR05(行业通用型号为HC-SR05,以下统称HC-SR05)是一款低成本、高性价比的超声波测距模块,核心通过超声波的发射、空气传播、障碍物反射与接收,结合声波在空气中的传播速度,计算模块与目标物体的直线距离。其工作逻辑可拆解为“信号触发-声波传播-回波接收-距离计算”四大核心环节,兼具原理简洁性与工程实用性,广泛应用于嵌入式系统测距场景。

一、核心物理基础:超声波特性与声速校准
HC-SR05的测距逻辑依赖超声波的物理特性,其中声速的稳定性直接决定测量精度,需重点关注环境因素对声速的影响:
1. 超声波定义与关键特性
超声波是频率高于20kHz的机械纵波(人耳听觉上限约20kHz),具备两大核心特性:
- 定向传播性:40kHz(HC-SR05工作频率)超声波的波束角较小(约15°-30°),能量集中,适合短距离定向测距;
- 强反射性:遇到密度差异较大的介质界面(如空气-金属、空气-液体)时,会发生明显反射,形成可被检测的“回波”,这是测距的核心前提。
2. 声速的计算与环境校准
超声波在空气中的传播速度并非恒定值,受温度、湿度、气压影响(其中温度影响最显著),需根据实际环境校准:
- 标准声速:在标准大气压(101.325kPa)、干燥空气、25℃ 条件下,声速约为 346m/s(常见简化值340m/s适用于精度要求较低的场景);
- 温度校准公式:精确计算时,声速 ( v )(单位:m/s)与环境温度 ( t )(单位:℃,指空气温度,非模块表面温度)的关系为:
v=331.4+0.607×t v = 331.4 + 0.607 \times t v=331.4+0.607×t - 湿度与气压影响:湿度每增加10%,声速约增加0.1-0.3m/s;气压每变化1kPa,声速约变化0.6m/s,通常在室内环境中可忽略,户外高精度场景需额外校准。
二、HC-SR05模块结构与工作流程
HC-SR05模块由超声波发射器(TXR)、超声波接收器(RXR)、内部控制MCU、电源滤波电路四部分组成(部分简化版省略滤波电路,但核心功能一致),完整工作流程需外部控制器(如单片机)与模块协同完成,共5个步骤:
1. 外部触发:向TRIG引脚输入触发信号
外部控制器需向模块的 TRIG引脚 发送一个 持续时间≥10μs的高电平信号,触发模块进入测距模式:
- 信号要求:高电平持续时间需严格控制(建议10-20μs),过短(<10μs)会导致模块无法识别触发指令,过长(>50μs)可能引发内部MCU误判;
- 示例:STM32单片机通过GPIO口输出15μs高电平,可稳定触发HC-SR05。
2. 声波发射:TXR输出40kHz超声波脉冲
模块内部MCU接收到TRIG触发信号后,会驱动发射器(TXR,通常为压电陶瓷换能器)输出 8个连续的40kHz正弦波脉冲:
- 频率选择原因:40kHz是“测距距离”与“抗干扰能力”的平衡点——低于30kHz易受环境噪音(如电机、风扇)干扰,高于50kHz会导致声波衰减过快(传播距离缩短);
- 脉冲数量:8个脉冲可确保接收器能准确识别“有效信号”,避免单脉冲因环境干扰被误判为噪音。
3. 声波传播与回波接收:RXR捕获反射信号
- 传播阶段:40kHz超声波以球面波形式在空气中传播,遇到障碍物(如墙面、金属板、液体表面)时,部分能量被反射形成“回波”;
- 接收阶段:回波传播至模块时,接收器(RXR,与TXR结构相同,功能为“声-电转换”)将机械波信号转换为微弱的电信号,经内部放大电路(通常为运算放大器)放大后,传递给内部MCU。
4. 回波反馈:ECHO引脚输出高电平计时信号
模块内部MCU检测到放大后的回波电信号后,立即控制 ECHO引脚 输出高电平,直至回波信号消失(或内部超时):
- 高电平持续时间意义:ECHO引脚高电平的 总持续时间 ( t ),等于“超声波从TXR发射到RXR接收”的往返时间(即声波从模块到障碍物再返回模块的总时间);
- 超时机制:若模块在发射声波后 38ms内未接收到回波(对应最大测距距离约6.5m,远超模块标称的4m上限),ECHO引脚会自动拉低,避免长期占用外部控制器资源。
5. 距离计算:外部控制器计算单程距离
外部控制器通过定时器(或中断)读取ECHO引脚高电平的持续时间 ( t ),结合校准后的声速 ( v ),计算模块与障碍物的 单程距离 ( d ):
-
公式推导:声波往返距离 = 声速 × 往返时间 → 单程距离
d=v×t2 d = \frac{v \times t}{2} d=2v×t -
单位换算示例(以25℃环境、声速346m/s为例):
若ECHO高电平持续时间
t=2000μs=2×10−3s t = 2000μs = 2×10^{-3}s t=2000μs=2×10−3s
则:d=346×2×10−32=0.346 m=34.6 cm d = \frac{346 \times 2×10^{-3}}{2} = 0.346 \, \text{m} = 34.6 \, \text{cm} d=2346×2×10−3=0.346m=34.6cm
三、HC-SR05关键参数与应用限制
理解参数特性是避免工程误区的核心,HC-SR05的典型参数与限制如下表所示:
| 参数类别 | 典型值(工业标称) | 详细说明与限制 |
|---|---|---|
| 有效测距范围 | 2cm ~ 400cm | - 近距离(<2cm):回波与发射波叠加,RXR无法区分,导致测量失效; - 远距离(>400cm):声波能量衰减严重,回波信号低于检测阈值,精度下降至±10%以上。 |
| 测量精度 | ±3mm(20-100cm) | - 精度受温度影响:每偏差1℃,精度误差增加约0.2%; - 受障碍物表面影响:镜面/光滑表面(如金属板)反射效率高,精度优;多孔/吸声表面(如海绵)反射弱,误差大。 |
| 工作电压 | 5V DC | 电压波动需控制在±0.2V内,低于4.8V可能导致发射功率不足(测距距离缩短),高于5.2V可能烧毁内部MCU。 |
| 工作电流 | 15mA(静态)/60mA(发射) | 静态电流指模块未触发时的功耗,发射电流指TXR输出脉冲时的峰值电流,需确保外部电源能提供足够的瞬时电流。 |
| 测量周期 | ≥60ms | 两次触发之间需间隔≥60ms,避免前一次测距的回波(延迟回波)干扰后一次测量,导致时间计算错误。 |
| 波束角 | 约15°(半功率角) | 仅在波束角范围内的障碍物能反射回波,超出范围的障碍物可能无法检测(如模块正前方1m处有物体,斜前方30°处物体可能被忽略)。 |
四、中断式测距实现方案(基于STM32)
HC-SR05的测距实现分为“轮询式”与“中断式”,其中中断式可释放CPU资源,适合实时性要求较高的系统(如智能小车避障、工业液位检测)。以下为基于STM32 HAL库的中断式实现方案,包含工作流程、硬件配置、代码实现与注意事项。
1. 实现核心逻辑
中断式实现通过外部中断检测ECHO引脚的上升沿/下降沿,结合定时器记录时间差,无需CPU轮询等待,具体流程:
- 外部控制器调用
sonar_trigger_measurement()函数,向TRIG引脚输出触发信号; - ECHO引脚检测到上升沿(回波开始),触发外部中断,记录定时器当前值(
sonar_start_time),并将中断触发方式切换为“下降沿检测”; - ECHO引脚检测到下降沿(回波结束),再次触发外部中断,记录定时器当前值(
sonar_end_time),标记测量完成(sonar_measurement_done = 1); - 外部控制器调用
sonar_get_distance_mm()函数,读取时间差并计算距离(单位:mm)。
2. 硬件配置要求
需严格按照以下要求配置STM32硬件引脚与外设:
| 硬件模块 | 配置参数 |
|---|---|
| TRIG引脚 | - 模式:GPIO推挽输出模式; - 初始电平:低电平(避免误触发); - 示例:PA0(需与代码中 TRIG_PORT/TRIG_PIN匹配)。 |
| ECHO引脚 | - 模式:GPIO浮空输入模式(或上拉输入,避免外部干扰); - 中断配置:外部中断线(EXTI),初始触发方式为“上升沿触发”; - 示例:PA15(对应EXTI15中断线,需在CubeMX中配置NVIC优先级)。 |
| 定时器(TIM) | - 模式:自由运行模式(无自动重装载,ARR设为最大值0xFFFF或0xFFFFFFFF); - 时钟频率:1MHz(即计数周期1μs,便于时间计算); - 示例:TIM4(需确保定时器时钟已使能,且无其他中断占用)。 |
| NVIC中断优先级 | - ECHO引脚外部中断优先级:高于普通任务,低于系统紧急中断(如硬件错误中断); - 定时器中断:无需使能(仅用于计数,不触发中断)。 |
3. 完整代码实现(基于STM32 HAL库)
(1)头文件定义(HR04.h)
#ifndef __SR04_H
#define __SR04_H
#include "main.h"
#include "tim.h"
#include "stm32f4xx_hal.h"
#include "math.h"
#include "stdio.h"
#define TRIG_PIN GPIO_PIN_11
#define TRIG_PORT GPIOA
#define ECHO_PIN GPIO_PIN_12
#define ECHO_PORT GPIOA
void sonar_init(void);
void sonar_trigger_measurement(void);
uint8_t sonar_get_distance_mm(int32_t *distance_mm);
#endif
(2)源文件实现(HR04.c)
#include "SR04.h"
volatile uint32_t sonar_start_time = 0;
volatile uint32_t sonar_end_time = 0;
volatile uint8_t sonar_measurement_done = 0;// 0:未完成 1:完成
volatile uint8_t sonar_state = 0; // 0: 空闲, 1: 等待下降沿
void sonar_init(void)
{
// 确保Echo引脚已在CubeMX中配置为上升沿触发中断
// 这里假设已在CubeMX中完成ECHO_PIN的EXTI配置
sonar_measurement_done = 0;
}
/**
* @brief 触发一次测距
* @param 无
* @retval 无
*/
void sonar_trigger_measurement(void)
{
// 如果正在测量,则退出
if (sonar_state != 0) {
return;
}
// 重置状态
sonar_measurement_done = 0;
sonar_state = 1;
// 触发Trig高电平10μs
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);
// 精确延时10μs(根据系统时钟调整循环次数)
for(volatile uint32_t i = 0; i < 1000; i++);
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);
}
/**
* @brief 获取超声波传感器测量的距离(单位:毫米)
*
* 此函数用于从HC-SR04超声波传感器获取测量距离,并将结果以毫米为单位存储到distance_mm指针指向的变量中。
*
* @param[out] distance_mm 指向存储测量距离(单位:毫米)的变量的指针
*
* @retval 0 测量成功,distance_mm中存储有效距离
* @retval 1 测量未完成,无法获取距离
* @retval 2 测量结果超出传感器有效范围(20mm - 4000mm)
*
* @note 距离计算基于声速340m/s(0.34mm/μs),并考虑定时器溢出的情况。
*/
uint8_t sonar_get_distance_mm(int32_t *distance_mm)
{
if (!sonar_measurement_done) {
return 1; // 测量未完成
}
uint32_t time;
// 处理定时器溢出
if (sonar_end_time < sonar_start_time) {
time = (0xFFFFFFFF - sonar_start_time) + sonar_end_time + 1;
} else {
time = sonar_end_time - sonar_start_time;
}
// 计算距离(单位:毫米)
// 声速340m/s = 340mm/ms = 0.34mm/us,除以2是因为声波往返
*distance_mm = (int32_t)(time * 0.34f / 2.0f);
// 过滤超出传感器范围的值(典型范围20mm - 4000mm)
if (*distance_mm < 20 || *distance_mm > 4000) {
*distance_mm = -1;
//return 2; // 超出范围
}
return 0;
}
(3)中断实现(main.c)
/*!--------定时器9为1us中断,period拉满-------!*/
HAL_TIM_Base_Start(&htim9); // 启动定时器9,用于超声波测距计时
while(1){
if (sonar_measurement_done == 1) {
if (sonar_get_distance_mm(&distance_mm) == 0) {
printf("Distance: %ld mm\r\n", distance_mm);
}
sonar_measurement_done = 0; // 清零,等待下次测量
}
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2) // 1ms中断
{
if (timer_count_100ms >= 100) // 100ms
{
timer_count_100ms = 0;
sonar_trigger_measurement(); // 触发超声波测距
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == ECHO_PIN) {
if (sonar_state == 1 && HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_SET) {
// 上升沿,记录开始时间
sonar_start_time = __HAL_TIM_GET_COUNTER(&htim9);
sonar_state = 2;
}
else if (sonar_state == 2 && HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_RESET) {
// 下降沿,记录结束时间
sonar_end_time = __HAL_TIM_GET_COUNTER(&htim9);
sonar_measurement_done = 1;
sonar_state = 0;
}
}
}
4. 关键技术细节与注意事项
(1)定时器计时精度的保障
定时器的计时精度直接影响距离计算误差,需重点配置以下参数:
- 时钟频率:建议配置为1MHz(计数周期1μs),此时时间差的最小误差为1μs,对应距离误差约0.17mm(满足HC-SR05的±3mm精度要求);
- 定时器位数:优先使用32位定时器(如TIM4),其最大计数值为0xFFFFFFFF(约4294秒),可避免短时间内溢出;若使用16位定时器(如TIM2),需在中断中处理溢出计数,否则会导致时间计算错误。
(2)特殊场景的适配
在液位检测、高温环境等特殊场景中,需额外适配:
- 液位检测:超声波在空气-液体界面的反射率较高,但需注意液面波动(如水流冲击)会导致回波不稳定,建议增加“距离变化率过滤”(如连续两次测量的距离差≤5mm时,判定为稳定值);
- 高温环境(>60℃):模块内部压电陶瓷换能器的频率特性会随温度变化,需每10℃重新校准声速(通过温度传感器实时采集环境温度,动态更新声速值);
五、总结
HC-SR05模块的核心优势在于低成本、易集成,其测距原理基于“超声波往返时间+声速”的物理关系,工程实现中需重点关注环境声速校准、中断与定时器的协同、抗干扰优化三大核心点。本文提供的中断式实现方案,通过STM32 HAL库完成了从触发、计时到距离计算的全流程,兼顾了效率与稳定性,可直接移植到智能小车、智能家居、工业检测等场景。
在实际开发中,建议先通过示波器观察TRIG触发信号和ECHO回波信号的波形(确认高电平持续时间、上升沿/下降沿是否正常),再逐步优化软件逻辑,最终实现满足项目精度要求的测距功能。
更多推荐



所有评论(0)