寫這篇文章之前,我是調試了差不多一整天,並不是我對快速傅里葉變換了解透了。只是把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有比較。如果有需要的話,大家花點積分下載。畢竟調試不容易。傳送門見下
詳細代碼