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

最近采用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)

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值