1 . 建立工程,生成代碼時選擇包含所有庫。

2. 打開 option for target 選擇 Target 標簽,在code generatio中,將floating point hardware 選擇 USE Single Precision。

3. 打開 option for target 選擇 C/C++ 標簽。
在define后添加:__TARGET_FPU_VFP,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING,ARM_MATH_CM4,__CC_ARM,由於使用HAL的庫,所以前面有USE_HAL_DRIVER,STM32F429xx的全局宏定義,如果使用的不是HAL庫,而是使用固件庫的話,一般會有固件庫的一個全局宏定義USE_STDPERIPH_DRIVER和STM32F4XXxx在里面。所以當前只需要添加
__TARGET_FPU_VFP,
ARM_MATH_MATRIX_CHECK,
ARM_MATH_ROUNDING,
ARM_MATH_CM4,
__CC_ARM
注意中間用英文逗號分開。其中ARM_MATH_MATRIX_CHECK是庫函數的參數檢查開關。ARM_MATH_ROUNDING這個是庫函數在運算是是否開啟四舍五入的功能,可以根據實際需要進行配置。ARM_MATH_CM4這個就非常重要,必須要配置進去,否則在編譯之后,會默認使用math.h的庫函數,而不會用到硬件的FPU的。__CC_ARM是不同編譯器的編譯配置宏定義,__CC_ARM就是代表MDK開發環境。

4. 添加浮點庫(.lib)文件到工程(或者添加源碼庫文件)。
DC分量值為15360.001,則對應的直流分量為15360.001/FFT點數 = 15360.001/1024=15。
如果用的是 uv4,打開 C:\Keil\ARM\CMSIS\Lib\ARM 目錄,復制“arm_cortexM4lf_math.lib”文件到你的工程下,並加入工程。
如果用的是 uv5,打開 C:\Keil_v5\ARM\Pack\ARM\CMSIS\4.2.0\CMSIS\Lib\ARM 目錄,復制“arm_cortexM4lf_math.lib”文件到工程下,並加入工程,4.2.0是庫的版本,每個版本可能不一樣。
也可以從官方下載固件庫程序包中復制也行, \STM32F4xx_DSP_StdPeriph_Lib\Libraries\CMSIS\Lib\ARM。

如果查看DSP庫的各個函數的原型,可以添加源碼庫文件, 則當前工程目錄下的Drivers\CMSIS\DSP_Lib\Source目錄可以查看,當然安裝目錄下也有該庫源文件。
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(離散余弦變換)和配套的初始化函數。
相關函數說明以及示例也可在安裝路徑Keil_v5\ARM\PACK\ARM\CMSIS\4.5.0\CMSIS\Documentation\DSP\html下獲得,自行查閱。
5. DSP庫的FFT變換示例。
在工程的main.c文件中添加如下代碼。
說明:采樣頻率為1024Hz,fft點數為1024點,則頻率分辨率,計算公式:分辨率=采樣頻率/采樣點數 = 1Hz,此時能看到0Hz,1Hz,2Hz,3Hz,.....512Hz的頻率分量。
FFTOutput這個數組中,下標0對應的元素就是0Hz(也就是直流分量)的幅度,下標1對應的就是1Hz的幅度,下標2對應2Hz的幅度......,依次類推。
此點非常重要,例如采樣率為2048Hz,那么頻率分辨率為2Hz,那么能看到0Hz,2Hz,4Hz,6Hz,.....1024Hz的頻率分量
FFTOutput這個數組中,下標0對應的元素就是0Hz(也就是直流分量)的幅度,下標1對應的就是2Hz的幅度,下標2對應4Hz的幅度......,依次類推。此時去看1Hz,3Hz,則會出現誤差比較大的情況。
#include "arm_math.h" //添加頭文件
#define FFT_LENGTH 1024 //FFT長度,默認是1024點FFT
#define SAMPLE_FREQ 1024 //采樣頻率
float fft_inputbuf[FFT_LENGTH*2]; //FFT輸入輸出數組,此數組為arm_cfft_radix4_f32的輸入輸出數組,前一個元素為實部,后一個為虛部,每兩個元素代表一個點.
float fft_outputbuf[FFT_LENGTH]; //arm_cmplx_mag_f32()幅度輸出數組
arm_cfft_radix4_instance_f32 scfft; //fft變換的初始化參數
在主函數進入while(1)之前添加如下代碼
說明:arm_sin_f32函數生成采樣點,采樣信號為DC信號,100Hz,150Hz信號的疊加,此時分辨率為1Hz,剛好能夠看到DC, 100Hz,150Hz頻率分量的幅度,分別對應fft幅度輸出數組的下標0,100,150。
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft結構體,設定FFT相關參數
for(int i=0;i<FFT_LENGTH;i++)//生成信號序列
{
fft_inputbuf[2*i]=15 + 10*arm_sin_f32(2*PI*i*100/SAMPLE_FREQ) + \
5.5*arm_sin_f32(2*PI*i*150/SAMPLE_FREQ); //生成實部
fft_inputbuf[2*i+1]=0;//虛部全部為0
}
arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計算(基4(即fft長度22*n),FFT長度只能為64,256,1024,4096目前測試過這幾個長度,)
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把運算結果復數求模得幅值
若要查看某一頻率分量的實部與虛部,則可以查看fft_inputbuf數組。下標對應乘以2,因為實部和虛部存在。當把采樣頻率改為2048Hz,生成信號頻率其中一路改為151Hz,讀者可以自行測試該頻率分量的幅度,肯定會存在誤差。