stm32hal库超声波测距多个
时间: 2025-06-20 09:53:59 浏览: 16
### STM32 HAL库实现多个超声波传感器测距的方法
为了在STM32中使用HAL库实现多个超声波传感器的测距功能,可以采用以下设计思路:
#### 1. **硬件连接**
每个超声波模块都需要单独的GPIO引脚来控制其触发信号(Trig)以及接收回响信号(Echo)。由于Echo信号是一个输入信号,建议将其配置为外部中断模式以便实时捕获高电平持续时间。对于Trig信号,则可以直接由GPIO输出。
如果需要同时管理多个超声波模块,推荐将这些模块分别分配至不同的GPIO组,并确保它们之间互不干扰[^1]。
#### 2. **软件初始化**
##### GPIO 配置
- Trig 引脚:设置为推挽输出模式。
- Echo 引脚:设置为浮空输入或上下拉输入模式,并启用外部中断功能。
##### 定时器配置 (TIM3)
利用定时器捕捉机制记录Echo信号的上升沿和下降沿时刻差值。按照引用中的描述,设定预分频寄存器(PSC)为71(即72MHz/(71+1)=1MHz),自动重装载寄存器.ARR=65535, 这样每计数一次代表1微秒的时间增量[^2]。
以下是具体的代码示例:
```c
// 初始化 TIM3
void MX_TIM3_Init(void){
__HAL_RCC_TIM3_CLK_ENABLE();
TIM_HandleTypeDef htim3;
htim3.Instance = TIM3;
// 设置时基单元参数
TIM_Base_InitTypeDef sTimerBaseConfig;
sTimerBaseConfig.Prescaler = 71; // PSC=71 -> 1us tick
sTimerBaseConfig.CounterMode = TIM_COUNTERMODE_UP;
sTimerBaseConfig.Period = 65535; // ARR=65535 max count value
sTimerBaseConfig.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim3);
// 输入捕获通道配置 IC1 和 IC2 分别用于不同传感器
TIM_IC_InitTypeDef sICConfig;
sICConfig.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING_FALLING;
sICConfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
sICConfig.ICPrescaler = TIM_ICPSC_DIV1;
sICConfig.ICFilter = 0xF;
HAL_TIM_IC_ConfigChannel(&htim3,&sICConfig,TIM_CHANNEL_1);
HAL_TIM_IC_ConfigChannel(&htim3,&sICConfig,TIM_CHANNEL_2);
}
```
#### 3. **中断服务程序(ISR)**
当检测到Echo信号发生变化时进入相应的处理逻辑。通过读取定时器当前计数值并存储起来,在后续计算过程中得出实际飞行时间。
```c
uint32_t start_time_ch1,end_time_ch1,duration_us_ch1;
uint32_t start_time_ch2,end_time_ch2,duration_us_ch2;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 ){
if(__HAL_TIM_IS_CAPTURE_POSITIVE_EDGE(htim)){
start_time_ch1=__HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);
}else{
end_time_ch1=__HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);
duration_us_ch1=end_time_ch1-start_time_ch1;
}
}
if(htim->Instance==TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2 ){
if(__HAL_TIM_IS_CAPTURE_POSITIVE_EDGE(htim)){
start_time_ch2=__HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2);
}else{
end_time_ch2=__HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2);
duration_us_ch2=end_time_ch2-start_time_ch2;
}
}
}
float calculate_distance(uint32_t time_in_microseconds,float temperature_celsius){
const float sound_speed_at_20C=343.2f;//m/s at standard condition
float speed_adjusted=sound_speed_at_20C*(1+(temperature_celsius-20)/680.);
return ((time_in_microseconds*speed_adjusted)/(2e6));//[m]
}
```
最后调用`calculate_distance()`函数传入所测量得到的时间长度与环境温度即可获得最终的距离数据[^1].
#### 注意事项
- 测量频率需遵循至少50ms间隔的规定以免造成错误结果。
- 对于超出有效探测范围的目标物应回避误判情况的发生。
阅读全文
相关推荐


















