news 2026/5/21 16:37:14

【STM32】基于HAL库的HC-SR04超声波测距:定时器输入捕获与温度补偿实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【STM32】基于HAL库的HC-SR04超声波测距:定时器输入捕获与温度补偿实战

1. HC-SR04超声波测距模块基础

HC-SR04是市面上最常见的低成本超声波测距模块,价格通常在10元以内,但测距效果却相当可靠。我第一次用这个模块是在大学做智能小车项目,当时就被它简单的四线接口和稳定的性能惊艳到了。

模块正面有两个金属圆筒,一个是发射器(T),一个是接收器(R)。工作时,发射器会发出40kHz的超声波脉冲,遇到障碍物反射后被接收器检测到。模块背面有四个引脚:

  • VCC:接3.3V或5V电源(实测5V时测距更远)
  • Trig:触发信号输入,给10us以上高电平启动测距
  • Echo:回响信号输出,高电平持续时间对应距离
  • GND:接地

工作时序特别简单:给Trig脚一个10us以上的高电平脉冲,模块就会自动发射8个40kHz的超声波脉冲,然后Echo脚会输出一个高电平,这个高电平的持续时间就是从发射到接收的时间差t。距离计算公式为:距离 = (t × 声速)/2。这里的除以2是因为声波是往返时间。

2. STM32硬件连接与CubeMX配置

我用的是STM32F103C8T6最小系统板,成本不到20元,完全够用。连接方式如下:

  • VCC → 5V
  • Trig → PA1(任意GPIO均可)
  • Echo → PA0(必须连接支持输入捕获的定时器通道)
  • GND → GND

在CubeMX中的配置步骤:

  1. 启用TIM2定时器,选择内部时钟源
  2. 配置通道1为输入捕获模式
  3. 设置预分频器(PSC)为71,ARR为65535(72MHz主频下得到1MHz计数频率,1us分辨率)
  4. 开启TIM2全局中断和捕获中断
  5. 配置PA1为GPIO输出模式
  6. 启用USART1用于调试输出

关键点在于定时器配置。我选择TIM2是因为它是最基础的通用定时器,所有STM32型号都有。输入捕获模式可以精确测量Echo高电平的持续时间,1us的分辨率对于超声波测距完全够用。

3. HAL库输入捕获实现

HAL库的输入捕获流程比标准库更抽象,但用熟练后反而更简单。主要逻辑都在回调函数中处理:

// 定义测量结构体 typedef struct { uint16_t start_val; uint16_t end_val; float distance; uint8_t capture_flag; } SR04_TypeDef; SR04_TypeDef hcsr04; // 输入捕获回调函数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM2) { if(hcsr04.capture_flag == 0) { // 捕获上升沿 hcsr04.start_val = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING); hcsr04.capture_flag = 1; } else { // 捕获下降沿 hcsr04.end_val = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING); hcsr04.capture_flag = 0; // 计算距离 uint16_t pulse_width = (hcsr04.end_val > hcsr04.start_val) ? (hcsr04.end_val - hcsr04.start_val) : (65535 - hcsr04.start_val + hcsr04.end_val); hcsr04.distance = pulse_width * 0.0343 / 2; // 单位cm } } }

这个实现有几个关键点:

  1. 使用结构体保存测量状态,避免全局变量混乱
  2. 在上升沿捕获时立即切换为下降沿捕获,确保能测量完整脉冲宽度
  3. 处理定时器计数器溢出的情况(end_val < start_val时)
  4. 计算距离时使用0.0343cm/us的声速(25℃标准值)

4. 温度补偿算法实现

标准声速是25℃下的343m/s,但实际环境中温度变化很大。温度每升高1℃,声速增加约0.6m/s。我在项目中增加了DS18B20温度传感器,接线如下:

  • VCC → 3.3V
  • DQ → PB0(需接4.7K上拉电阻)
  • GND → GND

温度补偿代码:

float Get_Speed_By_Temp(float temp) { return 331.5 + 0.6 * temp; // 声速与温度关系公式 } void Update_Distance_With_Temp(float temp) { float speed = Get_Speed_By_Temp(temp); uint16_t pulse_width = (hcsr04.end_val > hcsr04.start_val) ? (hcsr04.end_val - hcsr04.start_val) : (65535 - hcsr04.start_val + hcsr04.end_val); hcsr04.distance = pulse_width * (speed / 10000) / 2; // 转换为cm单位 }

实测发现,在冬季(约5℃)和夏季(约35℃)时,补偿前后的测距误差可以从±3cm降低到±1cm以内。对于需要精确测距的场景(如自动泊车),这个改进非常关键。

5. 完整工作流程与优化技巧

主程序的工作流程如下:

int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); MX_USART1_UART_Init(); // 初始化HC-SR04 HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); while (1) { // 触发测距 HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET); delay_us(20); HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET); // 读取温度并更新距离 float temp = DS18B20_GetTemp(); Update_Distance_With_Temp(temp); // 串口输出 printf("距离: %.1fcm 温度: %.1f℃\r\n", hcsr04.distance, temp); HAL_Delay(100); // 两次测量间隔至少60ms } }

几个优化点值得注意:

  1. 触发脉冲严格控制在20us,既满足模块要求又不会过长
  2. 测量间隔大于60ms,避免上次测量的回波干扰
  3. 使用printf重定向输出调试信息,方便观察数据
  4. 加入超时判断,防止因物体超出量程导致程序卡死

6. 常见问题与解决方法

在实际调试中遇到过几个典型问题:

问题1:测量值跳动大解决方法:

  • 在软件中加入滑动平均滤波(如取最近5次测量的平均值)
  • 确保电源稳定,我在VCC脚加了100uF电容后明显改善
  • 检查物体表面是否平整,粗糙表面会导致回波散射

问题2:短距离测量不准原因:HC-SR04有2cm左右的盲区 解决方法:

  • 程序中对小于3cm的结果直接过滤
  • 改用盲区更小的US-015模块(约0.5cm)

问题3:高温环境下异常原因:温度超过DS18B20量程(-55~125℃) 解决方法:

  • 加入温度范围检查,超限时使用默认声速
  • 改用防水型的DS18B20探头

7. 进阶应用示例

基于这个基础框架,可以扩展很多实用功能。比如我在智能小车上实现的自动避障:

void Auto_Avoidance(void) { Get_Distance(); // 获取前方距离 if(hcsr04.distance < 20.0) { // 20cm内障碍物 Stop_Car(); HAL_Delay(500); Turn_Right(90); // 右转90度 Get_Distance(); // 再次测距 if(hcsr04.distance < 30.0) { // 右侧也有障碍 Turn_Left(180); // 掉头 } } else { Move_Forward(); // 安全距离,继续前进 } }

这个简单的逻辑配合超声波模块,就能实现基本的避障功能。如果需要更复杂的应用,可以结合多路超声波模块实现环境建模。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 7:44:38

HY-Motion 1.0创新应用:元宇宙社交中个性化动作表情生成系统

HY-Motion 1.0创新应用&#xff1a;元宇宙社交中个性化动作表情生成系统 1. 这不是动画预设&#xff0c;而是你的“数字身体语言”正在实时生长 你有没有试过在元宇宙会议里&#xff0c;想挥手打招呼却只能点选三个固定动作&#xff1f;或者在虚拟社交平台中&#xff0c;精心…

作者头像 李华
网站建设 2026/5/21 10:48:41

惊艳效果展示:用Nano-Banana生成高精度产品爆炸图案例集

惊艳效果展示&#xff1a;用Nano-Banana生成高精度产品爆炸图案例集 1. 为什么一张好爆炸图&#xff0c;比十页说明书更有说服力&#xff1f; 你有没有遇到过这样的场景&#xff1a; 客户盯着产品手册上密密麻麻的文字和侧视剖面图&#xff0c;眉头越皱越紧&#xff1b; 工程…

作者头像 李华
网站建设 2026/5/20 10:41:14

Clawdbot汉化版企业微信集成实战:Python爬虫数据自动处理

Clawdbot汉化版企业微信集成实战&#xff1a;Python爬虫数据自动处理 1. 企业微信与Clawdbot的强强联合 想象一下这样的场景&#xff1a;每天早晨&#xff0c;你的团队成员打开企业微信&#xff0c;就能收到一份自动生成的行业动态报告。这份报告不仅包含最新的市场数据&…

作者头像 李华
网站建设 2026/5/20 22:57:58

零基础游戏汉化工具避坑指南:3大误区+5步解决方案

零基础游戏汉化工具避坑指南&#xff1a;3大误区5步解决方案 【免费下载链接】Degrees-of-Lewdity-Chinese-Localization Degrees of Lewdity 游戏的授权中文社区本地化版本 项目地址: https://gitcode.com/gh_mirrors/de/Degrees-of-Lewdity-Chinese-Localization 还在…

作者头像 李华
网站建设 2026/5/20 10:43:13

LeagueAkari智能辅助工具效率提升完全指南

LeagueAkari智能辅助工具效率提升完全指南 【免费下载链接】LeagueAkari ✨兴趣使然的&#xff0c;功能全面的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/LeagueAkari LeagueAkari是一款基于英雄联盟官…

作者头像 李华
网站建设 2026/5/21 9:55:09

音乐聚合免费体验破局指南:一站式解锁多平台音乐资源

音乐聚合免费体验破局指南&#xff1a;一站式解锁多平台音乐资源 【免费下载链接】MusicFreePlugins MusicFree播放插件 项目地址: https://gitcode.com/gh_mirrors/mu/MusicFreePlugins 在数字音乐时代&#xff0c;音乐爱好者常常面临多平台切换的困扰——在A平台收藏的…

作者头像 李华