最近采用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(我也不懂,但依照着修改,呵呵)。
1
按照这个约束,重新理清思路:先在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倍。
上一篇:STM32F4学习笔记4——STM32的AD用DMA方式时的请注意初始化顺序
下一篇:STM32F4学习笔记1——如何使用DSP库
推荐阅读最新更新时间:2024-03-16 16:24