资源描述
dsp课程设计报告
52
2020年4月19日
文档仅供参考,不当之处,请联系改正。
DSP课程设计总结
( - 第2学期)
题 目 : 数据采集处理和控制系统设计
专业班级 : 电子1202
学生姓名 : 李茹
学 号 : 12052203
指导教师 : 李莉
设计成绩 :
年 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
FLASH
WR
OE
READY
RS
DSP _
R/W
X2/CLKIN
A0-A19
电源
D0-D15
复位电路
JTAG
晶振
图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 软件总体流程
A/D采样
对采样信号进行FFT运算,并求两频率值
设计FIR低通滤波器
调用卷积算法对信号进行处理
LCD显示频率值
返回第二步
4.2 核心模块及实现代码
(1)主要代码
//------------------头文件--------------------------------------
#include "DspRegDefine.h" //VC5402 寄存器定义
#include "stdio.h" //输入输出接口定义
#include "math.h" //数学计算定义
//---------------------------------------------------------------
/* ****************** 宏定义 ***************
************************************************************
*/
#define UCHAR unsigned char
#define UINT16 unsigned int
#define UINT32 unsigned long
#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] = ".";
int a;
int b;
int c;
int d;
/*
**********************************************************************
*************** 所使用的函数原型 *****************
**********************************************************************
*/
void cpu_init(void); //初始化CPU
void Delay(UINT16 numbers); //延迟
void xint2_init(void); //外部中断2初始化子程序
void kfft(double pr[Length],double pi[Length],int n,int k,double fr[Length],double fi[Length],int l,int il);//基2快速傅立叶变换子程序
interrupt void ExtInt2(); //中断2中断子程序
void firdes(double npass); //fir
void Convolveok( //卷积函数
double *x, //原始输入数据
double *h, //冲击响应
double *y, //卷积输出结果
UINT16 length, //序列长度
UINT16 fLen
);
extern void delay_100us(void); //100us延迟 --指令之间的延迟
extern void delay_1us(void); //1us延迟 --时钟之间的延迟
void delay_50ms(void); //50ms延迟 --复位延迟
void delay_20ms(void); //20ms延迟 --清屏延迟
void SendByte(UCHAR dat); //串行发送一字节数据
void SendCMD(UCHAR dat); //写指令寄存器
void SendDat(UCHAR dat); //写显示数据或单字节字符
void Display(UCHAR x_add,UCHAR dat1,UCHAR dat2); //写汉字到LCD 指定的位置
void Initlcm(void); //初始化 LCM
//-------------------------------------------------------------------
/*
************************************************************************
*********************** 函数定义 ******************
************************************************************************
*/
//--------------------------------------------------------------------
// 函数名称 : void cpu_init(void)
// 函数说明 : 初始化CPU
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
void cpu_init(void)
{
asm(" nop ");
asm(" nop ");
asm(" nop ");
//-------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsigned int*)CLKMD=0x0; //switch to DIV mode clkout= 1/2 clkin
while(((*(unsigned int*)CLKMD)&01)!=0);
*(unsigned int*)CLKMD=0x77ff; //switch to PLL X 3 mode
//--------------------------------------------------------------------
/*---------------------------------------------------------------------*/
*(unsigned int*)PMST=0x3FF2;
//---------------------------------------------------------------------
/*--------------------------------------------------------------------*/
*(unsigned int*)SWWSR=0x7fff;
//--------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsigned int*)SWCR=0x0001;
//--------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsigned int*)BSCR=0xf800;
//--------------------------------------------------------------------
asm(" ssbx intm "); //Disable all mask interrupts
//--------------------------------------------------------------------
//--------------------------------------------------------------------
*(unsigned int*)IMR=0x0;
//--------------------------------------------------------------------
/*--------------------------------------------------------------------*/
*(unsigned int*)IFR=0xffff;
//--------------------------------------------------------------------
asm(" nop ");
asm(" nop ");
asm(" nop ");
}
/*
***********************************************************
- 函数名称 : void Delay(int numbers)
- 函数说明 : 延时
- 输入参数 : numbers
- 输出参数 : 无
***********************************************************
*/
void Delay(UINT16 numbers)
{
UINT16 i,j;
for(i=0;i<4000;i++)
for(j=0;j<numbers;j++);
}
//--------------------------------------------------------------------
// 函数名称 : void xint2_init(void)
// 函数说明 : 初始化XINT2
// 输入参数 : 无
// 输出参数 : 无
//--------------------------------------------------------------------
void xint2_init() //外部中断2初始化子程序
{
*(unsigned int*)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快速傅立叶变换子程序
// 输入参数 :
// 输出参数 : 无
//--------------------------------------------------------------------
void kfft(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./(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.;
}
}
void firdes(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滤波器的函数
}
}
}
void Convolveok( //卷积函数
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<fLen;m++)
{
xmid[m] = 0.0;
}
for (m=0; m<length; m++)
{
xmean = x[m] + xm
展开阅读全文