数据采集处理和控制系统设计.docx
《数据采集处理和控制系统设计.docx》由会员分享,可在线阅读,更多相关《数据采集处理和控制系统设计.docx(20页珍藏版)》请在冰豆网上搜索。
数据采集处理和控制系统设计
DSP大作业
题目:
数据采集处理和控制系统设计
院系名称:
电气工程学院专业班级:
学生姓名:
学号:
目录
1引言2
2.系统分析3
2.1主要任务3
2.2设计要求3
2.3系统总体结构方框图4
3.硬件设计5
3.1DSP模块设计5
3.2电源模块设计6
3.3时钟模块设计6
3.4存储器模块设计7
3.5TMS320VC5416最小系统PCB版图8
4软件设计9
5程序运行效果10
5.1采集的数据及其FFT计算结果10
5.2叠加波形与滤波后波形比较10
5.3滤波前后信号的频谱图比较11
6课程设计总结11
7参考文献12
附录1程序13
1引言
21世纪是数字化的时代,随着信息处理技术的飞速发展,DSP(数字信号处理器)技术逐渐发展成为一门主流技术,它在电子信息、通信、软件无线电、自动控制、仪表技术、信息家电等高科技领域得到了越来越广泛的应用。
相对于模拟滤波器,数字滤波器没有漂移,能够处理低频信号,频率响应特性可做成非常接近于理想的特性,且精度可以达到很高,容易集成等,这些优势决定了数字滤波器的应用越来越广泛,工程上常用它来做信号处理、数据传送和抑制干扰等。
。
同时DSP的出现和迅速发展也促进了数字滤波器的发展,并为数字滤波器的硬件实现提供了更多的选择。
本课题主要应用应用DSP集成开发环境—CCS调试C程序,用TMS320VC5416来实现信号采集处理与控制系统的设计。
2.系统分析
2.1主要任务
本系统设计的主要任务包括DSP硬件系统设计和软件系统设计。
其中硬件设计要求设计一个精简的能独立运行的DSP系统,包括绘制系统的原理图和PCB版图;软件设计要求编写基于所设计的硬件系统的CCS程序使其能够完成数据采集处理和控制等功能。
2.2设计要求
利用实验箱的模拟信号产生单元产生不同频率的信号,或者产生两个频率的信号的叠加。
在DSP中采集信号,并且对信号进行频谱分析,滤波等。
通过键盘选择算法的功能,将计算的信号频率或者滤波后信号的频率在LCD上显示。
主要功能如下:
一、对外部输入的模拟信号采集到DSP内存,会用CCS软件显示采集的数据波形。
二、对采集的数据进行如下算法分析:
(1)频谱分析:
使用fft算法计算信号的频率。
(2)对信号进行IIR滤波或FIR滤波,并且计算滤波前后信号的频率。
三、外部键盘选择算法功能,并且将结果在LCD上显示。
2.3系统总体结构方框图
3.硬件设计
3.1DSP模块设计
3.2电源模块设计
3.3时钟模块设计
3.4存储器模块设计
3.5TMS320VC5416最小系统PCB版图
板上包括了支持TMS320VC5416独立运行的时钟电路、复位电路、Flash模块、JTAG仿真接口电路以及电源模块等。
所有的器件都放在了正面,电源、复位按键和JTAG接口放在了板子边缘方便连接和调试。
4软件设计
5程序运行效果
5.1采集的数据及其FFT计算结果
可见所采集的信号中仅含有多种频率分量,直流、低频和高频。
5.2叠加波形与滤波后波形比较
可见滤波后信号中的高频分量得到了较大的衰减,滤波后波形变得平滑。
5.3滤波前后信号的频谱图比较
由滤波前后高低频分量的相对大小再次证明低通滤波器对高频分量的衰减作用较强。
6课程设计总结
DSP作为嵌入式处理器家族的一大类,其结构特点决定了它尤其适合做数字信号处理的应用,而学好数字信号处理对日后的信息处理的深入学习和应用有着重要意义,因而学好DSP技术也就有着深远的意义。
通过此次课程设计我学习了一个实际的电子系统的完整的设计流程,掌握了PCB设计软件AltiumDesigner的使用方法,并熟悉了CCS工程的建立和基于TMS320VC5416的DSP程序的编写。
在此次课程设计中我也遇到了很多问题,首先是绘制PCB版图时的布局和布线问题,这是一个需要经验和技巧的问题,尤其是Flash器件与DSP的连线较多而DSP的所有数据线和地址线分布又较为分散,所以也就多画了几遍,争取精益求精还是能够画好的。
还有创建CCS工程后cmd文件和中断向量表的详细配置,这两个文件的修改需要清楚DSP的结构以及存储器映射情况,通过阅读几本参考书和其他一些资料,自己已经基本明白了他们的作用和配置方法。
还有就是程序的调试,DSP的结构比单片机要复杂的多,相应的寄存器也就较多,而很多情况下编写DSP程序都需要操作和配置寄存器,这既要求对冯诺依曼体系结构的处理器的共性有一定了解,同时也要针对DSP的特点来进行,编程前需对各个硬件模块之间的内在联系进行整体考虑,这样可以训练自己的系统思维。
当然这些问题都有一定的难度,但是想办法解决它们的过程也就是学习和进步的过程。
通过此次课程设计我对TMS320C54x系列DSP的硬件结构有了较为深刻的认识,值得一提的是54x的DSP没有大量的GPIO可使用,这显然是不能满足实际应用的需求的,试验箱上采用的是使用CPLD作为DSP与其他器件之间的桥梁,通过IO端口的访问来进行输入和输出操作,同时使用AD7822时也是通过CPLD来为它提供必要的时序,这样就大大简化了DSP对外围器件的控制任务,使其能够专注于运行各种算法,该设计方案为自己设计DSP系统提供了有益的参考。
此次课程设计持续时间虽然不长,但是自己在设计过程中却学到了不少的知识和技能,包括从查阅和参考的各种资料中也学到了DSP的硬件和软件设计技巧,以及CCS的使用和常见问题的排除和程序的调试组装等等。
7参考文献
【1】清源科技.TMS320C54xDSP硬件开发教程[M].机械工业出版社,2003
【2】TMS320VC5416DataManualTexasInstruments,2005
【3】江思敏,刘畅.TMS320C54xDSP的应用程序设计教程[M].机械工业出版社
【4】TMS320C54x系列DSP的CPU与外设.清华大学出版社
附录1程序
FFT算法程序:
voidkfft(doublepr[Length],doublepi[Length],intn,intk,doublefr[Length],doublefi[Length],intl,intil)
{
intit,m,is,i,j,nv,l0;
doublep,q,s,vr,vi,poddr,poddi;
for(it=0;it<=n-1;it++)
{
m=it;is=0;
for(i=0;i<=k-1;i++)
{j=m/2;is=2*is+(m-2*j);m=j;}
fr[it]=pr[is];fi[it]=pi[is];
}
pr[0]=1.0;pi[0]=0.0;
p=6.283185306/(1.0*n);
pr[1]=cos(p);pi[1]=-sin(p);
if(l!
=0)pi[1]=-pi[1];
for(i=2;i<=n-1;i++)
{
p=pr[i-1]*pr[1];q=pi[i-1]*pi[1];
s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
pr[i]=p-q;pi[i]=s-p-q;
}
for(it=0;it<=n-2;it=it+2)
{
vr=fr[it];vi=fi[it];
fr[it]=vr+fr[it+1];fi[it]=vi+fi[it+1];
fr[it+1]=vr-fr[it+1];fi[it+1]=vi-fi[it+1];
}
m=n/2;nv=2;
for(l0=k-2;l0>=0;l0--)
{
m=m/2;nv=2*nv;
for(it=0;it<=(m-1)*nv;it=it+nv)
for(j=0;j<=(nv/2)-1;j++)
{
p=pr[m*j]*fr[it+j+nv/2];
q=pi[m*j]*fi[it+j+nv/2];
s=pr[m*j]+pi[m*j];
s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);
poddr=p-q;poddi=s-p-q;
fr[it+j+nv/2]=fr[it+j]-poddr;
fi[it+j+nv/2]=fi[it+j]-poddi;
fr[it+j]=fr[it+j]+poddr;
fi[it+j]=fi[it+j]+poddi;
}
}
if(l!
=0)
for(i=0;i<=n-1;i++)
{
fr[i]=fr[i]/(1.0*n);
fi[i]=fi[i]/(1.0*n);
}
if(il!
=0)
for(i=0;i<=n-1;i++)
{
pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);
if(fabs(fr[i])<0.000001*fabs(fi[i]))
{
if((fi[i]*fr[i])>0)pi[i]=90.0;
elsepi[i]=-90.0;
}
else
pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;
}
}
卷积程序:
voidconvolve(double*Input,double*Impulse,double*Output,uintlength1,uintlength2)
{
intp,j,k;
for(k=0;k{
for(p=0;pmid[length1-p-1]=mid[length1-p-2];//移位操作
mid[0]=Input[k];
for(j=0;jOutput[k]+=mid[j]*Impulse[j];
}
}
FIR滤波器设计函数:
voidfirdes(doublenpass)//npass归一化的截止频率参数
{
intt;
for(t=0;t{h[t]=sin((t-(FLen-1)/2.0)*2*npass*3.1415926)/(3.1415926*(t-(FLen-1)/2.0));
}
if(t==((FLen-1)/2))h[t]=npass;
}
求最大值和次大值函数:
intm1=0;
intm2=0;
intfmax,smax;
voidfindmax(double*p)//使用全局变量保存频谱最大点与次大点对应的K值
{
inti;
doublemax=p[5];//因存在直流分量,避开几个点防止干扰
for(i=5;i<128;i++)
{
if(p[i+1]>max)
{
max=p[i+1];
m1=i+1;
}
}
p[m1]=0;//清零最大值以便求次大值
max=p[5];
for(i=5;i<128;i++)
{
if(p[i+1]>max)
{
max=p[i+1];
m2=i+1;
}
}
if(m1>m2){fmax=m1;smax=m2;}
else{fmax=m2;smax=m1;}
}
外部中断2服务函数:
interruptvoidExtInt2()//中断2中断子程序,负责数据采集和处理
{
*(unsignedint*)IFR=0xFFFF;//清除中断标志
data_buff[i]=port8002&0x00ff;//读取AD采样值
i++;
if(i==256&&flag==1)//flag控制当显示数据刷新后再处理
{
i=0;//在此设断点,观察采集进来的信号
for(k=0;k{
real[k]=data_buff[k];//解决格式不兼容问题
img[k]=0.0;
FMag[k]=0.0;
}
kfft(real,img,256,8,Freal,Fimg,0,1);//求输入信号的频谱
for(k=0;k{
FMag[k]=sqrt((Freal[k]*Freal[k]+Fimg[k]*Fimg[k]));
}
findmax(FMag);
freq1=(250.0*smax)/256;//信号频率=DFT分辨率*K
freq2=(250.0*fmax)/256;
convolve(data,h,y,51,256);//卷积滤波
for(k=0;k{
yout[k]=y[k];//解决格式不兼容问题
img[k]=0.0;//必须重新初始化
yFMag[k]=0.0;
}
kfft(yout,img,256,8,yFreal,yFimg,0,1);
for(k=0;k{
yFMag[k]=sqrt((yFreal[k]*yFreal[k]+yFimg[k]*yFimg[k]));
}
findmax(FMag);
yfreq=(250.0*fmax)/256;
k=0;//此处设置断点
flag=0;
}
return;
}
LCD显示控制文件lcd.c
#include"DspRegDefine.h"//VC5402寄存器定义
#defineuintunsignedint
#defineucharunsignedchar
#defineCLEAR0x0001//清除显示
#defineRESAC0x0002//位址歸位
#defineSETPOINT0x0006//進入點設定,,DDRAM位址計數器(AC)加1
#defineCURSOR0x000F//整體顯示,游標顯示,游標位置反白
#defineMCURSOR0x0014//游標向右移動,AC=AC+1
#defineFUCSET0x0030//功能設定,控制界面,基本指令集,默认设置
#defineCGRAMAC0x0040//設定CGRAM位址
#defineDDRAMAC0x0080//設定DDRAM位址
uintioportport8006;//液晶串行数据端口
uintioportport8007;
ucharfirst[16]="1fft2fir3iir";
ucharsecond[16]="低频:
KHZ";
ucharthird[16]="高频:
KHZ";
ucharfourth[16]="滤波:
KHZ";
ucharnumber[11]="0123456789.";
externdoublefreq1,freq2,yfreq;
voidDelay(uintnumbers)
{
uinti,j;
for(i=0;i<300;i++)
for(j=0;j}
voidSendByte(uchardat)
{
uchari;
uinttemp;
for(i=0;i<8;i++)
{
temp=port8007;//读IO8007SCLK="0";
if(dat&0x0080)
port8006=0;//写IO8006SID="1",发送数据"1"MSB先发送
else
temp=port8006;//读IO8006SID="0",发送数据"0"MSB先发送
port8007=0;//写IO8007SCLK="1";
dat=dat<<1;//数据左移,移位到dat.7
}
temp=port8007;//读IO8007SCLK="0";
}
voidSendCMD(uchardat)
{
SendByte(0x00F8);//11111,00,0RW=0,RS=0同步标志
SendByte(dat&0x00F0);//高四位
SendByte((dat&0x000F)<<4);//低四位
}
voidSendDat(uchardat)
{
SendByte(0x00FA);//11111,01,0RW=0,RS=1
SendByte(dat&0x00F0);//高四位
SendByte((dat&0x000F)<<4);//低四位
}
voidInitlcm()
{
SendCMD(FUCSET);//功能設定,8BIT并口,基本指令集
Delay
(1);
SendCMD(FUCSET);//功能設定,8BIT并口,基本指令集
Delay
(1);
SendCMD(CURSOR);//整體顯示,游標顯示,游標位置反白
Delay
(1);
SendCMD(CLEAR);//清除显示
Delay
(1);//需要50ms延时
SendCMD(SETPOINT);//進入點設定,游標右移,DDRAM位址計數器(AC)加1
Delay
(1);
}
voiddisplay()//显示基本框架
{
uinti;
Delay(500);
SendCMD(0x0080);//第一行
Delay
(1);
for(i=0;i<16;i++)
{
SendDat(first[i]);
Delay
(1);
}
SendCMD(0x0090);//第二行
Delay
(1);
for(i=0;i<16;i++)
{
SendDat(second[i]);
Delay
(1);
}
SendCMD(0x0088);//第三行
Delay
(1);
for(i=0;i<16;i++)
{
SendDat(third[i]);
Delay
(1);
}
SendCMD(0x0098);//第四行
Delay
(1);
for(i=0;i<16;i++)
{
SendDat(fourth[i]);
Delay
(1);
}
//SendCMD(CLEAR);//清除显示
}
voiddisplay1()
{
uintge,shi,bai;
SendCMD(0x0093);//可以设定基地址或者偏移地址
Delay
(1);
bai=(int)(freq1*10.0)/100;
shi=(int)(freq1*10.0)%100/10;
ge=(int)(freq1*10.0)%10;//强制类型转换并提取各位显示
SendDat(number[bai]);
Delay(0);
SendDat(number[shi]);
Delay(0);
SendDat(number[10]);
Delay(0);
SendDat(number[ge]);
Delay(0);
}
voiddisplay2()
{
uintge,shi,bai;
SendCMD(0x008b);//可以设定基地址或者偏移地址
Delay
(1);
bai=(int)(freq2*10.0)/100;
shi=(int)(freq2*10.0)%100/10;
ge=(int)(freq2*10.0)%10;//强制类型转换并提取各位显示
SendDat(number[bai]);
Delay(0);
SendDat(number[shi]);
Delay(0);
SendDat(number[10]);
Delay(0);
SendDat(number[ge]);
Delay(0);
}
voiddisplay3()
{
uintge,shi,bai;
SendCMD(0x009b);//可以设定基地址或者偏移地址
Delay
(1);
bai=(int)(yfreq*10.0)/100;
shi=(int)(yfreq*10.0)%100/10;
ge=(int)(yfreq*10.0)%10;//强制类型转换并提取各位显示
SendDat(number[bai]);
Delay(0);
SendDat(number[shi]);
Delay(0);
SendDat(number[10]);
Delay(0);
SendDat(number[ge]);
Delay(0);
}