原文地址: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