CMSIS DSP FFT
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采样信号(实部虚部交错,虚部设置为0)
在使用单片机的ADC功能进行采样时,有几个概念需要注意:
- 采样率 f_s:单位时间内对连续信号采样的次数,即用于触发ADC的定时器的频率。根据Nyquist采样定理,采样率f_s至少是信号最高频率的两倍
- FFT点数 N:即DMA缓冲数组的长度,也是函数中的FFT_LEN
- 采样时间:1/采样率 * FFT点数
- 频率分辨率 Δf:采样率/FFT点数,需保证信号频率应是频率分辨率的整数倍,否则需要加窗函数
进行FFT运算后,时域转换为频域
- fft_buffer[0]:直流分量
- fft_buffer[1]:Nyquist频率(f_s / 2)分量
- fft_buffer[2*i]、fft_buffer[2*i+1]:是频率为 i * 采样率 / FFT点数 所对应复数的实部(Re)和虚部(Im),i 大于1且小于 N/2。由奈奎斯特采样定理可得,信号不可能有比N/2大的频率分量。
函数对输出数组的存储数据进行了优化
索引0(fftBuffer[0]):直流分量(k=0,实部)
索引1(fftBuffer[1]):Nyquist频率(k=N/2,实部)
索引2~N-1:交替存储k=1到k=N/2-1的实部和虚部。
幅度谱和相位谱的计算可根据 信号与系统 课程上的知识,这里不再赘述。另外要注意:
幅度校正:除去直流分量和奈奎斯特点以外,其他频率的幅度应×2
此外,可以利用相位谱来计算两个信号之间的相位差。
如果要将FFT转到物理量纲,则需乘矫正因子