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


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

 

 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM