STM32驱动HC-SR04超声波测距模块实战指南 📅 2026/7/18 3:15:15 1. 超声波测距原理与HC-SR04模块解析超声波测距技术基于声波在空气中的传播特性实现。当超声波发射器向特定方向发射高频声波通常为40kHz时声波遇到障碍物会反射接收器捕获反射波后通过计算发射与接收的时间差即可计算出距离。这个原理与蝙蝠的声呐定位系统类似都是利用声波的往返时间进行空间感知。HC-SR04模块是市面上最常见的低成本超声波测距方案其核心由四个引脚构成VCC5V供电输入Trig触发控制信号输入Echo回响信号输出GND地线模块工作时序分为三个阶段触发阶段给Trig引脚至少10μs的高电平信号发射阶段模块自动发送8个40kHz的超声波脉冲接收阶段模块检测回波并通过Echo引脚输出高电平高电平持续时间与距离成正比具体距离计算公式为距离(cm) (高电平时间(μs) × 声速(340m/s)) / 2除以2是因为声波经历了往返路径。实际应用中需要考虑温度对声速的影响声速修正公式为V 331.4 0.6 × 温度(℃) m/s2. STM32硬件连接与开发环境搭建2.1 硬件连接方案推荐使用STM32F103C8T6最小系统板蓝色药丸板作为主控其GPIO资源丰富且性价比高。具体接线方式HC-SR04引脚STM32引脚备注VCC5V也可接3.3V但测距会缩短TrigPA1任意GPIO输出模式EchoPA2需配置为输入捕获模式GNDGND共地连接注意Echo引脚虽然输出5V电平但实测可直接连接STM32的3.3V GPIO而不会损坏芯片这是因为其输出电流很小。若担心电平问题可添加1kΩ电阻分压。2.2 开发环境配置安装Keil MDK-ARM 5.x建议版本5.36下载STM32F1xx HAL库或直接使用CubeMX生成配置工程时需开启GPIO外设对应Trig引脚定时器输入捕获用于Echo高电平时间测量串口调试输出可选对于习惯使用现代IDE的开发者也可选择VSCodePlatformIO方案[env:bluepill_f103c8] platform ststm32 board bluepill_f103c8 framework libopencm33. 核心代码实现与优化3.1 基础测距实现使用HAL库的典型代码结构// 初始化代码 void HC_SR04_Init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; // Trig引脚配置为推挽输出 GPIO_InitStruct.Pin GPIO_PIN_1; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); // Echo引脚配置为输入捕获 TIM_IC_InitTypeDef sConfigIC {0}; htim2.Instance TIM2; htim2.Init.Prescaler 72-1; // 1MHz计数频率 htim2.Init.CounterMode TIM_COUNTERMODE_UP; htim2.Init.Period 0xFFFF; HAL_TIM_IC_Init(htim2); sConfigIC.ICPolarity TIM_ICPOLARITY_RISING; sConfigIC.ICSelection TIM_ICSELECTION_DIRECTTI; HAL_TIM_IC_ConfigChannel(htim2, sConfigIC, TIM_CHANNEL_1); } // 触发测量函数 float Get_Distance(void) { uint32_t start_time 0, end_time 0; // 发送10us高电平触发信号 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); delay_us(10); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 等待回波信号 while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) GPIO_PIN_RESET); start_time htim2.Instance-CNT; while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) GPIO_PIN_SET); end_time htim2.Instance-CNT; // 计算距离单位cm return (end_time - start_time) / 58.0f; }3.2 非阻塞式实现优化基础方案会阻塞CPU等待回波改进方案使用定时器中断volatile uint32_t pulse_start 0, pulse_width 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_1) { if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1)) { if(pulse_start 0) { pulse_start HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); } else { pulse_width HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) - pulse_start; pulse_start 0; __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING); } __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC1); } } }4. 实测问题排查与精度优化4.1 常见问题解决方案无回波信号检查模块供电是否稳定示波器观察5V纹波确认Trig信号宽度≥10μs建议15-20μs测试环境避免柔软吸音材料如窗帘、泡沫测量结果跳动大增加软件滤波建议取5次测量中值#define SAMPLE_SIZE 5 float Get_Stable_Distance(void) { float samples[SAMPLE_SIZE]; for(int i0; iSAMPLE_SIZE; i) { samples[i] Get_Distance(); HAL_Delay(30); // 防止声波干扰 } // 简单排序取中值 for(int i0; iSAMPLE_SIZE-1; i) { for(int ji1; jSAMPLE_SIZE; j) { if(samples[i] samples[j]) { float temp samples[i]; samples[i] samples[j]; samples[j] temp; } } } return samples[SAMPLE_SIZE/2]; }远距离测量失效确保被测物体表面平整最佳为硬质平面模块安装角度建议垂直于被测面角度误差≤15°环境温度超过40℃需增加声速补偿4.2 精度提升技巧温度补偿实现float Get_Temperature_Compensated_Distance(float temp) { float sound_speed 331.4f 0.6f * temp; float raw_distance Get_Stable_Distance(); return raw_distance * 340.0f / sound_speed; }定时器优化配置将定时器时钟源设为内部时钟72MHz预分频设置为71得到1MHz计数频率开启定时器输入捕获滤波TIM_IC_FILTER值设为4硬件改进方案在VCC与GND间并联100μF电解电容0.1μF陶瓷电容Echo信号线串联100Ω电阻减少振铃效应模块加装橡胶减震圈降低机械振动干扰实际项目中我在智能小车避障系统使用这套方案时发现当多个超声波模块同时工作时会出现交叉干扰。解决方案是采用分时触发策略错开各模块的测量时间至少50ms并通过编码区分不同模块的回波信号。