一、系统架构设计
1、一发多收拓扑
发射探头 │ ▼ ┌─────────────┐ │ 超声波束 │ └──────┬──────┘ │ ┌─────┼─────┐ ▼ ▼ ▼ 接收1 接收2 接收3 (Rx1) (Rx2) (Rx3) │ │ │ └──┬──┴──┬──┘ │ │ 时间差Δt1 Δt2 │ │ 距离解算 → 目标位置
2、系统指标
| 参数 | 指标 |
|---|
| 工作频率 | 40kHz |
| 探测距离 | 0.2m ~ 5m |
| 角度覆盖范围 | 120° |
| 测距精度 | ±2cm |
| 响应时间 | < 50ms |
| 接收通道 | 3~8个 |
二、硬件设计方案
1、核心器件选型
| 器件 | 型号 | 说明 |
|---|
| MCU | STM32F407ZGT6 | 168MHz,17个定时器 |
| 发射驱动 | MAX232/TXS0108E | 高压驱动 |
| 接收放大 | LM358×2级联 | 带通滤波+放大 |
| 超声波探头 | TCT40-16T/R | 16mm,40kHz |
| 模拟开关 | CD4051 | 多路复用 |
| 电平转换 | TXS0108E | 5V/3.3V |
2、发射电路
STM32 PWM ── 74HC04 ── BS170 MOSFET ── 变压器 ── 发射探头 │ MAX232 (倍压)
3、接收电路(每个通道)
接收探头 ── 前置放大(LM358) ── 带通滤波(40kHz) ── 比较器 ── STM32 │ 增益可调(电位器)
三、STM32 资源配置
1、定时器分配
/* 定时器功能分配 */TIM1 ── 发射PWM(40kHz,8个周期) TIM2 ── 接收通道1捕获 TIM3 ── 接收通道2捕获 TIM4 ── 接收通道3捕获 TIM5 ── 系统时间基准 TIM6 ── 采样周期控制
2、GPIO 引脚定义
/* 发射控制 */#defineTRIG_PINGPIO_PIN_8#defineTRIG_PORTGPIOA/* 接收通道 */#defineECHO1_PINGPIO_PIN_0// TIM2_CH1#defineECHO2_PINGPIO_PIN_6// TIM3_CH1#defineECHO3_PINGPIO_PIN_6// TIM4_CH1/* 模拟开关控制 */#defineSEL_A_PINGPIO_PIN_12#defineSEL_B_PINGPIO_PIN_13#defineSEL_C_PINGPIO_PIN_14
四、核心代码实现
1、超声波参数定义
#ifndefULTRASONIC_H#defineULTRASONIC_H#include"stm32f4xx_hal.h"#defineNUM_RECEIVERS3#defineSOUND_SPEED340.0f// 声速 m/s#defineTRIGGER_PULSE_US10// 触发脉冲宽度#defineMEASURE_TIMEOUT_MS50// 测量超时#defineSAMPLE_RATE_HZ20// 采样频率/* 接收通道结构体 */typedefstruct{uint8_tchannel_id;// 通道IDuint32_techo_time_us;// 回波时间(μs)floatdistance_m;// 距离(m)uint8_tvalid_flag;// 数据有效性uint32_tlast_update;// 最后更新时间}Receiver_t;/* 一发多收系统 */typedefstruct{Receiver_t receivers[NUM_RECEIVERS];uint32_ttrigger_time;// 触发时间uint8_tmeasurement_done;// 测量完成标志floattarget_x;// 目标X坐标floattarget_y;// 目标Y坐标floatconfidence;// 置信度}Ultrasonic_System_t;externUltrasonic_System_t us_system;#endif
2、定时器初始化
/* TIM1 - 发射PWM初始化 */voidTIM1_Trigger_Init(void){TIM_HandleTypeDef htim1;TIM_OC_InitTypeDef sConfigOC={0};__HAL_RCC_TIM1_CLK_ENABLE();htim1.Instance=TIM1;htim1.Init.Prescaler=84-1;// 84MHz/84 = 1MHzhtim1.Init.CounterMode=TIM_COUNTERMODE_UP;htim1.Init.Period=25-1;// 40kHz (1MHz/40kHz = 25)htim1.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter=0;HAL_TIM_PWM_Init(&htim1);sConfigOC.OCMode=TIM_OCMODE_PWM1;sConfigOC.Pulse=12;// 50%占空比sConfigOC.OCPolarity=TIM_OCPOLARITY_HIGH;sConfigOC.OCNPolarity=TIM_OCNPOLARITY_HIGH;sConfigOC.OCFastMode=TIM_OCFAST_DISABLE;sConfigOC.OCIdleState=TIM_OCIDLESTATE_RESET;sConfigOC.OCNIdleState=TIM_OCNIDLESTATE_RESET;HAL_TIM_PWM_ConfigChannel(&htim1,&sConfigOC,TIM_CHANNEL_1);HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);}/* 接收通道定时器初始化 */voidTIM_Receiver_Init(void){TIM_HandleTypeDef htim2,htim3,htim4;// TIM2_CH1 - 接收通道1__HAL_RCC_TIM2_CLK_ENABLE();htim2.Instance=TIM2;htim2.Init.Prescaler=84-1;// 1MHzhtim2.Init.CounterMode=TIM_COUNTERMODE_UP;htim2.Init.Period=0xFFFFFFFF;// 32位最大计数HAL_TIM_IC_Init(&htim2);TIM_IC_InitTypeDef sConfigIC={0};sConfigIC.ICPolarity=TIM_INPUTCHANNELPOLARITY_RISING;sConfigIC.ICSelection=TIM_ICSELECTION_DIRECTTI;sConfigIC.ICPrescaler=TIM_ICPSC_DIV1;sConfigIC.ICFilter=0x0;HAL_TIM_IC_ConfigChannel(&htim2,&sConfigIC,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);// 类似配置TIM3、TIM4...}
3、发射控制
/* 发射超声波脉冲 */voidUltrasonic_Trigger(void){uint32_tstart_time;// 记录触发时间us_system.trigger_time=HAL_GetTick();// 启动PWM发射HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);// 发射8个周期后停止start_time=HAL_GetTick();while(HAL_GetTick()-start_time<1);// 延迟200μsHAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);// 重置所有接收通道for(inti=0;i<NUM_RECEIVERS;i++){us_system.receivers[i].valid_flag=0;us_system.receivers[i].echo_time_us=0;}us_system.measurement_done=0;}
4、输入捕获中断处理
/* TIM2输入捕获中断 - 接收通道1 */voidHAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef*htim){staticuint32_tic_val1[NUM_RECEIVERS]={0};staticuint8_tis_first_capture[NUM_RECEIVERS]={1};if(htim->Instance==TIM2&&htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){if(is_first_capture[0]==0){// 第二次捕获(下降沿)uint32_tic_val2=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);uint32_tdiff=ic_val2-ic_val1[0];us_system.receivers[0].echo_time_us=diff;us_system.receivers[0].distance_m=(diff*0.001f)*SOUND_SPEED/2.0f;us_system.receivers[0].valid_flag=1;us_system.receivers[0].last_update=HAL_GetTick();is_first_capture[0]=1;}else{// 第一次捕获(上升沿)ic_val1[0]=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);is_first_capture[0]=0;}}// 类似处理TIM3、TIM4...}
5、一发多收距离解算
/* 一发多收位置解算 */voidMultistatic_Position_Estimation(void){floatdistances[NUM_RECEIVERS];uint8_tvalid_count=0;// 收集有效距离数据for(inti=0;i<NUM_RECEIVERS;i++){if(us_system.receivers[i].valid_flag&&us_system.receivers[i].distance_m>0.2f&&us_system.receivers[i].distance_m<5.0f){distances[valid_count++]=us_system.receivers[i].distance_m;}}if(valid_count<2){us_system.confidence=0.0f;return;}// 基于时间差的多基站定位算法// 简化版本:使用最近的两个接收器进行三角定位if(valid_count>=2){floatd1=distances[0];floatd2=distances[1];// 假设接收器间距已知(例如30cm)floatreceiver_spacing=0.3f;// 简化三角定位floatx=(d1*d1-d2*d2+receiver_spacing*receiver_spacing)/(2*receiver_spacing);floaty=sqrt(d1*d1-x*x);us_system.target_x=x;us_system.target_y=y;us_system.confidence=(float)valid_count/NUM_RECEIVERS;}us_system.measurement_done=1;}
6、主循环处理
/* 主任务 */voidUltrasonic_Task(void){staticuint32_tlast_trigger=0;uint32_tcurrent_time=HAL_GetTick();// 周期性触发测量if(current_time-last_trigger>1000/SAMPLE_RATE_HZ){Ultrasonic_Trigger();last_trigger=current_time;}// 检查是否所有通道都有数据uint8_tall_received=1;for(inti=0;i<NUM_RECEIVERS;i++){if(us_system.receivers[i].valid_flag==0){all_received=0;break;}}// 超时处理if(current_time-us_system.trigger_time>MEASURE_TIMEOUT_MS){all_received=1;// 强制处理}// 进行位置解算if(all_received){Multistatic_Position_Estimation();// 输出结果if(us_system.measurement_done){printf("Target: (%.2f, %.2f)m, Confidence: %.1f%%\n",us_system.target_x,us_system.target_y,us_system.confidence*100);}}}
五、高级功能实现
1、自适应增益控制
/* 自动增益控制 */voidAGC_Control(void){staticuint8_tgain_level=1;for(inti=0;i<NUM_RECEIVERS;i++){if(us_system.receivers[i].echo_time_us<100){// 信号太强,降低增益gain_level=(gain_level>1)?gain_level-1:1;break;}elseif(us_system.receivers[i].echo_time_us>5000){// 信号太弱,增加增益gain_level=(gain_level<8)?gain_level+1:8;break;}}// 设置模拟开关选择增益档位HAL_GPIO_WritePin(SEL_A_PORT,SEL_A_PIN,(gain_level&0x01)?GPIO_PIN_SET:GPIO_PIN_RESET);HAL_GPIO_WritePin(SEL_B_PORT,SEL_B_PIN,(gain_level&0x02)?GPIO_PIN_SET:GPIO_PIN_RESET);HAL_GPIO_WritePin(SEL_C_PORT,SEL_C_PIN,(gain_level&0x04)?GPIO_PIN_SET:GPIO_PIN_RESET);}
2、多目标识别
/* 多目标检测 */typedefstruct{floatdistance;uint8_tamplitude;uint8_tchannel_mask;}Echo_Target_t;voidMulti_Target_Detection(void){#defineMAX_TARGETS5Echo_Target_t targets[MAX_TARGETS];uint8_ttarget_count=0;// 分析每个通道的回波信号for(intch=0;ch<NUM_RECEIVERS;ch++){// 检测多个回波峰值uint32_t*echo_times=Get_Echo_Timeline(ch);uint8_tpeak_count=Find_Echo_Peaks(echo_times);for(intp=0;p<peak_count&&target_count<MAX_TARGETS;p++){targets[target_count].distance=echo_times[p]*0.001f*SOUND_SPEED/2.0f;targets[target_count].channel_mask|=(1<<ch);target_count++;}}// 聚类分析,合并同一目标的多个回波Cluster_Targets(targets,&target_count);}
六、误差分析与补偿
1、温度补偿
/* 温度补偿声速 */floatGet_Sound_Speed(floattemperature_c){// v = 331.4 + 0.6 × Treturn331.4f+0.6f*temperature_c;}/* 在距离计算中使用 */us_system.receivers[i].distance_m=(diff*0.001f)*Get_Sound_Speed(current_temp)/2.0f;
2、时间延迟补偿
/* 硬件延迟补偿 */#defineHW_DELAY_US2.5f// 发射电路延迟#defineSW_DELAY_US1.2f// 软件处理延迟floatCompensate_Distance(floatraw_distance){floattime_compensation=(HW_DELAY_US+SW_DELAY_US)*0.001f;floatdistance_compensation=time_compensation*SOUND_SPEED/2.0f;returnraw_distance-distance_compensation;}
参考代码 实现超声波传感器一发多收的测距功能www.youwenfan.com/contentcsv/72819.html
七、性能优化
1、实时性优化
| 优化项 | 方法 |
|---|
| 中断处理 | 使用DMA减少CPU占用 |
| 数据缓存 | 环形缓冲区存储回波数据 |
| 算法优化 | 查表法替代浮点运算 |
| 并行处理 | 多通道同时采样 |
2、抗干扰措施
/* 中值滤波 */floatMedian_Filter(float*data,uint8_tlen){// 冒泡排序取中值for(inti=0;i<len-1;i++){for(intj=0;j<len-i-1;j++){if(data[j]>data[j+1]){floattemp=data[j];data[j]=data[j+1];data[j+1]=temp;}}}returndata[len/2];}
八、测试验证
1、测试项目
| 测试项目 | 方法 | 标准 |
|---|
| 单目标测距 | 固定距离测量 | ±2cm |
| 多目标分辨 | 前后放置障碍物 | 最小间距>15cm |
| 角度特性 | 旋转目标 | 120°覆盖 |
| 抗干扰性 | 添加噪声源 | 误检率<5% |
| 长期稳定性 | 连续运行24h | 漂移<3cm |
2、标定流程
1. 静态标定:在0.5m、1m、2m、3m、4m处测量 2. 温度标定:-10°C、0°C、25°C、50°C 3. 角度标定:0°、30°、60°、90° 4. 多目标标定:前后目标分离测试