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

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

targe 復數 printf HR length col end sar 進行

原文地址:http://www.cnblogs.com/NickQ/p/8541156.html

測試環境:單片機:STM32F407ZGT6 IDE:Keil5.20.0.0 固件庫版本:STM32F4xx_DSP_StdPeriph_Lib_V1.4.0

第二部分:本教程使用DSP——lib庫的方式,進行FFT運算。

由於上一篇教程STM32F4使用FPU+DSP庫進行FFT運算的測試過程一 ,進行FFT運算的是void arm_cfft_radix4_f32(const arm_cfft_radix4_instance_f32 * S,float32_t * pSrc)函數。

偶然發現,這個函數在STM32F4xx_DSP_StdPeriph_Lib_V1.4.0庫說明中,描述為--不要使用該功能,已經被arm_cfft_f32()替代。

這一類不推薦使用的函數還有很多,例如arm_cfft_radix2_f32,arm_cfft_radix2_init_f32等等,在此不再展開,詳細可在\STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\CMSIS\index.html中查看。這是ST提供的,以網頁的形式描述的說明文檔。。
技術分享圖片

通過使用arm_cfft_f32()替代arm_cfft_radix4_f32後發現,arm_cfft_f32()函數確實更簡單易用。因此此教程中我們使用arm_cfft_f32(),而不再使用arm_cfft_radix4_f32。

我們知道,arm_cfft_radix4_f32是基於4的FFT,也就是說每次運算的長度必須是32,256,1024等,而arm_cfft_f32()也可以運算長度為512的FFT,另外,在arm_cfft_f32()函數不需要使用諸如arm_cfft_radix4_init_f32的初始化配置函數。取而代之的是包含"arm_const_structs.h"頭文件,並使用它說提供的配置變量即可。下圖是arm_const_structs.h

提供的配置變量。

技術分享圖片

準備空工程,配置Keil環境.請參考 STM32F4使用FPU+DSP庫進行FFT運算的測試過程一 的配置,使能STM32的FPU等,在此不做贅述。

添加文件到工程,我們需要DSP的lib庫,路徑為STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Libraries\CMSIS\Lib\ARM

該文件夾下有如下lib庫,
arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
arm_cortexM4l_math.lib (Little endian on Cortex-M4)
arm_cortexM4b_math.lib (Big endian on Cortex-M4)
arm_cortexM3l_math.lib (Little endian on Cortex-M3)
arm_cortexM3b_math.lib (Big endian on Cortex-M3)
arm_cortexM0l_math.lib (Little endian on Cortex-M0)
arm_cortexM0b_math.lib (Big endian on Cortex-M3)

因為測試環境所使用的是STM32F407xx,屬於Cortex-M4內核,小端模式,支持浮點運算單元。因此選擇第一個 lib庫,arm_cortexM4lf_math.lib

將其添加到工程中,並包含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 #include "arm_const_structs.h"
12 
13 #define FFT_LENGTH        1024         //FFT長度,默認是1024點FFT
14 
15 float fft_inputbuf[FFT_LENGTH*2];    //FFT輸入數組
16 float fft_outputbuf[FFT_LENGTH];    //FFT輸出數組
17 
18 int main(void)
19 { 
20     
21     delay_init(168);
22     lcd_init(0);    //初始化LCD
23     key_init();
24     uart_init(115200);        //初始化串口波特率為115200
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]=10+4.5*arm_sin_f32(2*PI*i*200/FFT_LENGTH)+34                                           7.5*arm_sin_f32(2*PI*i*350/FFT_LENGTH);
35                     
36                      fft_inputbuf[2*i+1]=0;//虛部全部為0
37                 }
38                //arm_cfft_sR_f32_len1024,該變量即為"arm_const_structs.h"提供的配置變量,包含頭文件後,直接調用即可。
39                arm_cfft_f32(&arm_cfft_sR_f32_len1024,fft_inputbuf,0,1);
40                arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH);    //把運算結果復數求模得幅值 
41                 
42                 printf("FFT Result:\r\n");
43                 for(int i=0;i<FFT_LENGTH;i++)
44                 {
45                     printf("%f\r\n",fft_outputbuf[i]);
46                 }
47         }
48         delay_ms(60);
49     }
50 }

編譯下載運行。

結果分析:

技術分享圖片

如圖,我們產生的信號是基波幅度為10,200Hz幅度為4.5,350Hz幅度為7.5

基波:10240/1024 = 10

200Hz: 2304*2/1024 = 4.5

350Hz:3840*2/1024 = 7.5

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