FFT 即 傅里叶变换

1. 初始化

#define FFT_LEN 1024
arm_rfft_fast_instance_f32 S;
arm_rfft_fast_init_f32(&S,FFT_LEN);

S应作为全局变量或长期存在的变量,避免反复初始化

FFT_LEN应为2的幂次

2. 傅里叶变换

float32_t fft_buffer[FFT_LEN*2];
arm_rfft_fast_f32(&S,fft_buffer,fft_buffer,0);

void arm_rfft_fast_f32(
    arm_rfft_fast_instance_f32 *S,  // FFT配置结构体
    float32_t *p,                  // 输入/输出缓冲区(实部)
    float32_t *q,                  // 输出缓冲区(虚部,可复用输入缓冲区)
    uint8_t ifftFlag               // 0=正变换(时域→频域),1=逆变换(频域→时域)
);

进行FFT运算前,fft_buffer存储的是ADC采样信号

在使用单片机的ADC功能进行采样时,有几个概念需要注意:

  • 采样率 f_s:单位时间内对连续信号采样的次数,即用于触发ADC的定时器的频率。根据Nyquist采样定理,采样率f_s至少是信号最高频率的两倍
  • FFT点数 N:即DMA缓冲数组的长度,也是函数中的FFT_LEN
  • 采样时间:1/采样率 * FFT点数
  • 频率分辨率 Δf:采样率/FFT点数,需保证信号频率应是频率分辨率的整数倍,否则需要加窗函数

进行FFT运算后,时域转换为频域

  • fft_buffer[2*i]、fft_buffer[2*i+1]:是频率为 i * 采样率 / FFT点数 所对应复数的实部(Re)和虚部(Im),i 大于1且小于 N/2。由奈奎斯特采样定理可得,信号不可能有比N/2大的频率分量。

此外,可以利用相位谱来计算两个信号之间的相位差。

如果要将FFT转到物理量纲,则需乘矫正因子  \frac{2}{N}

记录一下在使用FFT过程中遇到的问题:

多次使用FFT的时,最好先将Input和Output初始化置0

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐