FFT离散傅氏变换的快速算法
- 格式:docx
- 大小:11.61 KB
- 文档页数:6
第五章离散傅里叶变换及其快速算法1离散傅里叶变换(DFT)的推导(1)时域抽样:目的:解决信号的离散化问题。
效果:连续信号离散化使得信号的频谱被周期延拓。
⑵时域截断: 原因:工程上无法处理时间无限信号。
方法:通过窗函数(一般用矩形窗)对信号进行逐段截取。
结果:时域 乘以矩形脉冲信号,频域相当于和抽样函数卷积。
(3) 时域周期延拓:目的:要使频率离散,就要使时域变成周期信号。
方法:周期延拓中的搬移通过与 、:(t_nTs)的卷积来实现。
表示:延拓后的波形在数学上可表示为原始波形与冲激串序列的卷积。
结果:周期延拓后的周期函数具有离散谱。
经抽样、截断和延拓后,信号时域和频域都是离散、周期的。
过程见图▲t載曲后ft \ \ t \ f.............. ►t---------------- r fi0/1LL紹后-7ii t7V亍延拓・V 普义PFT「州-P TTnh图1 DFT 推导过程示意图〜00 ”N 4处理后信号的连续时间傅里叶变换:|~⑴虫ls h(nT 2o n=0「忆飞n/N-kfo)(i)l~(f)是离散函数,仅在离散频率点f 二kf 。
k —处存在冲激,强度为a k ,其To NTs余各点为0。
〜 N N 1(ii) H(f)是周期函数,周期为Nfo == I ,每个周期内有N 个不同的幅值。
To NTs Ts(iii)时域的离散时间间隔(或周期)与频域的周期(或离散间隔)互为倒数。
2 DFT 及IDFT 的定义(1) DFT 定义:设hnTs 是连续函数h(t)的N 个抽样值J ,这N 个点的宽度为N 的 DFT 为:DFT N h(nTs)]=A h(nTs)ej 2ffi /N =H ——J (k =0,1,..., N_1)7l NT s 丿IDFT 定义:设H 上是连续频率函数吧的N 个抽样值k 亠,…• N J ,这N 个点(NTs 丿 的宽度为N的IDFT 为:DFTN 1Hk_L7HLe 「2「伙/N 厶 门Ts,(k=0,1,…,N —1)|L NsN k 卫 NTs“Rk/N 称为N 点DFT 的变换核函数,龊讪称为N 点IDFT 的变换核函数。
FFT是离散傅立叶变换的快速算法离散傅立叶变换(Discrete Fourier Transform, DFT)是一种将离散信号变换到频域的方法,它在数字信号处理中有着广泛的应用。
然而,传统的DFT算法的计算复杂度为O(N^2),对于大规模的信号序列而言,计算时间会很长。
为了解决这个问题,FFt算法应运而生。
快速傅立叶变换(Fast Fourier Transform, FFT)是一种通过分治思想将DFT算法转化成更高效的计算方式。
FFT算法的核心思想是将一个长度为N的信号分解成N个长度为1的信号,然后逐步合并计算每个信号的频域表示,最终得到整个信号的频域表示。
FFT算法的时间复杂度为O(NlogN),大大提高了计算效率。
FFT算法的基本思想是基于蝶形运算和旋转因子的运用。
蝶形运算是指将两个频域采样值进行乘法和加法操作,然后得到两个新的频域采样值。
旋转因子是指用来调整频域采样的运算公式,可以通过旋转因子将频域采样值分解成两个较小规模的频域采样值。
通过不断地重复蝶形运算和旋转因子的运算,最终可以得到整个信号的频域表示。
在FFT算法中,需要注意的是将信号序列长度N转化为2的幂次方,这是因为FFT算法要求信号序列的长度必须是2的幂次方。
如果信号序列的长度不是2的幂次方,需要进行长度的补齐或者截断操作。
通过对信号序列进行补齐或者截断,可以避免频谱泄漏的问题,并且可以确保FFT算法的正确性。
FFT算法的具体实现通常采用递归或者迭代的方式。
递归实现的FFT算法主要是通过将整个信号序列分解成较小规模的子序列,然后对每个子序列进行FFT计算,最终得到整个信号的频域表示。
迭代实现的FFT算法则是通过依次计算每个蝶形运算的结果,从而得到整个信号的频域表示。
FFT算法在数字信号处理领域有着广泛的应用。
例如,它可以用于信号的滤波和去噪、信号的频谱分析和频率成分提取、图像处理中的边缘检测和特征提取等。
由于FFT算法具有高效的计算速度,尤其适合处理大规模信号序列,因此在实际应用中被广泛采用。
DFT 算法原理快速傅氏变换(FFT )是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。
设x(n)为N 项的复数序列,由DFT 变换,任一X (m )的计算都需要N 次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次实数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N 项复数序列的X (m ),即N 点DFT 变换大约就需要N2次运算。
当N=1024点甚至更多的时候,需要N2=1048576次运算,在FFT 中,利用WN 的周期性和对称性,把一个N 项序列(设N=2k,k 为正整数),分为两个N/2项的子序列,每个N/2点DFT 变换需要(N/2)2次运算,再用N 次运算把两个N/2点的DFT 变换组合成一个N 点的DFT 变换。
这样变换以后,总的运算次数就变成N+2(N/2)2=N+N2/2。
继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。
而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT 运算单元,那么N 点的DFT 变换就只需要Nlog2N 次的运算,N 在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT 的优越性。
、FFT的算法原理FFT 算法的输出X(K)为自然顺序,但为了适应原位计算,其输入序列不是按x(n)的自然顺序排序,这种经过M-1次奇偶抽选后的排序为序列的倒序。
因此,在运算之前应先对序列x(n)进行倒序。
倒序的规律就是把顺序数的二进制位倒置,即可得到倒序值。
倒序数是在M 位二进制数最高位加一,逢2向右进位。
FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。
有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。
这就是很多信号分析采用FFT变换的原因。
另外,FFT可以将一个信号的频谱提取出来,这在频谱分析方面也是经常用的。
虽然很多人都知道FFT是什么,可以用来做什么,怎么去做,但是却不知道FFT之后的结果是什意思、如何决定要使用多少点来做FFT。
现在圈圈就根据实际经验来说说FFT结果的具体物理意义。
一个模拟信号,经过ADC采样之后,就变成了数字信号。
采样定理告诉我们,采样频率要大于信号频率的两倍,这些我就不在此罗嗦了。
采样得到的数字信号,就可以做FFT变换了。
N个采样点,经过FFT之后,就可以得到N个点的FFT结果。
为了方便进行FFT 运算,通常N取2的整数次方。
假设采样频率为Fs,信号频率F,采样点数为N。
那么FFT之后结果就是一个为N点的复数。
每一个点就对应着一个频率点。
这个点的模值,就是该频率值下的幅度特性。
具体跟原始信号的幅度有什么关系呢?假设原始信号的峰值为A,那么FFT的结果的每个点(除了第一个点直流分量之外)的模值就是A的N/2倍。
而第一个点就是直流分量,它的模值就是直流分量的N倍。
而每个点的相位呢,就是在该频率下的信号的相位。
第一个点表示直流分量(即0Hz),而最后一个点N的再下一个点(实际上这个点是不存在的,这里是假设的第N+1个点,也可以看做是将第一个点分做两半分,另一半移到最后)则表示采样频率Fs,这中间被N-1个点平均分成N等份,每个点的频率依次增加。
例如某点n所表示的频率为:Fn=(n-1)*Fs/N。
由上面的公式可以看出,Fn所能分辨到频率为为Fs/N,如果采样频率Fs为1024Hz,采样点数为1024点,则可以分辨到1Hz。
1024Hz的采样率采样1024点,刚好是1秒,也就是说,采样1秒时间的信号并做FFT,则结果可以分析到1Hz,如果采样2秒时间的信号并做FFT,则结果可以分析到0.5Hz。
FFT是离散傅立叶变换的快速算法FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。
有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。
这就是很多信号分析采用FFT变换的原因。
另外,FFT可以将一个信号的频谱提取出来,这在频谱分析方面也是经常用的。
虽然很多人都知道FFT是什么,可以用来做什么,怎么去做,但是却不知道FFT之后的结果是什意思、如何决定要使用多少点来做FFT。
现在圈圈就根据实际经验来说说FFT结果的具体物理意义。
一个模拟信号,经过ADC采样之后,就变成了数字信号。
采样定理告诉我们,采样频率要大于信号频率的两倍,这些我就不在此罗嗦了。
采样得到的数字信号,就可以做FFT变换了。
N个采样点,经过FFT之后,就可以得到N个点的FFT结果。
为了方便进行FFT 运算,通常N取2的整数次方。
假设采样频率为Fs,信号频率F,采样点数为N。
那么FFT 之后结果就是一个为N点的复数。
每一个点就对应着一个频率点。
这个点的模值,就是该频率值下的幅度特性。
具体跟原始信号的幅度有什么关系呢?假设原始信号的峰值为A,那么FFT 的结果的每个点(除了第一个点直流分量之外)的模值就是A 的N/2倍。
而第一个点就是直流分量,它的模值就是直流分量的N倍。
而每个点的相位呢,就是在该频率下的信号的相位。
第一个点表示直流分量(即0Hz),而最后一个点N的再下一个点(实际上这个点是不存在的,这里是假设的第N+1个点,也可以看做是将第一个点分做两半分,另一半移到最后)则表示采样频率Fs,这中间被N-1个点平均分成N等份,每个点的频率依次增加。
例如某点n所表示的频率为:Fn=(n-1)*Fs/N。
由上面的公式可以看出,Fn所能分辨到频率为为Fs/N。
如果采样频率Fs为1024Hz,采样点数为1024点,则可以分辨到1Hz。
1024Hz的采样率采样1024点,刚好是1秒,也就是说,采样1秒时间的信号并做FFT,则结果可以分析到1Hz,如果采样2秒时间的信号并做FFT,则结果可以分析到0.5Hz。
快速傅立叶变换(FFT)算法实验实验目得:1、加深对DFT 算法原理与基本性质得理解;2、熟悉FFT 得算法原理与FFT子程序得算法流程与应用;3、学习用FFT 对连续信号与时域信号进行频谱分析得方法。
程序流程图:傅立叶变换就就是一种将信号从时域到频域得变换形式,就就是声学、语音、电信与信号处理等领域中得一种重要分析工具。
离散傅立叶变换(DFT)就就是连续傅立叶变换在离散系统中得表现形式,由于DFT 得计算量很大,因此在很长时间内其应用受到很大得限制。
快速傅立叶变换(FFT)就就是离散傅立叶变换得一种高效运算方法。
由于我们在计算DFT 时一次复数乘法需用四次实数乘法与二次实数加法;一次复数加法则需二次实数加法。
运算一个X(k)需要4N 次复数乘法及2N+2(N-1)=2(2N-1)次实数加法。
所以整个DFT运算总共需要4N^2 次实数乘法与N*2(2N-1)=2N(2N-1)次实数加法。
如此一来,计算时乘法次数与加法次数都就就是与N^2成正比得,当N 很大时,运算量就就是可观得,因而需要改进对DFT 得算法减少运算速度。
我们可以将DFT 运算中有些项合并。
我们先设序列长度为N=2^L,L为整数。
将N=2^L 得序列x(n)(n=0,1,……,N-1),按N得奇偶分成两组,也就就就是说我们将一个N 点得DFT 分解成两个N/2点得DFT,她们又重新组合成一个如下式所表达得N 点DFT:一般来说,输入被假定为连续得。
当输入为纯粹得实数得时候,我们就可以利用左右对称得特性更好得计算DFT。
这样得RFFT优化算法就就是包装算法:首先2N 点实数得连续输入称为“进包”。
其次N 点得FFT被连续运行。
最后作为结果产生得N 点得合成输出就就是“打开”成为最初得与DFT 相符合得2N 点输入。
使用这一思想,我们可以划分FFT得大小,它有一半花费在包装输入O(N)得操作与打开输出上。
AD原理图源程序#include<math、h>#include"DSP2833x_Device、h"// DSP2833x Header "DSP2833x_Examples、h"// DSP2833x Examples Include Fi#include"m、h"#include"i_cmplx、h"#include"ext_inf、h"/*********************************************************************************/#if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT#defineADC_MODCLK 0x3// HSPCLK =SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25、0 MHz#endif#if (CPU_FRQ_100MHZ)#define ADC_MODCLK 0x2//HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25、0 MHz#endif#define ADC_CKPS 0x1// ADC moduleclock =HSPCLK/2*ADC_CKPS = 25、0MHz/(1*2) = 12、5MHz#defineADC_SHCLK0xf //S/H widthin ADCmodule periods = 16 ADC clocks#defineAVG 1000 // Average sample limit#define ZOFFSET 0x00 // Average Zero offset#define BUF_SIZE160// Sample buffer size/*********************************************************************************//////////////////unsignedintSampleLong;#define SAMPLELONG 3////////////////////unsigned int Ad_data[1536]={0};unsignedint Ad_data1[1536]={0};unsigned int convcount = 0;volatile unsigned intadconvover =0;////////////////int m=0;double n;double p,q;PLEX DDataBuffer[512]={0};Uint32 mod[512];//////////////////////unsignedint i;/*********************************************************************************/// Prototype statements for functionsfound within this file、interruptvoidadc_isr(void);/*********************************************************************************/void main(void){ﻩ#if SAMPLELONG==1ﻩSampleLong =256;#endif#if SAMPLELONG==2ﻩSampleLong=512;ﻩ#endif#ifSAMPLELONG==3ﻩSampleLong=1024;ﻩ#endif// Step 1、Initialize System Control:// PLL,WatchDog, enable Peripheral Clocks//This example function isfound in the DSP2833x_SysCtrl、c file、InitSysCtrl();// Step 2、 Initialize GPIO:// Thisexample function is found in the DSP2833x_Gpio、c// illustrates how to setthe GPIOto it's default state、InitGpio(); //Skipped for this example// Step3、Clearall interrupts and initialize PIE vector table://Disable CPUinterruptsDINT;//Initialize the PIEcontrol registers totheir defaultstate、// The defaultstate is all PIE interrupts disabled and flag s// are cleared、// This function isfoundin the DSP2833x_PieCtrl、c file、InitPieCtrl();// Disable CPU interrupts and clear all CPUinterrupt flags: IER = 0x0000;IFR = 0x0000;// Initialize the PIE vector table with pointers to the shell Int errupt// Service Routines (ISR)、// Thiswill populatethe entire table, even if theinterrupt// is not usedin this example、 This is useful for debug purpose s、//The shell ISR routines are found in DSP2833x_DefaultIsr、c、// Thisfunctionis found inDSP2833x_PieVect、c、InitPieVectTable();//Interrupts thatare used inthisexample are re-mapped to// ISRfunctions found within this file、EALLOW; //This is neededto write to EALLOW protected regi sterPieVectTable、ADCINT= &adc_isr;EDIS; // This is needed to disable write to EALLOW prote cted registers// Step 4、 Initialize all theDevice Peripherals:// This function is found in DSP2833x_InitPeripherals、c// InitPeripherals();// Notrequired for this exampleInitAdc();// For this example, init the ADC// Step5、User specific code,enable interrupts://Enable ADCINTin PIEPieCtrlRegs、PIEIER1、bit、INTx6 = 1;IER|= M_INT1; //Enable CPU Interrupt1EINT;// Enable Global interrupt INTMERTM;// EnableGlobal realtime interrupt DBGMAdcRegs、ADCTRL1、bit、ACQ_PS =ADC_SHCLK;AdcRegs、ADCTRL3、bit、ADCCLKPS = ADC_CKPS;AdcRegs、ADCTRL1、bit、SEQ_CASC =1; // 0 Non-Cas caded Mode; 1 Cascaded ModeAdcRegs、ADCTRL2、bit、INT_ENA_SEQ1 = 0x1;AdcRegs、ADCTRL2、bit、RST_SEQ1= 0x1;AdcRegs、ADCCHSELSEQ1、bit、CONV00 = 0x6;AdcRegs、ADCMAXCONV、bit、MAX_CONV1 = 15;AdcRegs、ADCTRL2、bit、SOC_SEQ1 =0x1;for(;;){ﻩif(adconvover==1){ﻩﻩﻩfor(i=0;i<(SampleLong/2);i++)ﻩﻩﻩ{ﻩﻩDDataBuffer[i]、real=Ad_data[2*i];//short intﻩﻩDDataBuffer[i]、imag=Ad_data[2*i+1];//short intﻩﻩ}ﻩﻩswitch(SampleLong)ﻩﻩﻩ{ﻩﻩcase256:/*256point*/ﻩfft256(DDataBuffer,256);m=0;ﻩfor(i=0;i<128;i++)ﻩﻩ{ﻩﻩp=DDataBuffer[i]、real;ﻩq=DDataBuffer[i]、imag;ﻩﻩﻩﻩn=(long)p*(long)p+(long)q*(long)q;mod[m]=sqrt(n);ﻩm++;ﻩﻩ}ﻩﻩbreak;case 512: /*512 point*/ﻩ fft512(DDataBuffer,512);m=0;ﻩfor(i=0;i<256;i++)ﻩﻩﻩﻩ{ﻩp=DDataBuffer[i]、real;ﻩq=DDataBuffer[i]、imag;ﻩﻩﻩﻩn=(long)p*(long)p+(long)q*(long)q;ﻩﻩmod[m]=sqrt(n);ﻩﻩm++;ﻩﻩﻩﻩ}ﻩﻩbreak;ﻩﻩcase 1024:/*1024point*/ﻩﻩfft1024(DDataBuffer,1024);ﻩm=0;for(i=0;i<512;i++)ﻩ{p=DDataBuffer[i]、real;ﻩﻩq=DDataBuffer[i]、imag;n=(long)p*(long)p+(long)q*(long)q;ﻩﻩﻩmod[m]=sqrt(n);ﻩﻩm++;}ﻩbreak;}ﻩadconvover=0;ﻩ convcount=0;ﻩﻩﻩﻩ}ﻩ}}interrupt void adc_isr(void){//If40 conversions have been logged, start overif(convcount == SampleLong){adconvover = 1;}else{Ad_data[convcount]= AdcRegs、ADCRESULT0 >>4;convcount++;}// Reinitialize fornext ADC sequenceAdcRegs、ADCTRL2、bit、RST_SEQ1 = 1; //Reset SEQ1AdcRegs、ADCST、bit、INT_SEQ1_CLR =1;//Clear INT SEQ1 bitPieCtrlRegs、PIEACK、all = PIEACK_GROUP1;// Acknowledge in terruptto PIEAdcRegs、ADCTRL2、bit、SOC_SEQ1 = 0x1;return;}。
快速傅里叶变换(FFT)是一种计算离散傅里叶变换(DFT)及其逆变换的高效算法。
FFT的计算公式如下:
X[k] = ∑(n=0 to N-1) x[n] * W[k*n]
其中,X[k]表示离散傅里叶变换的输出,x[n]表示输入的时域信号,N表示输入信号的采样点数,W[k*n]表示复数单位元,即W[k*n] = e^(-2πikn/N)。
对于逆变换,可以使用以下公式:
x[n] = ∑(k=0 to N-1) X[k] * W[-k*n] / N
其中,x[n]表示输入的时域信号,X[k]表示离散傅里叶变换的输出,N表示输入信号的采样点数,W[-k*n]表示复数单位元的逆变换。
这些公式可以根据实际需求进行适当的修改和扩展,例如对于实数信号可以省略虚部,对于对称性可以优化计算等。