DSP库-RFFT-奇怪的结果 [英] DSP libraries - RFFT - strange results
问题描述
最近,我一直在尝试在STM32F4-Discovery评估板上进行FFT计算,然后将其发送到PC.我已经研究了我的问题-我认为制造商提供的FFT函数做错了.
Recently I've been trying to do FFT calculations on my STM32F4-Discovery evaluation board then send it to PC. I have looked into my problem - I think that I'm doing something wrong with FFT functions provided by manufacturer.
我正在使用CMSIS-DSP库. 目前,我一直在用代码生成样本(如果可以正常工作,我将通过麦克风进行采样).
I'm using CMSIS-DSP libraries. For now I've have been generating samples with code (if that works correct I'll do sampling by microphone).
我正在使用 arm_rfft_fast_f32
,因为将来我的数据将是浮动的,但是我在输出数组中得到的结果是疯狂的(我认为)-我的频率低于0.
I'm using arm_rfft_fast_f32
as my data are going to be floats in the future, but results I get in my output array are insane (I think) - I'm getting frequencies below 0.
number_of_samples = 512; (l_probek in code)
dt = 1/freq/number_of_samples
这是我的代码
float32_t buffer_input[l_probek];
uint16_t i;
uint8_t mode;
float32_t dt;
float32_t freq;
bool DoFlag = false;
bool UBFlag = false;
uint32_t rozmiar = 4*l_probek;
union
{
float32_t f[l_probek];
uint8_t b[4*l_probek];
}data_out;
union
{
float32_t f[l_probek];
uint8_t b[4*l_probek];
}data_mag;
union
{
float32_t f;
uint8_t b[4];
}czest_rozdz;
/* Pointers ------------------------------------------------------------------*/
arm_rfft_fast_instance_f32 S;
arm_cfft_radix4_instance_f32 S_CFFT;
uint16_t output;
/* ---------------------------------------------------------------------------*/
int main(void)
{
freq = 5000;
dt = 0.000000390625;
_GPIO();
_LED();
_NVIC();
_EXTI(0);
arm_rfft_fast_init_f32(&S, l_probek);
GPIO_SetBits(GPIOD, LED_Green);
mode = 2;
//----------------- Infinite loop
while (1)
{
if(true)//(UBFlag == true)
for(i=0; i<l_probek; ++i)
{
buffer_input[i] = (float32_t) 15*sin(2*PI*freq*i*dt);
}
//Obliczanie FFT
arm_rfft_fast_f32(&S, buffer_input, data_out.f, 0);
//Obliczanie modulow
arm_cmplx_mag_f32(data_out.f, data_mag.f, l_probek);
USART_putdata(USART1, data_out.b, data_mag.b, rozmiar);
//USART_putdata(USART1, czest_rozdz.b, data_mag.b, rozmiar);
GPIO_ToggleBits(GPIOD, LED_Orange);
//mode++;
//UBFlag = false;
}
}
}
推荐答案
我正在使用
arm_rfft_fast_f32
,因为将来我的数据将是浮动的,但是我在输出数组中得到的结果是疯狂的(我认为)-我的频率低于0.
I'm using
arm_rfft_fast_f32
as my data are going to be floats in the future, but results I get in my output array are insane (I think) - I'm getting frequencies below 0.
arm_rfft_fast_f32
函数确实可以不是返回频率,而是使用快速傅里叶变换(FFT)计算出的复数值系数.因此,使这些系数为负是完全合理的.更具体地说,对于振幅为15的单周期sin
测试音输入,预期系数为:
The arm_rfft_fast_f32
function does not return frequencies, but rather complex-valued coefficients computed using the Fast Fourier Transform (FFT). It is thus perfectly reasonable for those coefficients to be negative. More specifically, the expected coefficients for your single-cycle sin
test tone input with an amplitude of 15 would be:
0.0, 0.0; // special case packing real-valued X[0] and X[N/2]
0.0, -3840.0; // X[1]
0.0, 0.0; // X[2]
0.0, 0.0; // X[3]
...
0.0, 0.0; // X[255]
请注意,如文档前两个输出对应于纯实系数X[0]
和X[N/2]
(在随后的arm_cmplx_mag_f32
调用中,您应特别注意这种特殊情况;请参见下面的最后一点).
Note that as indicated in the documentation the first two outputs correspond to the purely real coefficients X[0]
and X[N/2]
(you should be particularly careful about this special case in your subsequent call to arm_cmplx_mag_f32
; see last point below).
每个频率分量的频率由k*fs/N
给出,其中N
是采样数(在您的情况下为l_probek
),而fs = 1/dt
是采样率(在您的情况下为freq*l_probek
) ):
The frequency of each of those frequency components are given by k*fs/N
, where N
is the number of samples (in your case l_probek
) and fs = 1/dt
is the sampling rate (in your case freq*l_probek
):
X[0] -> 0*freq*l_probek/l_probek = 0
X[1] -> 1*freq*l_probek/l_probek = freq = 5000
X[2] -> 2*freq*l_probek/l_probek = 2*freq = 10000
X[3] -> 3*freq*l_probek/l_probek = 2*freq = 15000
...
最后,由于前两个值的特殊包装,在计算N/2+1
幅度时需要小心:
Finally, due to the special packing of the first two values, you need to be careful when computing the N/2+1
magnitudes:
// General case for the magnitudes
arm_cmplx_mag_f32(data_out.f+2, data_mag.f+1, l_probek/2 - 1);
// Handle special cases
data_mag.f[0] = data_out.f[0];
data_mag.f[l_probek/2] = data_out.f[1];
这篇关于DSP库-RFFT-奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!