1. 程式人生 > >STM32F4使用FPU+DSP庫進行FFT運算的測試過程

STM32F4使用FPU+DSP庫進行FFT運算的測試過程

entry 信號 功能 ring void 加法 bsp ons mage

測試環境:單片機: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



STM32F4使用FPU+DSP庫進行FFT運算的測試過程