STM32F4学习笔记2——自建库函数整合FFT计算遇到的问题及解决方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hnxyxiaomeng/article/details/53122346

最近采用FFT计算信号频谱,需要先减去信号均值,参考网上看到的范例,实现了功能,代码为:

arm_mean_f32(DataBuffer, SIG_N, &MeanData);
for (int16_t k = 0 ; k <= SIG_N - 1 ; k++) {
DeMeanDataBuffer[k] = DataBuffer[k] - MeanData;
}

arm_mean_f32(DeMeanDataBuffer, SIG_N, &MeanData2);
arm_status status; 
arm_cfft_radix2_instance_f32 S;  
status = ARM_MATH_SUCCESS; 

status = arm_cfft_radix2_init_f32(&S, FFT_N,ifftFlag, doBitReverse); 

arm_cfft_radix2_f32(&S,DeMeanDataBuffer); 

arm_cmplx_mag_f32(DeMeanDataBuffer, FFT_Output, FFT_N);

但是上面这一段代码都要放在main函数中,对于追求简洁的我来说,这是无法忍受的。于是建头文件,自己写了个库函数,将上述代码打包,函数实现代码如下:

#include "xiao_fft.h"
#include "xiao_array.h"

void xiao_FFT_f32(
float32_t* FFT_Data,
  uint32_t FFTSize,
float32_t* FFT_Mag)
{
float32_t MeanData = 0;

float32_t FFT_Mag[FFTSize];
float32_t DeMeanData[FFTSize*2];
uint32_t ifftFlag = 0; 
uint32_t doBitReverse = 1;
arm_mean_f32(FFT_Data, FFTSize*2, &MeanData);
for ( int32_t k = 0 ; k <= FFTSize*2 - 1 ; k++) {
*(DeMeanData+k) = *(FFT_Data+k) - MeanData;
}
  arm_status status; 
arm_cfft_radix2_instance_f32 S;  
status = ARM_MATH_SUCCESS; 

status = arm_cfft_radix2_init_f32(&S, FFTSize,ifftFlag, doBitReverse); 

arm_cfft_radix2_f32(&S,FFT_Data); 

arm_cmplx_mag_f32(FFT_Data, FFT_Mag, FFTSize);
return;
}
    然而,问题出现了。函数始终无法返回FFT幅度值(FFT_Mag)。经断点调试发现,在函数arm_cfft_radix2_f32中进入了HardFault_Handler中断。在网上参考大神资料,发现原因如下:不要在函数内部定义超过几十个字节的大数组,不然会引起数组越界或堆栈溢出。而上述代码定义了大数组DeMeanData(我也不懂,但依照着修改,呵呵)。

按照这个约束,重新理清思路:先在main函数中去data均值,得到demean_data,然后再进行FFT。实现代码如下:

/////////////////////////////////////////////////////
xiao_demean_array_f32(DataBuffer,SIG_N,DeMeanDataBuffer);
xiao_FFT_f32(DeMeanDataBuffer,FFT_N,FFT_Output);

///////////////////////////////////////////////////
#include "xiao_array.h"
void xiao_demean_array_f32(
float32_t* xiao_array_data,
  uint32_t xiao_array_size,
float32_t* xiao_array_demean_data)
{
float32_t mean_data = 0;
arm_mean_f32(xiao_array_data, xiao_array_size, &mean_data);
for ( int32_t k = 0 ; k <= xiao_array_size - 1 ; k++) {
*(xiao_array_demean_data+k) = *(xiao_array_data+k) - mean_data;
}
}

/////////////////////////////////////////////////////

#include "xiao_fft.h"
#include "xiao_array.h"


void xiao_FFT_f32(
float32_t* FFT_Data,
  uint32_t FFTSize,
float32_t* FFT_Mag)
{

uint32_t ifftFlag = 0; 
uint32_t doBitReverse = 1;
  arm_status status; 
arm_cfft_radix2_instance_f32 S;  
status = ARM_MATH_SUCCESS; 

status = arm_cfft_radix2_init_f32(&S, FFTSize,ifftFlag, doBitReverse); 

arm_cfft_radix2_f32(&S,FFT_Data); 

arm_cmplx_mag_f32(FFT_Data, FFT_Mag, FFTSize);
return;
}

这下成功了!撒花庆祝!
另外,STM32的DSP库中,计算FFT时要求数据长度data_len必须是FFT点数FFT_Size的2倍。

(2016-04-17)

阅读更多
想对作者说点什么?
相关热词

博主推荐

换一批

没有更多推荐了,返回首页