色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

通俗易懂的講解FFT的讓你快速了解FFT

GReq_mcu168 ? 來源:未知 ? 2019-03-24 11:52 ? 次閱讀

相信網(wǎng)上現(xiàn)在有很多關(guān)于FFT的教程,我曾經(jīng)也參閱了很多網(wǎng)上的教程,感覺都不怎么通俗易懂。在基本上的研究FFT,并且通過編程的形式實現(xiàn)之后。我決定寫一篇通俗易懂的關(guān)于FFT的講解。因此我在接下來的敘述中盡量非常通俗細致的講解。

本人最早知道傅里葉變換的時候是沉迷于音樂的頻譜跳動無法自拔,當時就很想做一個音樂頻譜顯示器。搜閱了很多資料之后,才了解到傅里葉變換,和FFT。當然這都是以前的事情了,經(jīng)過了系統(tǒng)的學(xué)習(xí)+2個星期的研究,自制了一個FFT的算法,不敢說速度上的優(yōu)勢,但是個人認為是一種通俗易懂的實現(xiàn)方法。經(jīng)過實際的VC++模擬實驗、和STM32跑的也很成功。

首先,要會FFT,就必須要對DFT有所了解,因為兩者之間本質(zhì)上是一樣的。在此之前,先列出離散傅里葉變換對(DFT):

,k=0,1,…N-1

n=0,1…N-1

其中:

但是FFT之所以稱之為快速傅里葉變換,就利用了以下的幾個性質(zhì)(重中之重!)

周期性:

對稱性:

可約性:

先把這仨公式放到這,接下來會用到。

根據(jù)這幾個特性,就可以將一個長的DFT運算分解為若干短序列的DFT運算的組合,從而減少運算量。在這里,為了方便理解,我就用了一個按時間抽取的快速傅里葉變換(DIT-FFT)的方法。

首先,將一個序列x(n)一分為二

對于,k=0,1,…N-1? ?設(shè)N是2的整次冪 也就是N=2^M

將x(n)按照奇偶分組

x(2r)=x1(r)

x(2r+1)=x2(r) r=0,1,…..(N/2)-1

那么將DFT也分為兩組來預(yù)算

(第一項是偶第二項是奇)

這個時候,我們上邊提的三個性質(zhì)中的可約性就起到作用了:

回顧一下:

那么這個式子就可以化為:

(式1-1)

則X1(k)和X2(k)都是長度為N/2的序列 x1(k)和x2(k)的N/2點的離散傅里葉變換

其中:

K=0,1,2…N/2-1

至此,一個N點的DFT就被分解為2個N/2的DFT。但是X1(k),和X2(k)只有N/2個點,也就是說式子(1-1)只是DFT前半部分。要求DFT的后半部分可以利用其對稱性求出后半部分為:

(式1-2)

那么式(1-1)和(1-2)就可以專用一個蝶形信號流圖符號來表示。如圖:

以N=8為例,可以用下圖表示:

通過這樣的分解,每一個N/2點DFT只需(N^2)/4次復(fù)數(shù)相乘計算,明顯的節(jié)省了運算量。

以此類推,繼續(xù)將已經(jīng)得出的X1(k)和X2(k)按照奇偶分解,還是和上邊一樣的方法。那么就得出了百度上都可以找到的一大推的這個圖片了。(笑)

對于這張圖片我想強調(diào)的一點就是第二階蝶形運算的時候,WN0之后不應(yīng)該是WN1嗎,為什么是W2N了,這個問題之前困擾了我一段時間,但是不要忘了,前者的 W0N的展開是W0N/2因為此時N已經(jīng)按照奇偶分開了,所以是N/2而W2N/2也就是W2N是根據(jù)可約性得出的,在這里不能混淆.。

對于運算效率就不用多提了

以上就是FFT算法的理論內(nèi)容了,接下來就是用C語言對這個算法的實現(xiàn)了,對于FFT算法C語言的實現(xiàn),網(wǎng)上的方法層出不窮,介于本人比較懶(懶得看別人的程序),再加上自給自足豐衣足食的原則,我自己也寫了一個個人認為比較通俗易懂的程序,并且為了幫助讀者理解,我特意盡量減少了庫函數(shù)的使用,一些基本的函數(shù)都是自己寫的(難免有很多BUG),但是作為FFT算法已經(jīng)夠用了,目前這個程序只能處理2^N的數(shù)據(jù),理論上來講如果不夠2^N的話可以在后面數(shù)列補0這種操作為了簡約我也就沒有實現(xiàn),但是主要的功能是具備的,下面是代碼:

/*

時間:2018年11月24日

功能:將input里的數(shù)據(jù)進行快速傅里葉變換 并且輸出

*/

#include

#include

#define PI 3.1415926

#define FFT_LENGTH 8

double input[FFT_LENGTH]={1,1,1,1,1,1,1,1};

struct complex1{ //定義一個復(fù)數(shù)結(jié)構(gòu)體

double real; //實部

double image; //虛部

};

//將input的實數(shù)結(jié)果存放為復(fù)數(shù)

struct complex1 result_dat[8];

/* 虛數(shù)的乘法

*/

struct complex1 con_complex(struct complex1 a,struct complex1 b){

struct complex1 temp;

temp.real=(a.real*b.real)-(a.image*b.image);

temp.image=(a.image*b.real)+(a.real*b.image);

return temp;

}

/*

簡單的a的b次方

*/

int mypow(int a,int b){

int i,sum=a;

if(b==0)return 1;

for(i=1;i

sum*=a;

}

return sum;

}

/*

簡單的求以2為底的正整數(shù)

*/

int log2(int n){

unsigned i=1;

int sum=1;

for(i;;i++){

sum*=2;

if(sum>=n)break;

}

return i;

}

/*

簡單的交換數(shù)據(jù)的函數(shù)

*/

void swap(struct complex1 *a,struct complex1 *b){

struct complex1 temp;

temp=*a;

*a=*b;

*b=temp;

}

/*

dat為輸入數(shù)據(jù)的數(shù)組

N為抽樣次數(shù) 也代表周期 必須是2^N次方

*/

void fft(struct complex1 dat[],unsigned char N){

/*最終 dat_buf計算出 當前蝶形運算奇數(shù)項與W 乘積

dat_org存放上一個偶數(shù)項的值

*/

struct complex1 dat_buf,dat_org;

/* L為幾級蝶形運算 也代表了2進制的位數(shù)

n為當前級蝶形的需要次數(shù) n最初為N/2 每級蝶形運算后都要/2

i j為倒位時要用到的自增符號 同時 i也用到了L碟級數(shù) j是計算當前碟級的計算次數(shù)

re_i i_copy均是倒位時用到的變量

k為當前碟級 cos(2*pi/N*k)的 k 也是e^(-j2*pi/N)*k 的 k

*/

unsigned char L,i,j,re_i=0,i_copy=0,k=0,fft_flag=1;

//經(jīng)過觀察,發(fā)現(xiàn)每級蝶形運算需要N/2次運算,共運算N/2*log2N 次

unsigned char fft_counter=0;

//在此要進行補2 N必須是2^n 在此略

//蝶形級數(shù) (L級)

L=log2(N);

//計算每級蝶形計算的次數(shù)(這里只是一個初始值) 之后每次要/2

//n=N/2;

//對dat的順序進行倒位

for(i=1;i

i_copy=i;

re_i=0;

for(j=L-1;j>0;j--){

//判斷i的副本最低位的數(shù)字 并且移動到最高位 次高位 ..

//re_i為交換的數(shù) 每次它的數(shù)字是不能移動的 并且循環(huán)之后要清0

re_i|=((i_copy&0x01)<

i_copy>>=1;

}

swap(&dat[i],&dat[re_i]);

}

//進行fft計算

for(i=0;i

fft_flag=1;

fft_counter=0;

for(j=0;j

if(fft_counter==mypow(2,i)){ //控制隔幾次,運算幾次,

fft_flag=0;

}else if(fft_counter==0){ //休止結(jié)束,繼續(xù)運算

fft_flag=1;

}

//當不判斷這個語句的時候 fft_flag保持 這樣就可以持續(xù)運算了

if(fft_flag){

dat_buf.real=cos((2*PI*k)/(N/mypow(2,L-i-1)));

dat_buf.image=-sin((2*PI*k)/(N/mypow(2,L-i-1)));

dat_buf=con_complex(dat[j+mypow(2,i)],dat_buf);

//計算 當前蝶形運算奇數(shù)項與W 乘積

dat_org.real=dat[j].real;

dat_org.image=dat[j].image; //暫存

dat[j].real=dat_org.real+dat_buf.real;

dat[j].image=dat_org.image+dat_buf.image;

//實部加實部 虛部加虛部

dat[j+mypow(2,i)].real=dat_org.real-dat_buf.real;

dat[j+mypow(2,i)].image=dat_org.image-dat_buf.image;

//實部減實部 虛部減虛部

k++;

fft_counter++;

}else{

fft_counter--; //運算幾次,就休止幾次

k=0;

}

}

}

}

void main(){

int i;

//先將輸入信號轉(zhuǎn)換成復(fù)數(shù)

for(i=0;i

result_dat[i].image=0;

//輸入信號是二維的,暫時不存在復(fù)數(shù)

result_dat[i].real=input[i];

//result_dat[i].real=10;

//輸入信號都為實數(shù)

}

fft(result_dat,FFT_LENGTH);

for(i=0;i

input[i]=sqrt(result_dat[i].real*result_dat[i].real+result_dat[i].image*result_dat[i].image);

//取模

printf("%lf\n",input[i]);

}

while(1);

}

這個程序中input這個數(shù)組是輸入信號,在這里只模擬抽樣了8次,輸出的數(shù)據(jù)也是input,如果想看其它序列的話,可以改變FFT_LENGTH的值以及input里的內(nèi)容,程序輸出的是實部和虛部的模,如果單純想看實部或者虛部的幅度的話,請自行修改程序~這就是本次淺談FFT以及FFT算法的基本實現(xiàn)的全部內(nèi)容了參考書籍:數(shù)字信號處理

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FFT
    FFT
    +關(guān)注

    關(guān)注

    15

    文章

    438

    瀏覽量

    60073
  • STM32
    +關(guān)注

    關(guān)注

    2281

    文章

    10971

    瀏覽量

    360362
  • DFT
    DFT
    +關(guān)注

    關(guān)注

    2

    文章

    232

    瀏覽量

    23065

原文標題:高手分享:一篇通俗易懂的關(guān)于FFT的講解

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 5人收藏
  • jf_546700661

評論

相關(guān)推薦

通俗易懂的PID教程

本帖最后由 Calvin248 于 2013-5-5 15:31 編輯 幫助大家更好的理解PID算法,講解的很通俗易懂,并且附有程序,幫助大家理解掌握!
發(fā)表于 05-05 15:30

通俗易懂的PID算法

發(fā)幾個通俗易懂的PID算法,需要的拿走
發(fā)表于 01-26 00:54

通俗易懂系列整合—電源基礎(chǔ)知識講解

之前發(fā)表了六篇用通俗易懂的話講解電源知識的文章,分別是關(guān)于三極管、電阻、電容、電感、二極管和場效應(yīng)管的講解。怕想學(xué)習(xí)的壇友找不到內(nèi)容,所以這邊整合一下,給大家分享文章的鏈接。用通俗易懂
發(fā)表于 02-17 09:43

標準的PID處理例程(PID通俗易懂講解)[2]

標準的PID處理例程(PID通俗易懂講解)[2]
發(fā)表于 06-13 11:44

PID通俗易懂

PID通俗易懂.....................
發(fā)表于 06-30 18:54

通俗易懂之電子稱開發(fā)導(dǎo)航篇

通俗易懂之電子稱開發(fā)立項篇https://bbs.elecfans.com/jishu_919726_1_1.html通俗易懂之電子稱開發(fā)硬件篇https://bbs.elecfans.com
發(fā)表于 07-18 21:22

用最基礎(chǔ)的繼電器通俗易懂講解門電路

【轉(zhuǎn)載理由:用最基礎(chǔ)的繼電器通俗易懂講解門電路,對于理解CPU的與非或等門電路、觸發(fā)器和寄存器有很大幫助】PS:很久之前看的文章了,現(xiàn)在翻出來看看,對于門電路理解很有裨益,也是CPU設(shè)計的基礎(chǔ)閱讀
發(fā)表于 07-30 06:42

通俗易懂的《路由和交換》

通俗易懂的《路由和交換》 路由和交換是網(wǎng)絡(luò)世界中兩個重要的概念。傳統(tǒng)的交換發(fā)生在網(wǎng)絡(luò)的第二層,即數(shù)據(jù)鏈路層,而路由則發(fā)
發(fā)表于 08-01 10:39 ?1029次閱讀

通俗易懂的單片機教程

通俗易懂的單片機教程
發(fā)表于 09-29 15:45 ?637次下載
<b class='flag-5'>通俗易懂</b>的單片機教程

卡爾曼濾波的原理說明(通俗易懂)

通俗易懂的 卡爾曼濾波原理 由淺入深不光是公式的介紹
發(fā)表于 12-08 18:13 ?38次下載

卡爾曼濾波的原理說明(通俗易懂)

這是關(guān)于卡爾曼濾波的原理說明(通俗易懂),適合初學(xué)者
發(fā)表于 03-16 14:40 ?0次下載

PID通俗易懂

PID通俗易懂PID通俗易懂PID通俗易懂PID通俗易懂PID通俗易懂PID通俗易懂
發(fā)表于 04-19 09:54 ?21次下載

步進電機基本原理(通俗易懂)

步進電機基本原理(通俗易懂)
發(fā)表于 11-30 11:55 ?0次下載

通俗易懂的ArkTS語言入門指南

本文為我整理出來最通俗易懂的 ArkTS 語言入門指南。
的頭像 發(fā)表于 06-18 15:12 ?2.3w次閱讀
最<b class='flag-5'>通俗易懂</b>的ArkTS語言入門指南

FFT原理通俗易懂的解釋

FFT原理通俗易懂的解釋? 傅里葉變換(Fourier Transform,簡稱FFT)是一個廣泛應(yīng)用的數(shù)學(xué)工具,它可以將一個連續(xù)或離散信號分解成一系列單一的正弦函數(shù),這些正弦函數(shù)名稱為頻率成分或
的頭像 發(fā)表于 09-07 16:35 ?3576次閱讀
主站蜘蛛池模板: 97精品少妇偷拍AV | 欧美高清另类video | 欧美亚洲韩日午夜 | 寂寞夜晚免费观看视频 | 99视频全部看免费观 | 制服丝袜第一页 | 羞羞答答的免费视频在线观看 | 欧美一级久久久久久久久大 | 亚洲视频在线观看 | 国产普通话精品久久 | 精品一区二区三区在线成人 | 国产小伙和50岁熟女23p | 同桌别揉我奶了嗯啊 | AV久久久囯产果冻传媒 | 蓝男色gay | 亚洲精品成人无码区一在线观看 | 99热久久精品国产一区二区 | 国产人妻人伦精品无码.麻豆 | 97精品视频| 国产人妻人伦精品836700 | 久草在线在线精品观看 | 国产午夜精品鲁丝片 | 午夜射精日本三级 | 精品人妻无码一区二区三区蜜桃臀 | 国产精品爽爽久久久久久蜜桃 | 欧美一级情欲片在线 | 国内精品久久久久影院老司 | 欧美极限变态扩张video | 国模啪啪久久久久久久 | 色播播电影 | 24小时日本在线观看片免费 | 午夜视频在线网站 | 欧美高清69hd | 精品午夜中文字幕熟女人妻在线 | 亚洲色综合中文字幕在线 | 美女用手扒开粉嫩的屁股 | 国产午夜精品鲁丝片 | 国产亚洲精品久久久久久国模美 | 国产精品午夜福利在线观看 | 九色PORNY蝌蚪视频首页 | 日韩人妻双飞无码精品久久 |

電子發(fā)燒友

中國電子工程師最喜歡的網(wǎng)站

  • 2931785位工程師會員交流學(xué)習(xí)
  • 獲取您個性化的科技前沿技術(shù)信息
  • 參加活動獲取豐厚的禮品