概述
本人的课题是关于EIT采集系统,简单的说就是往人体注入特定频率的恒流源,再采集电压信号,通过分析电阻抗分布进行成像。采集的电压信号是需要进行FFT处理,只保留注入频率的信号成分。本文主要介绍如何在STM32F407上实现对特定频率进行FFT。
关于快速傅里叶变化这里不做过多的介绍,具体可参考别人写的博客:
如何 FFT(快速傅里叶变换) 求幅度、频率(超详细 含推导过程)_Xav Zewen的博客
使用DSP库进行FFT计算
1.1 DSP库开启
STM32F407是具有浮点运算(FPU)功能,可以通过MDK配置:target->Roating Point Hardware->Use Single Precison中打开。
同时在MDK配置中添加头文件:ARM_MATH_CM4
添加dsp数学库,由此就可以调用DSP库中的函数。
1.2 调用DSP库进行FFT计算
EIT的正弦激励电压为97.656kHz,经测试ADC的采样频率为8.3333MHz,采样512个数据点,取N=6(第7个数据点),即经FFT变换后的第7个数据点为97.656kHz频率成分的幅值。
FFT变换相关的代码如下:
float array_f32[512]; //储存每次采集的512点位数据(定义为全局变量)
float array_FFT_output[512]; //储存FFT变换后的512个数据
float array_arm_cmplx_mag[512]; //储存FFT变换后的512个数据的幅值信息
arm_rfft_fast_instance_f32 S;
arm_rfft_fast_init_f32(&S, fftSize); //初始化结构体S中的参数
arm_rfft_fast_f32(&S, array_f32, array_FFT_output, 0); //fft正变换
arm_cmplx_mag_f32(array_FFT_output, array_arm_cmplx_mag, 512);
/*------------ 保存FFT变换后的第7个数值 -----------------*/
eit_fft_result[num_EIT_208] = array_arm_cmplx_mag[6];
经测试,采集并计算一帧数据的时间为73ms,还不能达到EIT一秒20帧的采集要求。
FFT计算优化
考虑到我们只需要激励频率的电压幅值,其余频率成分对于我们来说是无效数据。由此,可以单独计算97.656kHz的频率成分,即只计算第7个点位的数据。
离散型傅里叶变化的计算公式如下:
取N=512,k=6,代入可求得第7个点位的数据,计算的代码如下:
float EIT_FUN_FFT(float *FFT_data, float N)
{
unsigned int i;
float SUM_Re = 0; //实频数值
float SUM_Im = 0; //虚频数值
float A = 0; //幅值
float k = 6; //第七个点位数据
//FFT展开式
for(i=0;i<512;i++)
{
SUM_Re = SUM_Re + FFT_data[i]*cos(2*3.1415926*K*i/N);
SUM_Im = SUM_Im - FFT_data[i]*sin(2*3.1415926*K*i/N);
}
//计算幅值
A = sqrt(SUM_Re*SUM_Re + SUM_Im*SUM_Im);
return A;
}
考虑到cos(2*3.1415926*K*i/N)和 sin(2*3.1415926*K*i/N) 的计算结果是固定值,不会因为ADC采集电压的不同而改变,由此,可以提前计算出N=512,k=6,i取0~511时的cos和sin的计算结果并储存起来,通过查询计算结果替代耗时的三角函数计算,以达到节省计算时间的效果。经过测试,新FFT算法采集一帧的时间为29ms,已能实现一秒30帧的采样要求。
最后
以上就是丰富小甜瓜为你收集整理的基于STM32F407实现快速傅里叶变化(FFT),计算指定频率的幅值使用DSP库进行FFT计算FFT计算优化的全部内容,希望文章能够帮你解决基于STM32F407实现快速傅里叶变化(FFT),计算指定频率的幅值使用DSP库进行FFT计算FFT计算优化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复