測試環境:單片機:STM32F407ZGT6 IDE:Keil5.20.0.0 固件庫版本:STM32F4xx_DSP_StdPeriph_Lib_V1.4.0
第一部分:使用源碼文件的方式,使用void arm_cfft_radix4_f32(const arm_cfft_radix4_instance_f32 * S,float32_t * pSrc)函數進行FFT運算。
准備空工程,配置Keil環境.使能STM32F4的FPU單元。
開啟硬件浮點運算,等效於在C/C++->define中定義__FPU_USED,__FPU_PRESENT兩個宏
添加全局宏定義,使能DSP庫所有的功能
圖中STM32F4XX,USE_STDPERIPH_DRIVER是新建工程都會用到的配置宏,新建工程參考:http://blog.csdn.net/qianrushi_jinxifeng/article/details/19673755
其他宏ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING 請參考:http://blog.csdn.net/desert187/article/details/20527921
向工程中添加使用到的DSP庫源碼
在stm32f4_dsp_stdperiph_lib\STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\CMSIS\DSP_Lib\Source目錄下會有如下目錄,都是DSP函數庫
BasicMathFunctions 基本數學函數:提供浮點數的各種基本運算函數,如向量加減乘除等運算。 CommonTables arm_common_tables.c文件提供位翻轉或相關參數表。 ComplexMathFunctions 復雜數學功能,如向量處理,求模運算的。 ControllerFunctions 控制功能函數。包括正弦余弦,PID電機控制,矢量Clarke變換,矢量Clarke逆變換等。 FastMathFunctions 快速數學功能函數。提供了一種快速的近似正弦,余弦和平方根等相比CMSIS計算庫要快的數學函數。 FilteringFunctions 濾波函數功能,主要為FIR和LMS(最小均方根)等濾波函數。 MatrixFunctions 矩陣處理函數。包括矩陣加法、矩陣初始化、矩陣反、矩陣乘法、矩陣規模、矩陣減法、矩陣轉置等函數。 StatisticsFunctions 統計功能函數。如求平均值、最大值、最小值、計算均方根RMS、計算方差/標准差等。 SupportFunctions 支持功能函數,如數據拷貝,Q格式和浮點格式相互轉換,Q任意格式相互轉換。 TransformFunctions 變換功能。包括復數FFT(CFFT)/復數FFT逆運算(CIFFT)、實數FFT(RFFT)/實數FFT逆運算(RIFFT)、和DCT(離散余弦變換)和配套的初始化函數。
我們需要CommonTables和TransformFunctions的下的部分文件
添加到工程如圖
另外我們需要包含相應的頭文件路徑,所需的頭文件在STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\CMSIS\Include路徑下可以找到
編寫main()函數,
1 #include "stm32f4xx_conf.h" 2 //位帶操作 3 #include "sys.h" 4 #include "delay.h" 5 #include "usart.h" 6 //LCD顯示屏功能 7 #include "Nick_lcd.h" 8 #include "Nick_keys.h" 9 10 #include "arm_math.h" 11 #define FFT_LENGTH 1024 //FFT長度,默認是1024點FFT 12 13 float fft_inputbuf[FFT_LENGTH*2]; //FFT輸入輸出數組,此數組為arm_cfft_radix4_f32的輸入輸出數組,前一個元素為實部,后一個為虛部,每兩個元素代表一個點. 14 float fft_outputbuf[FFT_LENGTH]; //arm_cmplx_mag_f32() 幅度輸出數組 15 arm_cfft_radix4_instance_f32 scfft; 16 17 int main(void) 18 { 19 delay_init(168); 20 lcd_init(0); //初始化LCD 21 key_init(); 22 uart_init(115200); //初始化串口波特率為115200 23 24 arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft結構體,設定FFT相關參數 25 26 while(1) 27 { 28 u32 keyval = (u32)keys_scan(0); 29 if(keyval==1) 30 { 31 for(int i=0;i<FFT_LENGTH;i++)//生成信號序列 32 { 33 fft_inputbuf[2*i]=15 + 10*arm_sin_f32(2*PI*i*100/FFT_LENGTH) + \ 34 5.5*arm_sin_f32(2*PI*i*150/FFT_LENGTH); //生成實部 35 36 fft_inputbuf[2*i+1]=0;//虛部全部為0 37 } 38 arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計算(基4) 39 arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把運算結果復數求模得幅值 40 41 printf("FFT Result:\r\n"); 42 for(int i=0;i<FFT_LENGTH;i++) 43 { 44 printf("%f\r\n",fft_outputbuf[i]); 45 } 46 } 47 delay_ms(60); 48 } 49 }
代碼分析:如代碼所示,利用arm_sin_f32函數產生了,一個基波幅度為15,頻率100Hz是幅度為10,頻率150Hz是幅度為5.5的信號。
經過FFT運算后,用arm_cmplx_mag_f32()函數求出賦值,並通過串口打印出來。
編譯運行
結果分析:
對串口收到的數據用matlab繪圖,如下
如圖,基波幅度為:15360/1024 = 15
100Hz成分幅度為: 5120*2/1024 = 10
150Hz成分幅度為: 2816*2/1024 = 5.5
因此所得的結果是正確的。博主目前為測試相位,故在此不做說明。
后記,這是使用源碼的方式進行操作的,所有源碼可跳轉,可編輯。但添加麻煩。
下一篇將使用ST提供的.lib庫直接進行運算。鏈接:http://www.cnblogs.com/NickQ/p/8541156.html