#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¿
fFFT_InputBuf[u32i*2+1] = 0; //Dé2¿è«2¿Îa0
fFIR_input[u32i] = fFFT_InputBuf[u32i*2];
}
arm_cfft_radix4_f32(&scFFT, fFFT_InputBuf); //FFT񄯯
arm_cmplx_mag_f32(fFFT_InputBuf, fFFT_OutputBuf, FFT_FENGTH); //ÇóÄ£
fFFT_OutputBuf[0] = fFFT_OutputBuf[0] / FFT_FENGTH; //Çó·ùÖμ
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õê¼»ˉscFFT½á11ì壬é趨FFT2Îêy
for(u32i = 0; u32i < FFT_FENGTH; u32i++)
{
fFFT_InputBuf[u32i*2] = fFIR_Output[u32i]; //êμ2¿
fFFT_InputBuf[u32i*2+1] = 0; //Dé2¿è«2¿Îa0
}
arm_cfft_radix4_f32(&scFFT, fFFT_InputBuf); //FFT񄯯
arm_cmplx_mag_f32(fFFT_InputBuf, fFFT_FIR_OutputBuf, FFT_FENGTH); //ÇóÄ£
fFFT_FIR_OutputBuf[0] = fFFT_FIR_OutputBuf[0] / FFT_FENGTH; //Çó·ùÖμ
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
一周热门 更多>