一般情况下M33 M4的内核是支持DSP包的,用户只需要自己添加支持包,并添加相应的头文件即可,比如#include "arm_math.h",#include "arm_const_structs.h" 等等。
(1)main.c
#include "gd32f30x.h"
#include "stdio.h"
#include "string.h"
#include "arm_math.h"
#include "arm_const_structs.h"
#define FFT_LENGTH 512 //做512个点的FFT
#define SAMPLING_RATE 640 //计算final_value_a 数组的采样率
#define TARGET_FREQUENCY 1.25f //要IFF还原的目标频率
float32_t fft_output_a[FFT_LENGTH];
float32_t final_value_a[FFT_LENGTH * 2]; //采集到的数据,按照复数的形式保存
float32_t ifft_output_a[FFT_LENGTH];
arm_cfft_radix2_instance_f32 Ua_cfft_config; //声明fft变换结构体
arm_cfft_radix2_instance_f32 Ua_ifft_config; //声明ifft变换结构体
int main(void)
{
arm_cfft_radix2_init_f32(&Ua_cfft_config, FFT_LENGTH, 0, 1); //配置正变换
arm_cfft_radix2_init_f32(&Ua_ifft_config, FFT_LENGTH, 1, 1); //配置逆变换
while(1)
{
arm_cfft_radix2_f32(&Ua_cfft_config,final_value_a); //基2的FFT
//fft_output_a[FFT_LENGTH]为频谱
arm_cmplx_mag_f32(final_value_a,fft_output_a,FFT_LENGTH);
//计算1.25HZ的索引位置,看看1.25HZ的波形在频谱中的第几个点
int target_index = (int)((float)FFT_LENGTH * TARGET_FREQUENCY / SAMPLING_RATE);
float32_t target_amplitude_a,target_amplitude_b;
float32_t target_phase_a,target_phase_b;
//提取1.25Hz振幅
arm_sqrt_f32(final_value_a[2 * target_index] * final_value_a[2 * target_index] +
final_value_a[2 * target_index + 1] * final_value_a[2 * target_index + 1],&target_amplitude_a);
//提取1.25Hz相位
target_phase_a = atan2f(final_value_a[2 * target_index + 1], final_value_a[2 * target_index]);
for (int i = 0; i < FFT_LENGTH; i++) // 构造IFFT输入数组
{
if (i == target_index )
{
final_value_a[2 * i] = target_amplitude_a * cos(target_phase_a);
final_value_a[2 * i + 1] = target_amplitude_a * sin(target_phase_a);
}
else
{
final_value_a[2 * i] = 0.0f;
final_value_a[2 * i + 1] = 0.0f;
}
}
arm_cfft_radix2_f32(&Ua_ifft_config, final_value_a); //基2的IFFT
for (int i = 0; i < FFT_LENGTH; i++) //提取IFFT数组的实部,就是还原的1.25HZ的波形
{
ifft_output_a[i] = final_value_a[2 * i];
}
}
}
注意:(1)根据奈奎斯特-香农采样定理,要对一个连续时间信号进行完美的重构,需要以不低于信号最高频率两倍的采样频率对其进行采样。简而言之,采样率越高,采到的目标频率的最大幅值的可能性越大
(2)通过fft想要滤除一些波形,得到自己想要的波形,首先要保证目标波形为整周期的波形,否则会出现频谱泄露的问题。
目前还没有摸索到如果通过不是完整周期,怎么FFT和IFFT,不过,听人说可以通过自己写DFT函数来实现,算了有时间再搞!