最近用STM32F407的DSP库(en.stm32f4_dsp_stdperiph_lib)实现了FFT功能,有三种方式,现将这三种方案做个对比。
方式一:使用arm_cfft_radix2_f32.c文件,基2
方式二:使用arm_cfft_radix4_f32.c文件,基4
方式三:使用arm_cfft_f32.c与CMSIS中的arm_cortexM4lf_mat.lib文件
采64点同一原始数据的相同数据段计算时间与所占资源
方式一:163uS Program Size: Code=9228RO-data=217380 RW-data=2108 ZI-data=4740
方式二:111uS Program Size:Code=11012 RO-data=217380 RW-data=2108 ZI-data=4740
方式三:103uS Program Size:Code=15848 RO-data=217396 RW-data=2120 ZI-data=2416
采128点同一原始数据的相同数据段计算所得到的周期,采用256点FFT采128点实际数据后续128个补0的方式。
方式一:
方式二:
方式三:
由上可算得Fn=(4-1)*50/256=0.5859375Hz,Tn=1/Fn=1.707s。与MATLAB分析的结果一致。
MATLAB结果:
原始信号:
另外在单片机中使用基2的算法,采128个点做128点的FFT分析结果为0.78125Hz与实际相差较大,见下图。
由上可得以下结论:
1. 运算时间由快到慢依次为arm_cfft_f32、arm_cfft_radix4_f32、arm_cfft_radix2_f32。
2. 所占资源相差不大。
3. 相同采集点情况下,补0对正确计算周期有帮助。
另外还有两个问题请教各位。
1.FFT以后频域中的模值比时域中实际信号的幅值小很多,不到1/2甚至更少。
2.FFT结果是对称的,为什么又不能使用一半的数据做分析呢。
离线
回答问题2,对于实数输入,输出的FFT结果是共轭的。所以,对实数输入,常用rfft优化,可以减少运算量。见arm_rfft_*函数。
离线
讲道理fft后每个点的值应该是对应频率的N(采样点数)/2倍,第一点是N倍
离线
感谢关注与回复,所以说可以只用一半的数据么。
回答问题2,对于实数输入,输出的FFT结果是共轭的。所以,对实数输入,常用rfft优化,可以减少运算量。见arm_rfft_*函数。
离线
是的,用单片机做FFT变换结果如你所说,MATLAB下就不对了。
讲道理fft后每个点的值应该是对应频率的N(采样点数)/2倍,第一点是N倍
离线
感谢关注与回复,所以说可以只用一半的数据么。
如果输入是实数(比如声音),那是只用一半的输出就可以。
离线
如果输入是实数(比如声音),那是只用一半的输出就可以。
输入的是实数,谢谢您。如果有虚数会输出不对称么。
离线
嗯,你试试咯。
离线
cpfft
离线