STM32F4使用FPU+DSP库进行FFT运算的测试过程二

原文地址: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.0LibrariesCMSISindex.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.0LibrariesCMSISLibARM

该文件夹下有如下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.0LibrariesCMSISInclude下的头文件即可。

编写测试用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:
");
43                 for(int i=0;i<FFT_LENGTH;i++)
44                 {
45                     printf("%f
",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

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