2017-02-17 18 views
1

最近我一直在试图对我的STM32F4-Discovery评估板进行FFT计算,然后将它发送到PC。我研究过我的问题 - 我认为我在制造商提供的FFT功能上做了一些错误。DSP库 - RFFT - 奇怪的结果

我正在使用CMSIS-DSP库。 现在我已经用代码生成了样本(如果这样做正确,我将通过麦克风进行采样)。

我使用arm_rfft_fast_f32我的数据将是在未来的花车,但结果我得到了我的输出数组是疯了(我认为) - 我得到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; 

     } 

    } 
} 
+0

你有没有确认您输入SA对你的测试来说,mples是正确的?另外,l_probek的价值是什么?它是512吗? –

+0

@DaveS他似乎在计算'buffer_input'中的测试正弦波。 – tofro

+0

关于这条线 - 你如何确定15的幅度? buffer_input [i] =(float32_t)15 * sin(2 * PI * freq * i * dt); –

回答

2

我使用arm_rfft_fast_f32我的数据要在彩车未来,但结果我在输出数组得到的是疯狂的(我认为) - 我得到的频率低于0

arm_rfft_fast_f32函数不返回的频率,而是复数系数使用Fast Fourier Transform (FFT)计算。因此这些系数是负的是完全合理的。更具体地,对于具有15的振幅的单周期sin测试音输入预期的系数将是:

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] 

注意,如在documentation指示的第一两个输出对应于纯实系数X[0]X[N/2] (您在后续致电arm_cmplx_mag_f32时应特别小心这种特殊情况;请参阅下面的最后一点)。

每个那些频率分量的频率由k*fs/N,其中N是样本的数目(在您的情况l_probek)和fs = 1/dt给出是采样速率(在你的情况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大小时需要小心:

// 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]; 
+0

非常感谢你SleuthEye。该死的我开始觉得自己没脑子了;) 另外我也为我的FFT生成了一些样本。 错误的** dt **我选择了频率。 今天早上我也检查过使用** sinf **函数来生成值会更明智些。 – Jejh

+0

我还有一个问题 - 是否正常,在我致电 'arm_rfft_fast_f3'函数后,我的输入数组发生了变化? – Jejh

+1

是的,简而言之就是这个功能是如何工作的。较长的答案是'arm_rfft_fast_f32'使用['arm_cfft_f32'](https://www.keil.com/pack/doc/CMSIS/DSP/html/group__ComplexFFT)。html#gade0f9c4ff157b6b9c72a1eafd86ebf80),它使用输入缓冲区进行就地计算(从而修改输入)。 – SleuthEye