FFT,即快速傅里叶变换,是一种测量信号频率的方法。在2023年H题、2021年A题中,均用到了fft算法。FFT算法往往配合高速AD采样、DMA配合使用,由于stm32cubemx里面有DSP库,所以我们可以使用官方的fft函数,这样做简单高效,准确度高。
下面我来详细介绍一下FFT算法,以及如何使用ADC+FFT测量信号频率。我争取用这一篇文章,帮你们彻底学会stm32的FFT实现。
我的2023H题代码在这里,建议看懂这篇文章,再根据我的代码修改。直接用大概率会出问题,毕竟我们用的开发板可能不一样,而且我用了三个AD采样引脚(实际只用了两个,第三个本来打算做反馈调节的,时间不够就没搞了),由接了3个AD9833模块作为输出,所以直接复制粘贴肯定搞不定。
链接: https://pan.baidu.com/s/1dMlcS2DNF-SYfLU5yADhtQ?pwd=ee7n 提取码: ee7n 复制这段内容后打开百度网盘手机App,操作更方便哦
FFT详解
什么是FFT
FFT是快速傅里叶变换的简称,这里我不介绍数学上的原理了,想要了解数学原理的话可以看这个:十分简明易懂的FFT(快速傅里叶变换)_路人黑的纸巾的博客-CSDN博客
咱们搞单片机的可以不需要知道它是怎么算的,只需要知道FFT的作用就行——计算信号的频率。对傅里叶变换有了解的都知道任何函数都可以写成几个正弦函数的和,只要知道各个sin函数的模值、频率、相位,就可以将这些个正弦函数写出来,把他们加起来就是这个信号的波形。
FFT可以得到不同频率的sin对应的实部和虚部,根据实部和虚部就可以得到模值与角度,从而写出信号的傅里叶变换式。咱们学单片机的只需要知道怎么处理FFT得到的数据,从而计算出信号频率就OK了。
单片机FFT原理及使用
单片机中,FFT通常会与AD采样一起使用。它的原理很简单,如下图:
首先要确定采样频率和采样个数。根据奈奎斯特采样定理,采样频率需要大于信号频率的两倍。由于采样频率越低,采集相同的点所需的时间越长,采集到的周期数会越多,结论会越精确,所以理论上采样频率越低越好,且不能低于输入信号的两倍。
采样个数的话,一般我是取1024个点。理论上采样的点越多越精确,越少花的时间越短。不过采样点数太少会导致LSB特别大,精度降得很厉害。采样点数太多的话会导致采样时间过长,且占用的内存会很大,计算量也会比较大。采样点数是2的k次幂,官方函数貌似最大是4096个点(我没试过)。
确定了采样频率f_s和采样个数n后,就可以使用ADC采样了。由于采样的点较多,建议使用DMA传输ADC数据。将这n个数据放入到数组a[n]里,这个数组a[n]就是输入的数据。然后我们就可以开始进行FFT计算了。
需要注意的是,官方FFT函数需要输入的数组是A[2n],这需要你对a[n]进行预处理。将ADC数据按顺序放到A[2n]的偶数位作为实部,