DSP课程设计总结
(20##-20##学年第2学期)
题 目 :数据采集处理和控制系统设计
专业班级 :
学生姓名 :
学 号 :
指导教师 :
设计成绩 :
20## 年 7 月
目 录
一设计目的............................................................................................1
二系统分析............................................................................................1
1.1 设计要求......................................................................................1
1.2 主要任务......................................................................................1
三硬件设计............................................................................................2
3.1 硬件总体结构............................................................................2
3.2 DSP模块设计.............................................................................4
3.3 电源模块设计............................................................................6
3.4 时钟模块设计............................................................................6
3.5 存储器模块设计.......................................................................7
四软件设计..........................................................................................9
4.1 软件总体流程...........................................................................9
4.2 核心模块及实现代码...............................................................9
五课程设计总结................................................................................29
六参考文献........................................................................................29
一设计目的
此设计结合硬件、软件得到一个基于TMS320VC5416芯片,能完成数据采集、频谱分析、滤波、LCD显示的DSP系统。以此加强了对DSP功能的认识,复习了Altium Designer软件的使用方法。并在此基础上利用CCS软件编程实现A/D采集,FFT变换处理,低通滤波,显示滤波成分等功能的完整的小型数字处理系统。
二系统分析
1.1设计要求
(1)硬件设计要求
设计一个功能完备的,能够独立运行的精简DSP硬件系统,使用Altium Designer绘制出系统原理图和PCB图。
(2)软件设计要求
利用实验箱的模拟信号产生单元产生不同频率的信号,或者产生两个频率的信号叠加。在DSP中采集信号,并且对信号进行频谱分析,滤波等。通过串口命令选择算法功能,将计算的信号频率或者滤波后的信号频率在LCD上显示。
1.2主要任务
(1)DSP 硬件系统设计
设计DSP基本结构并绘制单片机最小系统原理图和PCB图。
(2)数据采集处理和控制系统设计
利用CCS软件编程实现数据采集x(n)→对数据FFT处理、分析频率成分→根据频率成
分设计FIR低通滤波器h(n)→卷积x(n)*h(n)=y(n)得到滤波之后的信号→分析滤波之后y(n)的频率成分→LCD显示高频,低频和滤波器的截止频率。
三硬件设计
3.1 硬件总体结构
图1 硬件总体结构
本次实验使用TMS320VC5416芯片作为主芯片。外围电路包括:电源、复位电路、时钟发生器(外接晶振或外接晶体)、、外部存储器FLASH、仿真接口电路JTAG、外部中断(不用:上拉)、I/O(不用:输出悬空,输入上拉)与主机通信的并行接口HPI(不用:悬空)。
(1)原理图设计
图2 单片机最小系统原理图
(2)PCB板设计
图3 PCB图(1)
图4 PCB图(2)
如图所示,由于其右上部分地址线和数据线较多,铺铜不方便,所以Vcore层分布在TM320VC5416芯片的左下部分。+3.3V为顶层红色部分,GND为底层蓝色部分。
3.2 DSP模块设计
图5 DSP模块(1)
上图为TMS320VC5416芯片的设计,该芯片不用的输入引脚要拉高,输出引脚悬空。①本设计用到了该芯片的数据信号线,初始化、中断和复位线,部分存储器控制信号线,部分振荡器/定时信号线,串口信号线,电源引脚线和JTAG测试引脚线。②主CPU每个电源管脚旁边都有一个0.1uF的去耦电容,去耦电容可以提供较稳定的电源,同时也可以降低元件耦合到电源端的噪声,间接可以减少其他元件受此元件噪声的影响。③CLKMOD1、CLKMOD2、CLKMOD3分别接1、1、0,表示锁相环一倍频
图6 DSP模块(2)
图6 DSP模块(3)
3.3 电源模块设计
图7 电源模块
73HD316为DC-DC转换芯片,将+5V电压转换成Vcore和+3.3V电压,电源和地之间要接滤波电容。Vcore为内核电压,+3.3V为外设电压,这样可以减小功耗。
3.4 时钟模块设计
图8 时钟模块
10MHZ晶振的输出接到TM320VC5416芯片的X2/CLKIN管脚,芯片的X1悬空,即使用外部晶振。
3.5 存储器模块设计
图9 存储器模块
存储器的数据线和地址线分别接CPU的数据线和地址线。DSP控制信号R/W_L接FLASH的WE_L和OE表示DSP向FLASH写和从FLASH读有效。当DSP从FLASH读时,DSP输出高电平,但FLASH的OE为低有效,应接一个非门。
3.6 复位电路设计
图10 复位电路
如图所示有两种复位方法:(1)上电复位,利用RC的延迟特性,刚开始上电,由于电容电压不能突变,RESET处为低,直到电容充电完毕,变高,实现复位;(2)手动复位,S1闭合,电容放电,电平变低,断开,电容充电过程与上电复位相同,实现复位。发光二极管用来表示DSP的工作状态三个电源是否正常工作。
3.7 仿真接口电路设计
图11 仿真接口电路
JTAG仿真接口,用于将外部的程序、数据导入DSP内部,完成运算处理。是外部存储器与DSP的一个媒介。
四软件设计
4.1 软件总体流程
4.2 核心模块及实现代码
(1)主要代码
//------------------头文件--------------------------------------
#include "DspRegDefine.h" //VC5402 寄存器定义
#include "stdio.h" //输入输出接口定义
#include "math.h" //数学计算定义
//---------------------------------------------------------------
/* ****************** 宏定义 ***************
************************************************************
*/
#define UCHAR unsignedchar
#define UINT16 unsignedint
#define UINT32 unsignedlong
#define TRUE 1
#define FALSE 0
#define Length 256 //FFT的点数
//---------------------------------------------------------------
//--------------- LCD 指令 -----------------------------
//基本指令集 RE = 0
#define CLEAR 0x0001 //清除显示
#define RESAC 0x0002 //位址歸位
#define SETPOINT 0x0006 //進入點設定,游標右移,DDRAM 位址計數器(AC)加1
#define CURSOR 0x000F //整體顯示,游標顯示,游標位置反白
#define MCURSOR 0x0014 //游標向右移動,AC=AC+1
#define FUCSET 0x0030 //功能設定,BIT MPU 控制界面,基本指令集,默认设置
#define CGRAMAC 0x0040 //設定CGRAM 位址
#define DDRAMAC 0x0080 //設定DDRAM 位址
//第一行AC 範圍為80H..8FH
//第二行AC 範圍為90H..9FH
//第三行AC 範圍為A0H..AFH
//第四行AC 範圍為B0H..BFH
//#define READBF RS=0,RW=1,DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0
// BF AC6 AC5 AC4 AC3 AC2 AC1 AC0
// 讀取忙碌旗標(BF)和位址
// 就是读取指令寄存器,PORT8006,BF=1,表示LCD忙碌
//#define WRITERAM RS=1,RW=0,DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0
// D7 D6 D5 D4 D3 D2 D1 D0
// 寫入資料到RAM
// 就是写数据寄存器: PORT8005
//#define READRAM RS=1,RW=1,DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0
// D7 D6 D5 D4 D3 D2 D1 D0
// 讀取RAM 的值
// 就是从数据寄存器讀取資料, PORT8007
//擴充指令集 RE=1
#define IDLE 0x01 //待命模式
#define CGRAMSET 0x02 //捲動位址或RAM 位址選擇
#define REVERSE 0x04 //反白選擇
#define SLEEP 0x0c //脫離睡眠模式
#define EFUCSET 0x66 //擴充功能設定,8 BIT MPU 控制界面,為擴充指令集動作,繪圖顯示ON
#define SISA 0x40 //設定IRAM 位址或捲動位址
#define SETGDRAM 0x80 //設定繪圖RAM 位址
//---------------------------------------------------------
/* 端口定义 */
//---------------------------------------------------------
ioport UINT16 port8002; //定义输出AD端口为0x8002;
ioport UINT16 port8004; //写指令寄存器
ioport UINT16 port8005; //写数据寄存器
ioport UINT16 port8006; //读指令寄存器
ioport UINT16 port8007; //读数据寄存器
//----------------------------------------------------------
/* 全局变量定义 */
//---------------------------------------------------------
int in_x[Length]; //数据缓冲数组 Length
int i = 0;
int s,m = 0;
int intnum = 0;
int flag = 0; //采集Length点的标志
double xavg;
double x[Length],mo[Length],mo2[Length],pr[Length],pi[Length];
int n,l,il;
int k=8; //k为Length相对于2的幂次
double data_kfft[Length] ; //数据缓冲 256个数组
double data_re[Length] ; //数据缓冲 256个数组
double data_im[Length] ; //数据缓冲 256个数组
double data_buffim[Length] ; //数据缓冲 256个数组
double data_out[256] ;
double data_temp[256];
double data_out1[256];
double h[51] ;
int x1=0;
int x2=0;
double fhz=0;
double f1;
double f2;
double wc=0;
int i;
UINT16 temp;
UCHAR data_buff1[10] = "低频: ";
UCHAR data_buff2[10] = "高频: ";
UCHAR data_buff3[10] = "滤波: ";
UCHAR data_buff4[16] = "liru 12052203";
UCHAR num[11] = "0123456789.";
int a;
int b;
int c;
int d;
/*
**********************************************************************
*************** 所使用的函数原型 *****************
**********************************************************************
*/
voidcpu_init(void); //初始化CPU
voidDelay(UINT16 numbers); //延迟
voidxint2_init(void); //外部中断2初始化子程序
voidkfft(double pr[Length],double pi[Length],int n,int k,double fr[Length],double fi[Length],int l,int il);//基2快速傅立叶变换子程序
interruptvoidExtInt2(); //中断2中断子程序
voidfirdes(double npass); //fir
voidConvolveok( //卷积函数
double *x, //原始输入数据
double *h, //冲击响应
double *y, //卷积输出结果
UINT16 length, //序列长度
UINT16 fLen
);
externvoiddelay_100us(void); //100us延迟 --指令之间的延迟
externvoiddelay_1us(void); //1us延迟 --时钟之间的延迟
voiddelay_50ms(void); //50ms延迟 --复位延迟
voiddelay_20ms(void); //20ms延迟 --清屏延迟
voidSendByte(UCHAR dat); //串行发送一字节数据
voidSendCMD(UCHAR dat); //写指令寄存器
voidSendDat(UCHAR dat); //写显示数据或单字节字符
voidDisplay(UCHAR x_add,UCHAR dat1,UCHAR dat2); //写汉字到LCD 指定的位置
voidInitlcm(void); //初始化 LCM
//-------------------------------------------------------------------
/*
************************************************************************
*********************** 函数定义 ******************
************************************************************************
*/
//--------------------------------------------------------------------
// 函数名称 : void cpu_init(void)
// 函数说明 : 初始化CPU
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
voidcpu_init(void)
{
asm(" nop ");
asm(" nop ");
asm(" nop ");
//-------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsignedint*)CLKMD=0x0; //switch to DIV mode clkout= 1/2 clkin
while(((*(unsignedint*)CLKMD)&01)!=0);
*(unsignedint*)CLKMD=0x77ff; //switch to PLL X 3 mode
//--------------------------------------------------------------------
/*---------------------------------------------------------------------*/
*(unsignedint*)PMST=0x3FF2;
//---------------------------------------------------------------------
/*--------------------------------------------------------------------*/
*(unsignedint*)SWWSR=0x7fff;
//--------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsignedint*)SWCR=0x0001;
//--------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsignedint*)BSCR=0xf800;
//--------------------------------------------------------------------
asm(" ssbx intm "); //Disable all mask interrupts
//--------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsignedint*)IMR=0x0;
//--------------------------------------------------------------------
/*--------------------------------------------------------------------*/
*(unsignedint*)IFR=0xffff;
//--------------------------------------------------------------------
asm(" nop ");
asm(" nop ");
asm(" nop ");
}
/*
***********************************************************
- 函数名称 : void Delay(int numbers)
- 函数说明 : 延时
- 输入参数 : numbers
- 输出参数 : 无
***********************************************************
*/
voidDelay(UINT16 numbers)
{
UINT16 i,j;
for(i=0;i<4000;i++)
for(j=0;j
}
//--------------------------------------------------------------------
// 函数名称 : void xint2_init(void)
// 函数说明 : 初始化XINT2
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
voidxint2_init() //外部中断2初始化子程序
{
*(unsignedint*)IMR=0x0004;//使能int2中断
/*
bit 15 1: XINT2 flag --write "1" to clear
bit 14-3 0: reserved
bit 2 1: XINT2 Polarity --"1" rising eage
bit 1 0: XINT2 Priority --"0" High priority
bit 0 1: XINT2 Enable --"1" Enable interrupt
*/
asm(" rsbx INTM");//开总中断
}
//--------------------------------------------------------------------
// 函数名称 : void kfft(double pr[Length],double pi[Length],int n,int k,double fr[Length],double fi[Length],int l,int il)
// 函数说明 : 基2快速傅立叶变换子程序
// 输入参数 :
// 输出参数 : 无
//--------------------------------------------------------------------
voidkfft(double pr[Length],double pi[Length],int n,int k,double fr[Length],double fi[Length],int l,int il)
{
int it,m,is,i,j,nv,l0;
double p,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;
else pi[i]=-90.0;
}
else
pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;
}
}
voidfirdes(double npass)//fir滤波器,求出单位脉冲响应
{
int pi=3.14;
int t;
for (t=0; t<51; t++)
{
if (t == ((51-1)/2))
{
h[t]=2*npass;
}
else
{
h[t] = sin((t-(51-1)/2.0)*npass*pi*2)/(pi*(t-(51-1)/2.0));//fir滤波器的函数
}
}
}
voidConvolveok( //卷积函数
double *x, //原始输入数据
double *h, //冲击响应
double *y, //卷积输出结果
UINT16 length, // 序列长度
UINT16 fLen
)
{
UINT16 m,p,j;
double r,rm;
double xmean = 0.0;
double xmid[100];
h[0] = 0.0;
h[50] = 0.0;
for(m=0;m
{
xmid[m] = 0.0;
}
for (m=0; m
{
xmean = x[m] + xmean;
}
xmean = 1.0*xmean/length;
for (m=0; m
{
x[m] = x[m] - xmean;
}
for (m=0; m
{
for (p=0; p
{
xmid[fLen-p-1] = xmid[fLen-p-2];
}
xmid[0] = x[m];
r = 0.0;
rm= 0.0;
for (j=0; j
{
r = xmid[j] * h[j];
rm = rm + r;
}
y[m] = rm;
}
}
//--------------------------------------------------------------------
// 函数名称 : void delay_50ms(void)
// 函数说明 : 50ms延迟
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
voiddelay_50ms()
{
UINT16 i,j;
for(i=0;i<=1000;i++);
for(j=0;j<=2000;j++); //延迟250*1000*CLKOUT=500000*CLKOUT
//1/CLKOUT=0.2us
}
//--------------------------------------------------------------------
// 函数名称 : void delay_20ms(void)
// 函数说明 : 20ms延迟
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
voiddelay_20ms()
{
UINT16 i,j;
for(i=0;i<=1000;i++);
for(j=0;j<=400;j++); //延迟10*1000*CLKOUT=100000*CLKOUT
//1/CLKOUT=0.2us
}
// 函数名称 : void delay_100us(void)
// 函数说明 : 100us延迟
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
voiddelay_100us()
{
UINT16 i,j;
for(i=0;i<=1000;i++);
for(j=0;j<=2;j++); //延迟10*1000*CLKOUT=100000*CLKOUT
//1/CLKOUT=0.2us
}
// 函数名称 : void delay_1us(void)
// 函数说明 : 1us延迟
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
voiddelay_1us()
{
UINT16 i;
for(i=0;i<=20;i++);
//延迟10*1000*CLKOUT=100000*CLKOUT
//1/CLKOUT=0.2us
}
//--------------------------------------------------------------------
// 函数名称 : void SendByte(UCHAR dat) 串行发送一字节数据
// 函数说明 : 串行发送一字节数据,在时钟的上升沿发送数据,在时钟为低电平时,数据变化
// 输入参数 : 发送的数据
// 输出参数 : 无
//--------------------------------------------------------------------
voidSendByte(UCHAR dat)
{
UCHAR i;
for(i=0;i<8;i++)
{
temp = port8007; //读IO 8007 SCLK="0";
if(dat & 0x0080)
port8006 = 0; //写IO 8006 SID="1",发送数据"1" MSB先发送
else
temp = port8006; //读IO 8006 SID="0",发送数据"0" MSB先发送
port8007 = 0; //写IO 8007 SCLK="1";
dat = dat<<1; //数据左移,移位到dat.7
}
temp = port8007 ; //读IO 8007 SCLK="0";
}
//--------------------------------------------------------------------
// 函数名称 : void SendCMD(UCHAR dat) 写指令寄存器
// 函数说明 : 写指令寄存器
// 输入参数 : 输入的命令字
// 输出参数 : 无
//--------------------------------------------------------------------
voidSendCMD(UCHAR dat)
{
SendByte(0x00F8); //11111,00,0 RW=0,RS=0 同步标志
SendByte(dat & 0x00F0); //高四位
SendByte((dat & 0x000F)<<4); //低四位
}
//--------------------------------------------------------------------
// 函数名称 : void SendDat(UCHAR dat) 写显示数据或单字节字符
// 函数说明 : 写数据寄存器
// 输入参数 : 输入的数据
// 输出参数 : 无
//--------------------------------------------------------------------
voidSendDat(UCHAR dat)
{
SendByte(0x00FA); //11111,01,0 RW=0,RS=1
SendByte(dat & 0x00F0); //高四位
SendByte((dat & 0x000F)<<4); //低四位
}
//--------------------------------------------------------------------
// 函数名称 : void display(UCHAR x_add,UCHAR dat1,UCHAR dat2)写汉字到LCD 指定的位置
// 函数说明 : x_add显示RAM的地址,dat1/dat2显示汉字编码
// 输入参数 : x_add,dat1/dat2
// 输出参数 : 无
//--------------------------------------------------------------------
voidDisplay(UCHAR x_add,UCHAR dat1,UCHAR dat2)
{
SendCMD(x_add);//1xxx,xxxx 设定DDRAM 7位地址xxx,xxxx到地址计数器AC
SendDat(dat1);
SendDat(dat2);
}
//--------------------------------------------------------------------
// 函数名称 : void Initlcm(void)
// 函数说明 : 初始化 LCM
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
voidInitlcm()
{
asm(" nop ");
delay_50ms();
SendCMD(FUCSET); //功能設定,8BIT 并口,基本指令集
delay_100us();
SendCMD(FUCSET); //功能設定,8BIT 并口,基本指令集
delay_100us();
SendCMD(CURSOR); //整體顯示,游標顯示,游標位置反白
delay_100us();
SendCMD(CLEAR); //清除显示
delay_20ms();
SendCMD(SETPOINT); //進入點設定,游標右移,DDRAM 位址計數器(AC)加1
delay_100us();
}
//--------------------------------------------------------------------
// 函数名称 : void ExtInt2(void)
// 函数说明 : 中断2的子程序
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
interruptvoidExtInt2()//中断2中断子程序
{
int j;
int temp1=0;
int temp2=0;
*(unsignedint*)IFR=0xFFFF;//清除所有中断标志,"写1清0" ,这个语句可以省略,响应中断自动清除中断标志
//----读AD7822的转换结果---------------------------------------------
in_x[m] = port8002 & 0x00ff;
m++;
intnum = m;
//-------------------------------------------------------------------
if (intnum == Length)//采集到Length个点了吗?是,进行FFT分析
{
intnum = 0;
xavg = 0.0;
for (s=0; s
{
xavg = in_x[s] + xavg;//归一化处理
}
xavg = xavg/Length;
for (s=0; s
{
x[s] = 1.0*(in_x[s] - xavg);//即求出平均值(直流)后,减去直流
pr[s] = x[s]; //输入实部
pi[s] = 0; //输入虚部,如果虚部不赋值0为任意值
}
for(j=0;j<256;j++)//初始化数组in_x[i] =0
{
pi[j] = 0;
data_re[j] = 0;
data_im[j] = 0;
pr[j]=x[j];
}
kfft(pr,pi,Length,k,data_re,data_im,0,1); //调用FFT分析程序
for (s=0;s
{ mo[s] = sqrt(data_re[s]*data_re[s]+data_im[s]*data_im[s]);} //求输出模值
temp1=mo[2];
temp2=mo[50];
for(j=3;j<40;j++)
{
if(mo[j]>=temp1)
{
temp1=mo[j];
x1=j;
}
}//最大值,低频
for(j=40;j<128;j++)
{
if(mo[j]>=temp2)
{
temp2=mo[j];
x2=j;
}
}//最大值,高频
f1=x1*250.0/256.0;//低频频率,250为采样频率
f2=x2*250.0/256.0;//高频频率
fhz=(f1+f2)/500.0;//滤波器截止频率,fhz=(f1+f2)/2/250
firdes(fhz);//调用fir函数
for(j=0;j<256;j++) //初始化数组
{
data_buffim[j] = 0;
data_re[j] = 0;
data_im[j] = 0;
data_out[j]=0;
data_temp[j]=in_x[j];
}
Convolveok(data_temp,h,data_out,256,51);//调用卷积函数,输出结果保存在data_out
for(j=0;j<256;j++) //初始化数组
{
data_buffim[j] = 0;
data_re[j] = 0;
data_im[j] = 0;
data_out1[j]=data_out[j];
}
kfft(data_out1,data_buffim,256,8,data_re,data_im,0,1);
for (s=0;s
{ mo2[s] = sqrt(data_re[s]*data_re[s]+data_im[s]*data_im[s]);} //求输出模值
data_buff1[5]=num[0];
a=(int)(f1*10.0)/100;
data_buff1[6]=num[a];
b=(int)(f1*10.0)%100/10;
data_buff1[7]=num[b];
data_buff1[8]=num[10];
c=(int)(f1*10.0)%10;
data_buff1[9]=num[c];
//-----------------------------------------------------------
SendCMD(0x0080); //设定DDRAM的地址在第一行 82H
delay_100us();
for(i =0;i<10;i++)
{
SendDat(data_buff1[i]);
delay_100us();
asm(" nop ");
}
asm(" nop ");
d=(int)(f2)/100;
data_buff2[5]=num[d];
a=(int)(f2)%100/10;
data_buff2[6]=num[a];
b=(int)(f2)%10;
data_buff2[7]=num[b];
data_buff2[8]=num[10];
c=(int)(f2*10.0)%10;
data_buff2[9]=num[c];
//------------------------------
SendCMD(0x0090); //设定DDRAM的地址在第二行 92H
delay_100us();
for(i =0;i<10;i++)
{
SendDat(data_buff2[i]);
delay_100us();
}
asm(" nop ");
fhz=(f1+f2)/2;
d=(int)(fhz)/100;
data_buff3[5]=num[d];
a=(int)(fhz)%100/10;
data_buff3[6]=num[a];
b=(int)(fhz)%10;
data_buff3[7]=num[b];
data_buff3[8]=num[10];
c=(int)(fhz*10.0)%10;
data_buff3[9]=num[c];
//--------------------------------
SendCMD(0x0088); //设定DDRAM的地址在第三行 8AH
delay_100us();
for(i =0;i<10;i++)
{
SendDat(data_buff3[i]);
delay_100us();
}
asm(" nop ");
//--------------------------------
SendCMD(0x0098); //设定DDRAM的地址在第四行 9AH
delay_100us();
for(i =0;i<16;i++)
{
SendDat(data_buff4[i]);
delay_100us();
}
asm(" nop ");
/*SendCMD(0x0080); //设定DDRAM的地址在第一行 82H
delay_100us();
SendDat(data_buff1[1]);
delay_100us();
*/
//-------------------------------------------------------------
//delay_100us();
Delay(500);
//delay_100us();
SendCMD(CLEAR); //清除显示
m=0;
flag = 1; //改变标志位
}
}
/*
************************************************************
****************** 主函数 *******************
************************************************************
*/
voidmain()
{
//----------系统初始化-------------------------------
asm(" nop ");
cpu_init(); //初始化CPU
asm(" nop ");
xint2_init(); //外部中断2初始化
asm(" nop ");
for(i=0;i
in_x[i] = 0;
asm(" nop ");
//-----------LCD初始化--------------------------------
asm(" nop ");
Initlcm();
asm(" nop ");
i = 0 ;
for(i=0;i<256;i++) //初始化数组data_buff[i] =0
{
in_x[i] = 0;
data_buffim[i] =0;
data_kfft[i]=0; //数据缓冲 256个数组
data_re[i] = 0;
data_im[i] = 0;
}
asm(" nop ");
//-----------等待AD7822中断--------------------------
while(1)
{
if (flag == 1)
flag = 0; //在这里设置断点观察FFT的分析结果
}
}
(2)程序运行结果
①采集的数据及FFT运算结果
图12 采集的数据及FFT运算结果
如上图所示,上述波形含有两种频率成分,实验中需要将高频成分滤掉,保留低频成分。由于输入是实序列,因此频域为偶对称图形。
②采集的数据及滤波结果
图13 采集的数据及滤波结果
可得滤波后的波形较平滑,滤掉了高频分量。
③LCD显示
图14 LCD显示
LCD显示了采集到的数据中含有的低频和高频成分,并显示了滤波器的截止频率。截止频率为(低频+高频)/2。
五课程设计总结
本次课程设计分为硬件部分和软件部分。
(1)硬件部分
硬件部分的学习,首先学到了设计一个DSP系统的方法:根据所要实现的目标确定所需的各功能部件,以系统框图的形式表现出来;选择合适的DSP芯片,根据各个管脚的性质(通过查阅资料等形式)配置合适的外部电路,并利用Altium Designer软件画出原理框图;对各个芯片、部件等进行封装,尽量考虑工程实践的要求,如大小、贴片式还是插孔式;根据原理框图绘制PCB版图,直至一个完整的DSP系统绘制完成。
①通过绘制原理框图,进一步了解了DSP芯片及其实现功能。在画原理图的时候,首先要清楚单片机工作的原理,知道哪些管脚该接,哪些管脚不该接。有些不用的输入引脚要拉高,输出引脚悬空。在连接73HD316的管脚时,由于疏忽将Vcore和GND连接到了一起,最后在老师的提醒下得到了改正。这告诉我们要多练习,②在画PCB图的时候,首先要布局好元器件,因为存储器的地址线和数据线管脚不是按顺序排列,布局好元器件可以方便布线。主芯片的每个电源引脚都要加一个去耦电容再接地。
(2)软件部分
此次软件部分的设计是通过编程实现数据采集,处理,滤波,显示在LCD上这些功能。程序大体框架由例程得到,自己需要添加一些东西,例如FFT算法和卷积算法的实现等等。程序中有很多不理解的地方,多亏了老师的悉心教导,并且要求我们有不求甚解的心态。由于使用外部中断2,因此这些功能都需要在中断服务程序中完成,在主函数中只需要开中断即可。多次试验,我们学会了如何读懂程序、设置断点、查看变量和波形。根据FFT算法得到的频谱设计合适的滤波器,并与采集的数据卷积即可。LCD显示即将得到的频率显示在液晶上,要正确的选取显示地址,否则容易造成混叠,显示不出来。
通过实习,我们都学到了很多,也在坚持不懈中找到了乐趣。刚开始实习的时候,有很多不明白的地方,在实习的过程中,通过自己检出不懈的努力和老师的细心指导、同学们的帮助,最终完成了任务。
六参考文献
【1】TMS320VC5416 Data Manual Texas Instruments,2005
【2】TMS320C54x 系列DSP的CPU与外设 . 北京:清华大学出版社,2006
【3】叶青等,TMS320C54x 系列DSP技术及其应用 . 北京:机械工业出版社,2009
科信学院课程设计说明书(2008/20XX学年第二学期)课程名称:DSP控制器及其应用题目:DSP通用管脚控制LCD公告牌的文字显…
郑州航空工业管理学院电子通信工程系DSP原理及应用课程设计报告设计题目:基于TMS320F2812DSP处理器的FIR滤波器的设计…
一绪论数字图像处理DigitalImageProcessing是指将图像信号转换成数字信号并利用计算机对其进行处理的过程图像处理中…
DSP课程设计总结(20##-20##学年第2学期)题目:专业班级:电子1103学生姓名:学号:指导教师:设计成绩:20##年6月…
DSP课程设计总结(20##-20##学年第2学期)题目:数据采集处理和控制系统设计班级:电子091班学生姓名:学号:指导教师:2…
一绪论数字图像处理DigitalImageProcessing是指将图像信号转换成数字信号并利用计算机对其进行处理的过程图像处理中…
课程设计总结报告课程名称DSP控制器及其应用设计题目专业电子信息工程班级姓名学号指导教师报告成绩信息工程学院二一四年六月十三日目录…
科信学院课程设计说明书(2008/20XX学年第二学期)课程名称:DSP控制器及其应用题目:DSP通用管脚控制LCD公告牌的文字显…
一、课程设计的目的和要求1.1课程设计目的:本课程是DSP技术类课程配套的课程设计,要求学生通过高级语言或汇编语言编程实现较复杂的…
DSP课程设计总结(20##-20##学年第2学期)题目:数据采集处理和控制系统设计班级:电子091班学生姓名:学号:指导教师:2…
一Bios的启动过程DSP/BIOS的启动过程包括以下几步:*初始化DSP:复位中断向量指向c_int00地址,DSP/BIOS程…