写这篇文章之前,我是调试了差不多一整天,并不是我对快速傅里叶变换了解透了。只是把ST官方库实现FFT怎么用了解的差不多了。为什么单片机上要用FFT转化?
在个人上说,只能说上面吃饱 了没事干,上位机已经弄好的,非得弄到下位机来搞。而且因为肺炎的原因,个人那微不足道的工资又TM打了个7折,所以心情很不爽。不过从理性角度来说,如果算法可以用在下位机上对产品来说是很好的,毕竟脱离的电脑。
在上位机与下位机之间用FFT有什么区别?为什么我们要用ST官网的FFT算法,我们直接移植上位机的算法不就好了吗?其实,我开始也是这么想的。但是移植过程中发下因为上位机是使用MATLAB里的函数,电脑内存动不动就是8个G。奈何我们STM也就128K,那资源简直是天壤之别。
废话不多说,我们直接来上代码。
一、怎么移植,和网上说的都差不多,我就不废话了。
二、废话不多说,直接上代码。
这个是用4096个点的,运算出来的结果出来是2048的值(取模),至于为什么不是4096个点?因为时域经过FFT后到频域后值都是对称的,所以2048是正确的。
#include "arm_math.h"
#include "arm_const_structs.h"
#define FFT_LENGTH 4096
/* -------------------------------------------------------------------
* External Input and Output buffer Declarations for FFT Bin Example
* ------------------------------------------------------------------- */
float Input1_f32_10khz[FFT_LENGTH*2];//FFT input date
static float32_t testOutput[FFT_LENGTH/2];
/* ------------------------------------------------------------------
* Global variables for FFT Bin Example
* ------------------------------------------------------------------- */
uint32_t ifftFlag = 0;
uint32_t doBitReverse = 1;
/* Reference index at which max energy of bin ocuurs */
uint32_t refIndex = 213, testIndex = 0;
void StartTask06(void const * argument)
{
uint16_t i;
// arm_cfft_radix4_instance_f32 scfft;
arm_status status;
float32_t maxValue;
arm_cfft_f32(&arm_cfft_sR_f32_len4096, Input1_f32_10khz, ifftFlag, doBitReverse);
/* Process the data through the Complex Magnitude Module for
calculating the magnitude at each bin */
arm_cmplx_mag_f32(Input1_f32_10khz, testOutput, FFT_LENGTH/2);
/* Calculates maxValue and returns corresponding BIN value */
// arm_max_f32(testOutput, FFT_LENGTH/2, &maxValue, &testIndex);
}
}
特别注意,STM32 DSP输入值是向量,有实部与虚部。所以数组进入的点虚部是要填0的。我在这里翻车了。
我这里有更详细的代码。包括运算512、1024、2048、4096个点的计算。还有输入信号,与FFT运算后的结果。大家可以移植进去,然后与我的结果对比。先申明,我的结果是完全正确的,与matlab有比较。如果有需要的话,大家花点积分下载。毕竟调试不容易。传送门见下
详细代码