原文地址:http://www.cnblogs.com/NickQ/p/8541156.html 測試環境:單片機:STM32F407ZGT6 IDE:Keil5.20.0.0 固件庫版本:STM32F4xx_DSP_StdPeriph_Lib_V1.4.0 第二部分:本教程使用DSP——lib庫的 ...
原文地址: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,也就是說每次運算的長度必須是22n等,而arm_cfft_f32()可以運算長度為2n的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