两个问题,问题2:问题1:stm32f3的FPU咋没显著提升运算速度?FIR滤波出来后再FFT傅里叶变换,数据感觉有问题。

2019-07-20 10:50发布

#include "stm32f30x.h"
//#include "math"
#include "arm_math.h"
#include "FFT.h"
#include "TIM6.h"

#define FFT_FENGTH        1024

uint16_t u16FFT_time_ms = 0;
uint16_t u16FIR_time_ms = 0;
float32_t fFFT_InputBuf[FFT_FENGTH * 2] = {0.0};
float32_t fFFT_OutputBuf[FFT_FENGTH] = {0.0};

float32_t fFFT_FIR_OutputBuf[FFT_FENGTH] = {0.0};

#define BLOCK_SIZE                1024        //μ÷óÃarm_fir_f32′|àíμÄ2éÑùμã¸öêy
#define NUM_TAPS 100                //ÂË2¨Æ÷Ïμêy¸öêy

uint32_t u32BlockSize = BLOCK_SIZE;
uint32_t u32NumBlocks = FFT_FENGTH / BLOCK_SIZE;        //Dèòaμ÷óÃarm_fir_f32μÄ′Îêy
float32_t fFIR_input[FFT_FENGTH] = {0.0};        //2éÑùμã
float32_t fFIR_Output[FFT_FENGTH] = {0.0};        //ÂË2¨oóμÄêä3ö
float32_t        fFIR_StateBuf[BLOCK_SIZE + NUM_TAPS - 1] = {0.0};        //×′쬻o′æ
float32_t fFIR_Coeffs[NUM_TAPS] = {
-0.0004449822882,-0.000529786048,-0.0004296849656, -0.00015425522, 0.000231205282,
   0.000608043687,0.0008274181164,0.0007575381314,0.0003448091738,-0.0003353640495,
  -0.001068142592,-0.001550090848,-0.001498236787,-0.0007839158643,0.0004647070309,
   0.001848744578, 0.002804118674,  0.00280921231, 0.001625645091,-0.0005284877843,
   -0.00296607567,-0.004720899742,-0.004900803789,-0.003084987402,0.0003970534308,
   0.004448343068, 0.007507949602, 0.008109144866, 0.005506821442,0.0001263979357,
  -0.006383617874, -0.01158876345, -0.01310589258,-0.009574958123,-0.001402036985,
   0.009059074335,  0.01805452444,  0.02162205242,  0.01708529331, 0.004346948117,
   -0.01352019794, -0.03069991618, -0.04007250071, -0.03531132266, -0.01301661879,
    0.02580606192,  0.07545947284,   0.1266504675,   0.1687272042,   0.1924432814,
     0.1924432814,   0.1687272042,   0.1266504675,  0.07545947284,  0.02580606192,
   -0.01301661879, -0.03531132266, -0.04007250071, -0.03069991618, -0.01352019794,
   0.004346948117,  0.01708529331,  0.02162205242,  0.01805452444, 0.009059074335,
  -0.001402036985,-0.009574958123, -0.01310589258, -0.01158876345,-0.006383617874,
  0.0001263979357, 0.005506821442, 0.008109144866, 0.007507949602, 0.004448343068,
  0.0003970534308,-0.003084987402,-0.004900803789,-0.004720899742, -0.00296607567,
  -0.0005284877843, 0.001625645091,  0.00280921231, 0.002804118674, 0.001848744578,
  0.0004647070309,-0.0007839158643,-0.001498236787,-0.001550090848,-0.001068142592,
  -0.0003353640495,0.0003448091738,0.0007575381314,0.0008274181164, 0.000608043687,
   0.000231205282, -0.00015425522,-0.0004296849656,-0.000529786048,-0.0004449822882
};        //ÂË2¨Ïμêy

void FFT_test(void)
{
        uint32_t u32i = 0;
        arm_cfft_radix4_instance_f32 scFFT;
       
        u16TIM6_couter_FFT = 0;

        arm_cfft_radix4_init_f32(&scFFT, FFT_FENGTH, 0, 1);        //3õê¼»ˉscFFT½á11ì壬é趨FFT2Îêy
        for(u32i = 0; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_InputBuf[u32i*2] = 100 + 10*arm_sin_f32(2*PI*u32i/FFT_FENGTH) + 30*arm_sin_f32(2*PI*u32i*4/FFT_FENGTH) + 50*arm_sin_f32(2*PI*u32i*8/FFT_FENGTH) + 100*arm_sin_f32(2*PI*u32i*200/FFT_FENGTH);        //êμ2&#191;
                fFFT_InputBuf[u32i*2+1] = 0;        //Dé2&#191;è&#171;2&#191;&#206;a0
                fFIR_input[u32i] = fFFT_InputBuf[u32i*2];
        }
        arm_cfft_radix4_f32(&scFFT, fFFT_InputBuf);        //FFT±&#228;&#187;&#187;
        arm_cmplx_mag_f32(fFFT_InputBuf, fFFT_OutputBuf, FFT_FENGTH);        //&#199;ó&#196;£
        fFFT_OutputBuf[0] = fFFT_OutputBuf[0] / FFT_FENGTH;        //&#199;ó·ù&#214;μ
        for(u32i = 1; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_OutputBuf[u32i] = fFFT_OutputBuf[u32i] / (FFT_FENGTH / 2);
        }
       
        u16FFT_time_ms = u16TIM6_couter_FFT;
}


void FIR_test(void)
{
        uint32_t u32i = 0;
        arm_fir_instance_f32 S;
        float32_t *fInput;
        float32_t *fOutput;
        arm_cfft_radix4_instance_f32 scFFT;
       
        u16TIM6_couter_FIR = 0;
       
        fInput = fFIR_input;
        fOutput = fFIR_Output;
        arm_fir_init_f32(&S, NUM_TAPS, fFIR_Coeffs, fFIR_StateBuf, u32BlockSize);
        for(u32i = 0; u32i < u32NumBlocks; u32i++)
        {
                arm_fir_f32(&S, fInput+(u32i*u32BlockSize), fOutput+(u32i*u32BlockSize), u32BlockSize);
        }
       
        arm_cfft_radix4_init_f32(&scFFT, FFT_FENGTH, 0, 1);        //3&#245;ê&#188;&#187;ˉscFFT&#189;á11ì&#229;£&#172;éè&#182;¨FFT2&#206;êy
        for(u32i = 0; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_InputBuf[u32i*2] = fFIR_Output[u32i];        //êμ2&#191;
                fFFT_InputBuf[u32i*2+1] = 0;        //Dé2&#191;è&#171;2&#191;&#206;a0
        }
        arm_cfft_radix4_f32(&scFFT, fFFT_InputBuf);        //FFT±&#228;&#187;&#187;
        arm_cmplx_mag_f32(fFFT_InputBuf, fFFT_FIR_OutputBuf, FFT_FENGTH);        //&#199;ó&#196;£
        fFFT_FIR_OutputBuf[0] = fFFT_FIR_OutputBuf[0] / FFT_FENGTH;        //&#199;ó·ù&#214;μ
        for(u32i = 1; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_FIR_OutputBuf[u32i] = fFFT_FIR_OutputBuf[u32i] / (FFT_FENGTH / 2);
        }
       
        u16FIR_time_ms = u16TIM6_couter_FIR;
}


先上代码
问题1:
void FFT_test(void)   未使用FPU耗时14ms,使用FPU耗时13ms
void FIR_test(void)   未使用FPU耗时18ms,使用FPU耗时18ms
时间使用u16FFT_time_ms 、u16FIR_time_ms分别测量(TIM6定时1ms)的,测量精度比较低,但还是可以看出FPU基本没起作用,请问是否正常?
问题2:
void FFT_test(void)是对常量+1Hz+4Hz+8Hz+200Hz的1024个点的FFT变换,结果如下:
0  100.000038
1 10.0000191
4 30.0000877
8 99.9999161
200 10.0000191
其他频率都在 0.000135251816附近
可以看出FFT的计算还是很靠谱的

void FIR_test(void)是对常量+1Hz+4Hz+8Hz+200Hz先进行99阶的FIR低通滤波,截止频率为100Hz,后再对FIR滤波结果进行FFT变换。结果见附图
可以看到0、1、4、8以外的点都从0.0001左右上升到1~4左右了,FIR使得低频信号有所失真,请问这种失真属于正常么?


问题3:安富莱DSP FIR教程中有每次处理数据量的做法,请问是何意义?我测试了一次处理1024个点也是没有问题的。见附图2

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。