本帖最后由 zhangbaoyin 于 2023-7-6 17:21 编辑
【雅特力AT-START-F435】基于DSP库实数的FFT和逆FFT变换
一、工程模板更改
- 找到AT32固件库中的cmsis中的DSP库,路径如下
- 添加dsp库的文件如下图所示:
- 只需要添加如图所示的文件就行,其他文件都通过这个c文件包含了
- 添加头文件
- 建议开启AC6编译,这样可以节约一些代码空间
测试编译测试一下,如果没有报错就好了
二、FFT
在 TransformFunctions.c 中包含了所有的 FFT 和 RFFT(reverser fft 逆变换),编译之后展开会有包含的所有函数体的文件(一个函数功能一个c文件)
FFT正向变换,主要使用的是 arm_rfft_f32.c 实信号的正向FFT,单精度浮点32bit的运算。打开该文件,在代码 564 有该函数的描述:
可以发现,要使用正向FFT变换,需要下调用一个前向函数 arm_rfft_fast_init_f32() 初始化,该函数也有一个单独的c文件存放,直接调用就好。
- 参数 S :是一个结构体,从初始化结构体中产出。
- 参数 p :是一个指向源数据的数组
- 参数 pOut :是一个指向结果数据的数组
- 参数 ifftFlag :为 0 表示正变换,为 1 表示逆变换。数据流动方向都是从 p -> pOut
在主函数中调用如下:
arm_rfft_fast_init_f32(&S, 1024);
/* 1024 点实序列快速 FFT */
arm_rfft_fast_f32(&S, testInput_f32, testOutput_f32, ifftFlag);
三、FFT -> 幅频响应
FFT变换之后,不论是实信号还是复信号,结构都会变成一个复数,a + bi
在结果存放中,以两个数据位组合成一个组合,第一个位置存放的是实部 a ,第二个位置存放的是虚部 b
欲求得幅频响应,对每一个数据组取模,(a^2 + b^2) ^ (1/2) 就能得到该频率下的幅值
对于复数的模,也有加速的函数 arm_cmplx_mag_f32(); 调用方式如下:
/* 这里求解了 1024 组模值,实际函数 arm_rfft_fast_f32只求解出了 512 组 */
arm_cmplx_mag_f32(testOutput_f32, testOutputMag_f32, TEST_LENGTH_SAMPLES);
四、FFT逆变换
在 (二、FFT) 中可以知道,只需要将u8位 ifftFlag 置1就可求得FFT逆变换
/* 1024 点实序列快速逆 FFT */
ifftFlag = 1;
arm_rfft_fast_f32(&S, testOutput_f32, testRfft_f32, ifftFlag);
五、实验效果
- 使能按键中断,按键按下后,切换波形输出(原始波形、FFT变换->FFT逆变换之后的波形)
- 对比两个波形,如果一直,则FFT验证通过
- LED3亮、LED4灭,为原始波形
- LED3灭、LED4亮,为转换波形
2da62cbe11a482e1d1c03b3f789bc065
占用资源大小如下:
Code (inc. data) RO Data RW Data ZI Data Debug
12524 352 81680 40 53344 278227 Grand Totals
12524 352 81680 40 53344 278227 ELF Image Totals
12524 352 81680 40 0 0 ROM Totals
==============================================================================
Total RO Size (Code + RO Data) 94204 ( 92.00kB)
Total RW Size (RW Data + ZI Data) 53384 ( 52.13kB)
Total ROM Size (Code + RO Data + RW Data) 94244 ( 92.04kB)
==============================================================================