FFT在单片机上的实现 下载本文

河南科技大学毕业设计(论文)

P1ASF = 0x06;

//P1.1 P1.2口作为AD输入,P1.1作为今后可能开发双通道分析的保留。 AUXR1&= 0xfb;

//ADRJ=0,10位ADC的高8位放在ADC_RES中,后续将不再用低2位。 EADC=1;

//开AD中断 //启动ADC转换

//T0x12=1,定时器0以12倍速运行 //定时器0工作在方式1

ADC_CONTR=0x8a; NOP5; AUXR = 0x80; TMOD = 0x01; TL0 = T1MS; TH0 = T1MS>>8; TR0 = 1; ET0 = 1; EA = 1;

//定时器0赋初值 //开定时器0中断 //定时器0启动 //开总中断

§4.2.2 AD采样子程序

AD采样的数据将反映信号的频率,因此AD采样的间隔必须保证。有两种方案来保证时间间隔:使用高中断优先级的定时器或直接连续采样,靠ADC自己的采样延时来控制时间间隔。定时器控制看似更加准确,但ADC的采样延时仍存在,实际每两采样点的时间间隔=定时器延时时间?两次ADC采样延时时间之差。若ADC采样延时时间有误差,以这种方式定时的误差仍存在,且程序结构复杂,编写困难。

实际上,STC12C5A60S2单片机对模数转换速度已经有了很好的控制。本程序拟使用单片机数模转换的转换时间来控制采样速率,而不再使用另外的定时器。程序流程图如图:

13

河南科技大学毕业设计(论文)

图4-2 AD采样子程序流程图

STC12C5A60S2单片机对模数转换速度由AUXR1中的SPEED1、SPEED0两位控制。速度定义如表:

表4-1 STC12C5A60S2数模转换速度控制位

SPEED1 1 SPEED0 1 A/D转换所需时间 90个时钟周期转换一次,CPU工作频率21MHz时,A/D转换速度约250KHz 1 0 0

0 1 0 180个时钟周期转换一次 360个时钟周期转换一次 540个时钟周期转换一次 当SPEED1=0,SPEED0=0,fsoc=32MHz时,采样时间间隔td有:

14

河南科技大学毕业设计(论文)

td?540?16.9(us) fsoc采样的信号的最高频率分量fh有:

fh?1?29KHz 2?tdfh高于音频最高频率22KHz。由于人可感知的音频中多不超过12KHz,若隔点采样,则fh变为:

fh?1?15KHz 2?2td定采样点数为32个点,则通过FFT变换可将原信号变为16个频率分量相加(采样点数的确定和FFT结果的解释见下节)。最小频率分量为940Hz。

采样过程并未关断定时器0中断,因此采样过程会被打断。但定时器0的溢出间隔较长(5ms),期间可进行很多次完整的32点采样。只有当32个点是连续采样并被移出时,主循环中的数据处理函数才开始运行。 §4.2.3 蝶形运算的FFT算法

FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。

设x(n)为N项的复数序列,由DFT变换,任一X(m)的计算都需要N次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次复数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N项复数序列的X(m),即N点DFT变换大约就需要N^2次运算。当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+N^2/2。继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT运算

15

河南科技大学毕业设计(论文)

单元,那么N点的DFT变换就只需要Nlog2N次的运算,N在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT的优越性。

2点DFT运算称为蝶形运算,而整个FFT就是由若干级迭代的蝶形运算组成,而且这种算法采用原位运算,故只需N个存储单元

×1X1(k)×1×1k×WNkX(k)?X1(k)?WNX2(k)X2(k)×(-1)X(Nk?k)?X1(k)?WNX2(k)2

图4-3 蝶形运算单元

图4-3是FFT频域抽取算法的基本运算单元,一般称为蝶形运算.下一步再将X(4m+i),i=0,1,2,3分解成4个N42序列,迭代r次后完成计算,整个算法的复杂度减少为O(Nlog4N)

上诉结论可以推广到N点的一般情况,规律是第一列只有一种类型的蝶形运算,系数是 ,以后每列的蝶形类型,比前一列增加一倍,到第是N/2个蝶形类型,系数是,共N/2个。由后向前每推进一列,则用上述系数中偶数序号的那一半,例如第列的系数则为参加蝶形运算的两个数据点的间距,则是最末一级最大,其值为N/2,向前每推进一列,间距减少一半。

对N = 2L点FFT,共需L级蝶形运算,每级有N/2个蝶形运算组成,蝶形运算两节点的距离:2L-1(L表示级数)每个蝶形运算有一次复乘和2次复加。如

第L级的系数因子为(L?1,2,3...M)W2JL,J?0,1,2.......2L?1?1即第L级的蝶形运算系数因子类型数为2L?1个,如N=8,共有M?3级JJ2第一级20个为:W2J1?WM1?M?WM222M-LM?1L?1,J?00?WN0?W?N;L?2,J?0第二级21个为:WNJ2=?2??WN;L?2,J?10?WN;L?3,J?0?1M-L?WN;L?3,J?1第三级22个为:WNJ2=?2?WN;L?3,J?2?W3;L?3,J?3?N16