#include "xcorr.h" #include "usart.h" //float32_t x_rfft_out[1024]; //float32_t y_rfft_out[1024]; // //float32_t x_temp[1024]; // //float32_t cmplx_result[1024]; arm_rfft_fast_instance_f32 s; //q15_t x_rfft_out[1024]; //q15_t y_rfft_out[1024]; // //q15_t x_temp[1024]; // //q15_t cmplx_result[1024]; float32_t corrx_out[DATA_LEN]; float32_t x_buf[DATA_LEN]; float32_t y_buf[DATA_LEN]; float32_t x_fft_O_f32[DATA_LEN] = {0}; float32_t y_fft_O_f32[DATA_LEN]= {0}; float32_t cmplx_mul_result_f32[DATA_LEN]= {0}; float32_t max_val_f32; int32_t max_val_index_f32; //void fft_acc_corr_f32_test() //{ // arm_copy_f32((float32_t*)x,x_buf,DATA_LEN); // arm_copy_f32((float32_t*)y,y_buf,DATA_LEN); // // __HAL_TIM_SET_COUNTER(&htim16,0); // // 启定时器 // __HAL_TIM_ENABLE(&htim16); // // // arm_offset_f32(x_buf,-2048,x_buf,DATA_LEN); // arm_offset_f32(y_buf,-2048,y_buf,DATA_LEN); // // arm_rfft_fast_init_f32(&s,DATA_LEN); // // arm_rfft_fast_f32(&s,x_buf,x_fft_O_f32,0); // //arm_rfft_fast_init_f32(&s,DATA_LEN); // arm_rfft_fast_f32(&s,y_buf,y_fft_O_f32,0); // // arm_cmplx_conj_f32(y_fft_O_f32,y_fft_O_f32,DATA_LEN); // // // __HAL_TIM_DISABLE(&htim7); // // //arm_cmplx_mult_cmplx_q15_user(x_fft_O,y_fft_O,cmplx_mul_result,DATA_LEN*2); // arm_cmplx_mult_cmplx_f32(x_fft_O_f32,y_fft_O_f32,cmplx_mul_result_f32,DATA_LEN>>1); // //arm_rfft_init_q15(&s,DATA_LEN,1,1); // // // s.pTwiddleAReal // arm_rfft_fast_init_f32(&s,DATA_LEN); // arm_rfft_fast_f32(&s,cmplx_mul_result_f32,corrx_out,1); // // arm_max_f32(corrx_out,DATA_LEN,&max_val_f32,&max_val_index_f32); // // // 关闭定时 // __HAL_TIM_DISABLE(&htim16); // // //} //void fft_acc_corr_q15_test() //{ // arm_copy_f32((float32_t*)x,x_buf,DATA_LEN); // arm_copy_f32((float32_t*)y,y_buf,DATA_LEN); // // __HAL_TIM_SET_COUNTER(&htim16,0); // // 启定时器 // __HAL_TIM_ENABLE(&htim16); // // // arm_offset_f32(x_buf,-2048,x_buf,DATA_LEN); // arm_offset_f32(y_buf,-2048,y_buf,DATA_LEN); // // arm_rfft_fast_init_f32(&s,DATA_LEN); // // arm_rfft_fast_f32(&s,x_buf,x_fft_O_f32,0); // //arm_rfft_fast_init_f32(&s,DATA_LEN); // arm_rfft_fast_f32(&s,y_buf,y_fft_O_f32,0); // // arm_cmplx_conj_f32(y_fft_O_f32,y_fft_O_f32,DATA_LEN); // // // __HAL_TIM_DISABLE(&htim7); // // //arm_cmplx_mult_cmplx_q15_user(x_fft_O,y_fft_O,cmplx_mul_result,DATA_LEN*2); // arm_cmplx_mult_cmplx_f32(x_fft_O_f32,y_fft_O_f32,cmplx_mul_result_f32,DATA_LEN>>1); // //arm_rfft_init_q15(&s,DATA_LEN,1,1); // // // s.pTwiddleAReal // arm_rfft_fast_init_f32(&s,DATA_LEN); // arm_rfft_fast_f32(&s,cmplx_mul_result_f32,corrx_out,1); // // arm_max_f32(corrx_out,DATA_LEN,&max_val_f32,&max_val_index_f32); // // // 关闭定时 // __HAL_TIM_DISABLE(&htim16); //} q15_t dc_offset; float cal_tof(q15_t* x,uint32_t len) { q15_t max_val; float32_t echo_p = 0,echo_dt = 0; uint32_t max_val_p; uint32_t i=0,stop_position = 0; // 求取平均值 arm_mean_q15(x,100,&dc_offset); // 查找数组中的最大值和最大值所在的索引 arm_max_q15(x,len,&max_val,&max_val_p); max_val = max_val - dc_offset ; //uint16_t echo_position = 0; // 最大值的0.18倍 uint16_t max_val_zero_1R5 = (max_val*15/100)+dc_offset; // 最大值的0.45倍 uint16_t max_val_zero_4R5 = (max_val*45/100)+dc_offset; // 最大值的0.8倍 uint16_t max_val_zero_8R0 = (max_val*80/100)+dc_offset; //如果最大值位置大于200 则从最大值前200个位置开始寻找起始波形。 // 优化的地方,从最大值位置开始找到达波,可以最大限度排除偶然噪声干扰, // 因为噪声在波形到达出 噪声不是很大 //优化性能,如果不需要则从数组0位置开始寻找其实波形 if(max_val_p>=70) { i = max_val_p-70; }else { i = 0; } // 在最大值前寻找起始波形 for( ; i < max_val_p ; i++) { // 建议判断顶点,但是容易遇到偶然数据异常 类似于 28 29 28 30 29 28这种情况 //if( x[i-1] < x[i] && x[i]> x[i+1] ) // 排除以上数据异常情况,但是有可能就无法检测到30 这个顶点。 // 故需要检测下一个周期的顶点,然后再减去一个周期的时间。 if( x[i-2]=x[i+1] && x[i+1]>x[i+2]) { // 减去偏置电压 //temp_val_zero = arr[i]-2048; // 判断顶点是否在 15%-%45之间。 if(x[i] >= max_val_zero_1R5 && x[i] <= max_val_zero_4R5 ) { // 如果找到 函数退出 echo_dt = (x[i-1]-x[i+1])/2.0/(x[i-1]-2*x[i]+x[i+1]); echo_p = (float)i+echo_dt; return echo_p; } // 如果15% ~45%之间的数据未找到,则找45-80%的顶点。 // 判断顶点是否在 45% -- 80% 之间 if(x[i] >= max_val_zero_4R5 && x[i] <= max_val_zero_8R0) { // 如果找到 函数推出 echo_dt = (x[i-1]-x[i+1])/2.0/(x[i-1]-2*x[i]+x[i+1]); // 换算成第二个顶点的位置。 echo_p = (float)i+echo_dt - 12.5; return echo_p; } } } /* // 2.5M/0.2k= 12.5 查找最大值前5个周期(63个点)并计算到达时间 if(max_val_p>=63) { stop_position = max_val_p-63; } else { stop_position = 0; } for(i = max_val_p-5 ; i >= stop_position ; i--) { if( x[i-2]=x[i+1] && x[i+1]>x[i+2]) { // 减去偏置电压 //temp_val_zero = arr[i]-2048; // 如果15% ~45%之间的数据未找到,则找45-80%的顶点。 // 判断顶点是否在 45% -- 80% 之间 if(x[i] >= max_val_zero_4R5 && x[i] <= max_val_zero_8R0) { // 如果找到 函数推出 echo_dt = (x[i-1]-x[i+1])/2.0/(x[i-1]-2*x[i]+x[i+1]); // 换算成第二个顶点的位置。 echo_p = (float)i+echo_dt - 12.5; return echo_p; } // 判断顶点是否在 15%-%45之间。 if(x[i] >= max_val_zero_1R5 && x[i] <= max_val_zero_4R5 ) { // 如果找到 函数退出 echo_dt = (x[i-1]-x[i+1])/2.0/(x[i-1]-2*x[i]+x[i+1]); echo_p = (float)i+echo_dt; return echo_p; } } } */ return 0; } float32_t cal_dtof(q15_t* x , q15_t* y , uint32_t len) { float a,b,c; float w_val,x_val,y_val; float tof; arm_rfft_fast_init_f32(&s,len); // 定点数转成float arm_q15_to_float(x,x_buf,DATA_LEN); // 定点数转成float arm_q15_to_float(y,y_buf,DATA_LEN); // 初始化 fft arm_rfft_fast_init_f32(&s,DATA_LEN); // fft 前一半和后一半是对称的,所以只求解了512组数据 arm_rfft_fast_f32(&s,x_buf,x_fft_O_f32,0); // fft arm_rfft_fast_f32(&s,y_buf,y_fft_O_f32,0); // 复数取共轭 arm_cmplx_conj_f32(y_fft_O_f32,y_fft_O_f32,DATA_LEN>>1); // fft的数据 // 时域卷积==频域相乘 1024个数据 复数只有512个 arm_cmplx_mult_cmplx_f32(x_fft_O_f32,y_fft_O_f32,cmplx_mul_result_f32,DATA_LEN>>1); // ifft arm_rfft_fast_f32(&s,cmplx_mul_result_f32,corrx_out,1); // arm_max_f32(corrx_out,DATA_LEN,&max_val_f32,&max_val_index_f32); b =corrx_out[max_val_index_f32]; if(max_val_index_f32 == 0) { a =corrx_out[len-1]; c =corrx_out[max_val_index_f32+1]; } else if(max_val_index_f32 == len-1) { a =corrx_out[max_val_index_f32-1]; c =corrx_out[0]; }else { a =corrx_out[max_val_index_f32-1]; c =corrx_out[max_val_index_f32+1]; } // sin 插值 寻找最大值 w_val = acosf((a+c)/2.0/b); float sin_val = sinf(w_val); y_val = atanf((a-c)/2.0/b/sin_val); x_val = (0-y_val)/w_val; tof = max_val_index_f32+x_val; if(tof>len/2) tof= tof-len; return tof; } float xcorr_max_position_uint16_t(q15_t* xcorr_out,q15_t* x , q15_t* y , uint32_t len) { uint32_t i = 0; // y参数移动的次数 q15_t max_val=0; int32_t max_p=0; q15_t max_val_point[3]; float w_val,x_val,y_val; __HAL_TIM_SET_COUNTER(&htim16,0); // 启定时器 __HAL_TIM_ENABLE(&htim16); arm_correlate_fast_q15(x,len,y,len,xcorr_out); // 关闭定时 __HAL_TIM_DISABLE(&htim16); // xcorr(xcorr_out,x,y,len); for(i=0;imax_val) { max_val = xcorr_out[i]; max_p = i; } } // 曲线拟合 找到最大点 当作中间数据 max_val_point[1] =xcorr_out[max_p]; max_val_point[0] =xcorr_out[max_p-1]; max_val_point[2] =xcorr_out[max_p+1]; // sin 插值 寻找最大值 w_val = acosf((max_val_point[0]+max_val_point[2]-4096)*1.0/(max_val_point[1]-2048)/(max_val_point[1]-2048)); y_val = atanf((max_val_point[0]-max_val_point[2])/2.0/(max_val_point[1]-2048)/sinf(w_val)); x_val = (0-y_val)/w_val; //return ((float)max_p+0.1-0.1); return (((float)max_p)-x_val); // return -((float)max_p); }