并行fft频谱分析仪的设计.docx
- 文档编号:9819545
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:20
- 大小:171.15KB
并行fft频谱分析仪的设计.docx
《并行fft频谱分析仪的设计.docx》由会员分享,可在线阅读,更多相关《并行fft频谱分析仪的设计.docx(20页珍藏版)》请在冰点文库上搜索。
并行fft频谱分析仪的设计
并行fft频谱分析仪设计
小组成员:
孔峰3007204154
王云飞3007204163
张然3007204173
组号:
4c-2
07级电子信息工程2班
一、设计目标
本组旨在实现fft在51单片机上的并行运算。
虽然现在频谱分析仪一般基于快速傅里叶变换(即fft),大大减少了运算量,提高了运算速度,但仍显很慢。
N点fft需要进行N2/2次复数乘法和N2/2次复数加法运算,而每次复数运算又有特定的复数函数实现,运算量相当可观。
于是本组决定此系统由4个运算器并行进行运算,令有一个控制器控制如对扩展存储器存取等动作实现,旨在节省运算时间,提高效率。
二、完成情况简述
本组对于此命题并没有完全完成,软件设计,仿真等均基本完成,但结果并不尽如人意。
首先,由于89c52片内存储空间的限制,没有按照原定计划做1024点,即每个片子256点的fft。
由于为实现并行运算,不能对变量用“即取即用”,而需每次单片机对外部存储器读取时,读足所需256点8位原始数据,和128点复数w值,w值实部虚部各8位,这显然已经超出了片内256B变量定义空间限制,因此转而做256点,即每个片子64点。
其次,由于硬件情况限制和时间仓促,在硬件上,没有完成原定5个最小系统电路的焊接,只焊接了两个最小系统,即一个控制器,一个运算器用来模拟结果,单个运算器内64个点的运算结果尚且正常,然终究看不到最终4个运算器结合的效果。
最后,本组成功得通过电路和软件结合的手段,解决了四个运算器对于外部扩展存储器的轮流存取、fft核心算法、数据存取与运算同时进行、片内存储和扩展存储统一编址等关键问题,颇有获益。
三、系统总体描述和系统框图
运算器1
89c52
FFT频谱分析仪系统框图
控制器
89c52
Pc
输出电路
ADC
外存储器
6264
运算器4
89c52
运算器3
89c52
运算器2
89c52
系统框图如上所示,由五个51单片机最小系统组成,其中四个用于fft的具体运算,一个用于控制。
控制器两个专门输出端接于运算器1的两个中断管脚,运算器1的两个输出端接于运算器2的两个中断管脚,以此类推,最终运算器4的输出端接到控制器的某个输入端,作为反馈信号,当某一动作完成时通知控制器。
四、调试流程
系统运行流程大致如下图所示:
五、遇到的问题及解决方法
1.每一步蝶形所需数据不同,若每一层蝶形运算都重新取值的话则大大浪费时间。
解决:
若使用“先倒序后计算”方法,则前4步蝶形是单独一个片内64点本身的运算,后两步则才需要其他几个片子的运算结果。
所以为解决每一步存取浪费时间的问题,在前4步中,用各自的倒序代替存取,便可以大大节省时间,最后两步则将所有数据集合到扩展存储器中,重新分配给每个运算器。
这样也可以使控制器后期的程序设计更加连贯,控制器在完成了最后一步倒序后,直接组织输出
2.控制器对四个运算器控制的实现。
解决:
51单片机外部中断引脚有两个int0和int1,这样,每个运算器中只允许两个中断服务程序,而每个运算器又要完成“读、写、计算”几个动作。
在程序设计的过程中,我们将“读”和“计算”合并,即读数过后直接进算,只在读数结束后输出一个信号,通知下一个片子开始读数。
这样的话,后面的片子还在取值过程中的时候,前面的片子已经开始了计算,一定程度上节省了时间,同时解决了控制的问题。
3.W值的获得
解决:
由于c51编程中,允许变量定义的空间并不多。
在程序调试过程中:
autosegmenttoolarge的问题出现了多次。
经过我们粗略计算,发现对于256点fft,每个片中128点的w值是占空间的首要。
所以,我们将w值定义为常量,由扩展存储器中取出,放在每个片子的程序中去,而每个片子放程序的rom又足够大,这样,既节省了计算w值所需要的时间,又节省了空间。
4.几个片子对于一个扩展存储器的共享
实际上,这个问题我们在硬件实现上遇到的麻烦远比软件上麻烦很多,5个片子都要共享同一些地址/数据管脚,会遇到诸如“电流串扰“等等问题,这可能也成为了我们最终结果不尽如人意的原因之一。
在软件方面,考虑到硬件实现中的延迟等问题,同步问题不好解决,对存储器的存取操作采用时分的方式进行,虽然地址指针改变等问题实现起来较为繁琐,但具有很高的可操作性,可实现性。
六、原理图
总体图
单个最小系统图
控制器与扩展存储器
Adc
七、程序流程图和原代码
Fft核心算法流程
结束
写值
T=A(k)+A(k+B)WNp
A(k+B)=A(k)–A(k+B)WNp
A(k)=T
倒序
读入x(n)64点128点w值
开始
源代码:
Ic1:
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
uintRAMADDR=0x6000;
#defineRAM_6264XBYTE[RAMADDR]//6264地址范围H-7FFFH
sbitst=P3^0;
sbitce=P2^6;
sbitoe=P2^5;
sbitin=P3^1;
ucharn;
/**********************************************************
延时t毫秒
11.0592MHz时钟,延时约ms
**********************************************************/
voiddelayms(uintt)
{
uchark;
while(t--)
{
for(k=0;k<125;k++)
{;}
}
}
/**********************************************************
主函数
**********************************************************/
voidmain()
{
ucharval;
n=0;
EA=1;
EX0=1;
IT0=1;
val=0;
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
RAMADDR=0x6000;//6264首地址
oe=0;
ce=0;
st=1;
delayms(100);
st=0;
delayms(500);
val=P1;
RAM_6264=val;//数据写入
RAMADDR++;
for(n=0;n<256;n++)//写个数据入
{
st=1;
delayms(50);
st=0;
delayms(50);
val=P1;
RAM_6264=val;//数据写入
RAMADDR++;//修改地址
delayms
(1);
}
while
(1)
{
RAMADDR=0x6000;//6264首地址
for(n=0;n<256;n++)
{
temp=RAM_6264;//从中读取数据
RAMADDR++;//修改地址
temp=~temp;//输出为低电平动作
P1=temp;//送P0口显示
delayms(200);
}
}
delayms(10);
oe=1;
ce=1;
RAM_6264=0x01;
RAMADDR++;
RAM_6264=0x02;
delayms(10);
ce=0;
oe=0;
in=0;
while
(1);
}
voidic1in()interrupt0
{
oe=1;
ce=1;
n++;
RAMADDR++;
RAM_6264=n;
delayms(10);
ce=0;
oe=0;
in=1;
delayms(10);
in=0;
}
Ic2:
#include
#include
#include
#include
structcompx/*定義一個複數結構*/
{charreal;charimag;
};
structcompxidatadat[65];//FFT輸入輸出均從是s[1]開始存入
structcompxEE(structcompx,structcompx);//定義複數相乘結構
voidFFT(structcompxxin[],intN);/*定義FFT函數*/
structcompxEE(structcompxa1,structcompxb2)//兩複數相乘的程序
{structcompxb3;//b3保存兩複數間的結果
b3.real=a1.real*b2.real-a1.imag*b2.imag;//兩複數間的運算
b3.imag=a1.real*b2.imag+a1.imag*b2.real;
return(b3);/*返回結果*/
}
#defineucharunsignedchar
#defineuintunsignedint
uintRAMADDR=0x6000;
#defineRAM_6264XBYTE[RAMADDR]//6264地址范围H-7FFFH
sbitst=P3^0;
sbitce=P2^6;
sbitoe=P2^5;
sbitin=P3^1;
sbitrw=P3^5;
sbitfin=P1^0;
sbitenwrite=P1^7;
ucharvol=0;
ucharenread=0;
ucharcalfin=0;
/**********************************************************
延时t毫秒
11.0592MHz时钟,延时约ms
**********************************************************/
voiddelayms(uintt)
{
uchark;
while(t--)
{
for(k=0;k<125;k++)
{;}
}
}
voidwrite();
voidread();
voidcal();
/**********************************************************
FFT
**********************************************************/
voidfft(structcompxxin[],intN)/*FFT函數體*/
{intf,m,nv2,nm1,i,k,j=1,l;/*定義變量*/
structcompxv,w,t;/*定義結構變量*/
nv2=N/2;/*最高位值的權值*/
f=N;/*f為中間變量*/
for(m=1;(f=f/2)!
=1;m++){;}/*求級數m*/
nm1=N-1;/*nm1為數組長度*/
for(i=1;i<=nm1;i++)/*倒序*/
{if(i k=nv2;/*k為倒序中相應位置的權值*/ while(k j=j+k;/*j為數組中的位數,是一個十進制數*/ } {intle,lei,ip;//變量初始化,le為序列長度 floatpi; for(l=1;l<=m;l++)/*l控制級數*/ {le=pow(2,l);/*le等於的l次方*/ lei=le/2;/*蝶形兩節點間的距離*/ pi=3.14159265; v.real=1.0;//此次的v運於複數的初始化v.imag=0.0; w.real=cos(pi/lei);/*旋轉因子*/ w.imag=-sin(pi/lei); for(j=1;j<=lei;j++)//外循環控制蝶行運算的級數 {for(i=j;i<=N;i=i+le)//內循環控制每級間的運算次數 {ip=i+lei;/*蝶形運算的下一個節點*/ t=EE(xin[ip],v);/*第一個旋轉因子*/ xin[ip].real=xin[i].real-t.real;/*蝶形計算*/ xin[ip].imag=xin[i].imag-t.imag; xin[i].real=xin[i].real+t.real; xin[i].imag=xin[i].imag+t.imag; } v=EE(v,w);//調用EE複數相乘程序,結果給下次的循環 } } } } /********************************************************** 写 **********************************************************/ voidwrite() { uchari; oe=1; ce=1; rw=1; RAMADDR=0x6000; for(i=0;i<64;i++) { RAM_6264=(uchar)sqrt(dat[i+1].real*dat[i+1].real+dat[i+1].imag*dat[i+1].imag); RAMADDR++; } oe=0; ce=0; fin=0; } /********************************************************** 算 **********************************************************/ voidcal() { fft(dat,64); calfin=1; } /********************************************************** 读 **********************************************************/ voidread() { uchari; enread=0; oe=1; ce=1; rw=0; for(i=0;i<64;i++) { dat[i+1].real=RAM_6264; RAMADDR++; } rw=1; oe=0; ce=0; in=1; delayms(10); in=0; cal(); } /********************************************************** 主函数 **********************************************************/ voidmain() { RAMADDR=0x6000; P0=0xff; P1=0xff; P2=0xff; P3=0xff; ce=0; oe=0; EA=1; EX0=1; IT0=1; //6264首地址 while(enread==0); read(); while(calfin==0); while(enwrite==1); write(); while (1); } voidicin()interrupt0 { enread=1; } 注: 上程序中乃是其中一个运算器的程序,其中包含w值计算,实际最终并没有用这一个。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 并行 fft 频谱 分析 设计