ARM DSP库FFT/IFFT简介

ARM DSP库FFT/IFFT简介

Fri Aug 15 2025 Pin
607 words · 4 minutes

DSP库提供的FFT函数

新版 DSP 库浮点 FFT 推荐使用混合基函数 arm_cfft_f32, 基 2 函数 arm_cfft_radix2_f32 和基 4函数 arm_cfft_radix4_f32 将废弃。 ARM说明如下: DSP 库的早期发行版提供了单独的 radix-2 和 radix-4 对浮点数据进行运算的算法。 这些功能仍然提供,但已弃用。相比新版函数,老版的功能较慢且通用性较低。 当前复数 FFT 函数支持三种数据类型,分别是浮点,定点 Q31 和 Q15。这些 FFT 函数有一个共同的特点,就是用于输入信号的缓冲,在转化结束后用来存储输出结果。这样做的好处是节省了 RAM 空间,不需要为输入和输出结果分别设置缓存。由于是复数 FFT,所以输入和输出缓存要存储实部和虚部。存储顺序如下: {real[0], imag[0], real[1], imag[1],………………} ,在使用中切记不要搞错。

单精度函数

C
arm_cfft_f32
  • 支持16、32、64、128、256、512、1024、2048、4096点单精度复数FFT、IFFT。 用 float(32 位)
  • 在 Cortex-M4 / M7 / M33 / M55 等 MCU 上有硬件 FPU,运算非常快
  • 对大部分 DSP / FFT 应用足够(音频、滤波器、通信)

双精度函数

PLAINTEXT
arm_cfft_f64
  • 支持16、32、64、128、256、512、1024、2048、4096点双精度复数FFT、IFFT
  • 用 double(64 位)
  • 很多 Cortex-M 系列 没有 硬件双精度支持,只能用软件仿真 → 慢很多
  • 适合:需要非常高数值精度(科学计算、极低噪声需求)
  • 在 Cortex-A / Cortex-R 系列(有硬件 double FPU)更合适

代码示例

C
#include "arm_math.h"
#include <math.h>
#include <stdio.h>

#define FFT_SIZE 4096
#define SAMPLE_RATE 10000.0f   // ADC 采样率(举例)

float adc_buffer[FFT_SIZE];          // 存ADC采样的实数数据
float fft_buffer[2*FFT_SIZE];        // 存FFT复数输入/输出

float magnitude[FFT_SIZE/2];         // 存幅值谱  

int main(void)
{
    arm_cfft_instance_f32 S;

    // 1. ADC采样得到adc_buffer[],这里举例模拟一个信号
    for(int i=0;i<FFT_SIZE;i++) {
        adc_buffer[i] = arm_sin_f32(2*PI*1000*i/SAMPLE_RATE); // 1 kHz 正弦
    }

    // 2. 准备FFT输入(实部=adc数据,虚部=0)
    for(int i=0;i<FFT_SIZE;i++) {
        fft_buffer[2*i]   = adc_buffer[i];  // 实部
        fft_buffer[2*i+1] = 0.0f;           // 虚部
    }

    // 3. 初始化FFT
    arm_cfft_init_f32(&S, FFT_SIZE);

    // 4. 做FFT(ifftFlag=0表示FFT;doBitReverse=1输出正常顺序)
    arm_cfft_f32(&S, fft_buffer, 0, 1);

    // 5. 计算幅值谱,只取前 N/2 点
    for(int i=0;i<FFT_SIZE/2;i++) {
        float real = fft_buffer[2*i];
        float imag = fft_buffer[2*i+1];
        magnitude[i] = sqrtf(real*real + imag*imag);
    }

    // 6. 分析频率
    printf("Bin\tFreq(Hz)\tMagnitude\n");
    for(int i=0;i<FFT_SIZE/2;i++) {
        float freq = (i * SAMPLE_RATE) / FFT_SIZE;
        printf("%d\t%.1f\t\t%f\n", i, freq, magnitude[i]);
    }

    return 0;
}

部分内容引用出处: https://blog.csdn.net/qq_39376872/article/details/144627538


Thanks for reading!

ARM DSP库FFT/IFFT简介

Fri Aug 15 2025 Pin
607 words · 4 minutes