2017-02-17 76 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