DSP-AD采集与显示

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

AD采集与示波器显示
AD采集与示波器显示
摘要:是将信号以数字方式表示并处理的理论和技术。

这次实验将正弦波、方波、三角波经过AD转换,将采集的数据通过LCD显示出来。

通过AD采集模块,将正弦波、方波、三角波由模数转换成数据,经FFT程序对其进行傅里叶变换,得到采集数据的频谱,再经过LCD模块。

关键词:DSP;AD采集;LCD显示;FFT
一.设计任务和要求
A. 通过AD进行信号采集
B. 信号显示在LCD上,实现示波器的效果
说明:信号采集:通过AD进行信号采集
处理:把采集到的信号转换为可以显示的数据
输出/显示:显示在LCD上
二.实验开发环境
1.通用 PC机一台,安装 Windows2000 或 WindowsXP 操作系统且已安装常用软件(如:WinRAR 等)。

2.TMS320C55xx 评估板及相关电源。

本实验采用ICETEK-VC5509-A评估板。

3.通用 DSP 仿真器一台及相关连线。

本实验采用ICETEK-5100USB仿真器。

4.控制对象(选用)。

本实验采用ICETEK-CTR控制板。

5.TI的 DSP 开发集成环境 Code Composer Studio。

本实验采用CCS2.21 for ’C5000。

6.仿真器驱动程序。

7.实验程序及相关文档。

三.实验设备
通用计算机一台,ICETEK-VC5509-EDU 实验箱。

四.实验原理
1.将从信号源获取的模拟信号经过A/D转换后,再进行FFT变换,然后输出。

2.TMS320VC5509A 模数转换模块特性:
内置采样和保持的10位模数转换模块ADC,最小转换时间为500ns,最大采样率为21.5kHz。

有2个模拟输入通道(AIN0—AIN1)。

采样和保持获取时间窗口有单独的预定标控制。

3.模数转换工作过程:
模数转换模块接到启动转换信号后,开始转换第一个通道的数据。

经过一个采样时间的延迟后,将采样结果放入转换结果寄存器保存。

转换结束,设置标志。

等待下一个启动信号。

4.模数转换的程序控制:
模数转换相对于计算机来说是一个较为缓慢的过程。

一般采用中断方式启动转换或保存结果,这样在 CPU 忙于其他工作时可以少占用处理时间。

设计转换程序应首先考虑处理过程如何与模数转换的时间相匹配,根据实际需要选择适当的触发转换的手段,也要能及时地保存结果。

由于 TMS320VC5509A DSP芯片内的 A/D转换精度是10位的,转换结果的低10位为所需数值,所以在保留时应注意将结果的高6位去除,取出低10位有效数字。

5.FFT 的原理和参数生成公式:
FFT 并不是一种新的变换,它是离散傅立叶变换(DFT)的一种快速算法。

由于我们在计算 DFT 时一次复数乘法需用四次实数乘法和二次实数加法;一次复数加法则需二次实数加法。

每运算一个 X(k)需要 4N次复数乘法及 2N+2(N-1)=2(2N-1)次实数加法。

所以整个 DFT运算总共需要 4N^2 次实数乘法和 N*2(2N-1)=2N(2N-1)次实数加法。

如此一来,计算时乘法次数和加法次数都是和 N^2 成正比的,当 N很大时,运算量是可观的,因而需要改进对 DFT 的算法减少运算速度。

根据傅立叶变换的对称性和周期性,我们可以将 DFT 运算中有些项合并。

我们先设序列长度为N=2^L,L 为整数。

将N=2^L 的序列x(n)(n=0,1,……,N-1),按N的奇偶分成两组,也就是说我们将一个 N点的 DFT 分解成两个 N/2 点的 DFT,他们又重新组合成一个如下式所表达的 N点 DFT:
一般来说,输入被假定为连续的。

当输入为纯粹的实数的时候,我们就可以利用左右对称的特性更好的计算DFT。

我们称这样的 RFFT 优化算法是包装算法:首先 2N 点实数的连续输入称为“进包”。

其次N点的 FFT 被连续运行。

最后作为结果产生的 N点的合成输出是“打开”成为最初的与 DFT 相符合的 2N点输入。

使用这一思想,我们可以划分 FFT 的大小,它有一半花费在包装输入O(N)
的操作和打开输出上。

这样的 RFFT 算法和一般的 FFT 算法同样迅速,计算速度几乎都达到了两次 DFT的连续输入。

6.液晶显示屏的结构
实验箱左上方有一个长方形液晶屏,由64×128 个点阵构成。

显示时,每个点阵对应一个2 进制数,数为0,显示一点;为1,则不显示。

通过不同位置显示与不显示,可以显示数字、图形、汉字等。

每个点阵对应的2 进制数,64×128 个点阵,则对应64×128bit 空间
1)将液晶分为两块:左半屏和右半屏,每块64×64
2)每列64 个点阵,8 个点阵为一部分,分为8 部分,用一个byte 控制一个部分,这个byte 中哪个bit 为1,则显示;为0,则不显示。

3)每个半屏分为8 页,64 列。

4)通过向某行的相邻8 列输入显码,则可以显示数字
五.总体设计方案
1.【系统总体设计思路】
本系统实现对输入的方波、正弦波、三角波等信号采集,经过AD转换后,对这些数字信号处理,最后通过LCD显示出来,达到基本的示波器的效果。

总体设计思路如图所示。

系统包括信号源、控制器模块TMS320VC5509A、信号检测采集模块、显示模块四部分。

1.2【功能描述】
通过信号源输入的方波、正弦波、三角波等信号采集,经过AD转换后,对这些数字信号处理,最后通过LCD显示出来,达到基本的示波器的效果。

之后,通过对信号进行FFT变换,将其显示出来,同时显示波形的最大值/峰峰值,以及XY坐标网格。

1.3【模块操作】
AD采集部分:
1.设置通道0 信号源类型为正弦波,采集通道0 的128 个数据,并用Graph 图形窗口观察。

2.对采集到的128 个数据进行FFT,得到其幅频特性数据,并用Graph 图形窗口观察。

(额外验证的内容)
3.分别改变波形类型为:三角波和方波,重复步骤1,2。

4.设置波形类型为正弦波,改变波形的频率和振幅,重复步骤1、2,至少实验3 个不同频率和3 个不同振幅。

显示部分:
1.将采集到的128列数据进行处理,进行运算。

2.将二维数组显示在64*128的LCD上,显码数组。

1.4【结构框图】
系统由TMS320VC5509A为CPU的控制器、LCD显示模块、信号源输入、AD采集转换等模块构成。

六.实验结论
1.三角波
2.正弦波
七.相关代码
AD采集命令:
void InitADC();
void wait(unsigned int cycles);
void InitADC()
{
ADCCLKCTL=0x23; // 4MHz ADCLK
ADCCLKDIV=0x4f00;
}
void wait( unsigned int cycles )
{
int i;
for ( i = 0 ; i < cycles ; i++ ){ }
}
LCD显示左半屏:
LCD是64*128的点阵,通过对LCD显示阵列的分析,由于输入信号的幅度范围是0~1024,故用1024/16,得到1个点阵代表64个幅度值,记为buffer,然后用buffer%8,得到该列的页数,而用buffer/8得到余数就是在页数上的具体点阵位置:
buffer=nADC[j]/16;
m=buffer/8;
n=buffer%8;
LCD显示右半屏:
对数据个数进行判断,若个数大于等于64,则设置起始列的位置为CTRLCDCMDR=LCDCMDVERADDRESS+j-64;
选择显示FFT的频谱图
将采集到的信号进行FFT变换后,得到FFT频谱图
void InitForFFT()
{
int i;
for ( i=0;i<SAMPLENUMBER;i++ )
{
sin_tab[i]=sin(PI*2*i/SAMPLENUMBER);
cos_tab[i]=cos(PI*2*i/SAMPLENUMBER);
}
}
void FFT(float dataR[SAMPLENUMBER],float dataI[SAMPLENUMBER])
得到的FFT频谱图,送入LCD显示,显示方法同ADC-LCD显示。

3.3程序代码:
#include "myapp.h"
#include "ICETEK-VC5509-EDU.h"
#include "scancode.h"
#include <math.h>
#define PI 3.1415926
#define SAMPLENUMBER 128
#define LCDDELAY 1
void InitForFFT();
void lcd();
//int INPUT[SAMPLENUMBER];
int DATA[SAMPLENUMBER];
float
fWaveR[SAMPLENUMBER],fWaveI[SAMPLENUMBER],w[SAMPLENUMBER]; float sin_tab[SAMPLENUMBER],cos_tab[SAMPLENUMBER];
void InitForFFT();
void FFT(float dataR[SAMPLENUMBER],float dataI[SAMPLENUMBER]);
void InitADC();
unsigned int nADC[128];
main()
{
int j;
unsigned int uWork;
int i;
InitForFFT();
CLK_init();
SDRAM_init();
InitCTR();
// CloseCTR();
SetDSPPLL(SPEED144MHz);
TurnOnLCD(); // 打开显示屏
LCDCLS(); // 清除显示内存
while ( 1 )
{
//AD
for ( j=0;j<128;j++ ) //采集128个数据
{
ADCCTL=0x8000; // 启动AD转换,通道0
do
{
uWork=ADCDATA;
} while ( uWork&0x8000 );
nADC[j]=uWork&0x0fff;
}
LCDCLS(); // 清除显示内存
LCDCLS();
lcd();
for ( i=0;i<SAMPLENUMBER;i++ )
{
fWaveR[i]=nADC[i];
fWaveI[i]=0.0f;
w[i]=0.0f;
}
FFT(fWaveR,fWaveI); //对采集到的数据进行FFT处理
for ( i=0;i<SAMPLENUMBER;i++ )
{
DATA[i]=w[i];
}
asm( " nop");
}
}
void FFT(float dataR[SAMPLENUMBER],float dataI[SAMPLENUMBER])
//FFT处理函数
{
int x0,x1,x2,x3,x4,x5,x6,xx;
int i,j,k,b,p,L;
float TR,TI,temp;
for ( i=0;i<SAMPLENUMBER;i++ )
{
x0=x1=x2=x3=x4=x5=x6=0;
x0=i&0x01; x1=(i/2)&0x01; x2=(i/4)&0x01; x3=(i/8)&0x01;x4=(i/16)&0x01; x5=(i/32)&0x01; x6=(i/64)&0x01;
xx=x0*64+x1*32+x2*16+x3*8+x4*4+x5*2+x6;
dataI[xx]=dataR[i];
}
for ( i=0;i<SAMPLENUMBER;i++ )
{
dataR[i]=dataI[i]; dataI[i]=0;
}
for ( L=1;L<=7;L++ )
{ /* for(1) */
b=1; i=L-1;
while ( i>0 )
{
b=b*2; i--;
} /* b= 2^(L-1) */
for ( j=0;j<=b-1;j++ ) /* for (2) */
{
p=1; i=7-L;
while ( i>0 ) /* p=pow(2,7-L)*j; */
{
p=p*2; i--;
}
p=p*j;
for ( k=j;k<128;k=k+2*b ) /* for (3) */
{
TR=dataR[k]; TI=dataI[k]; temp=dataR[k+b];
dataR[k]=dataR[k]+dataR[k+b]*cos_tab[p]+dataI[k+b]*sin_tab[p];
dataI[k]=dataI[k]-dataR[k+b]*sin_tab[p]+dataI[k+b]*cos_tab[p];
dataR[k+b]=TR-dataR[k+b]*cos_tab[p]-dataI[k+b]*sin_tab[p];
dataI[k+b]=TI+temp*sin_tab[p]-dataI[k+b]*cos_tab[p];
} /* END for (3) */
} /* END for (2) */
} /* END for (1) */
for ( i=0;i<SAMPLENUMBER/2;i++ )
{
w[i]=sqrt(dataR[i]*dataR[i]+dataI[i]*dataI[i]);
}
}
void InitForFFT()
{
int i;
for ( i=0;i<SAMPLENUMBER;i++ )
{
sin_tab[i]=sin(PI*2*i/SAMPLENUMBER);
cos_tab[i]=cos(PI*2*i/SAMPLENUMBER);
}
}
void InitADC()
{
ADCCLKCTL=0x23; // 4MHz ADCLK
ADCCLKDIV=0x4f00;
}
void lcd() //LCD显示函数
{
int j,buffer,m,n;
CTRLCDCMDR=LCDCMDSTARTLINE; // 设置显示起始行
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for (j=0;j<128;j++) //对128列数据进行显示
{
buffer=nADC[j]/16; //得到以16压缩后的信号幅值
m=buffer/8; //得到页数
n=buffer%8; //余数为具体页数内的点阵位置
if(j<64)
{
CTRLCDCMDR=LCDCMDVERADDRESS+j; // 起始列=0
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDCMDR=LCDCMDPAGE+7-m; // 设置操作页=0
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDLCR=ledkey[0][n]; //页内的点阵位置
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
Delay(512);
}
else
{
CTRLCDCMDR=LCDCMDVERADDRESS+j-64; // 起始列=0
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDCMDR=LCDCMDPAGE+7-m; // 设置操作页=0
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDRCR=ledkey[0][n];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
Delay(512);
}
}
}
void LCDCLS() //刷新清屏函数
{
int i,j;
LCDCMD(LCDCMDSTARTLINE);
for ( i=0;i<8;i++ )
{
LCDCMD(LCDCMDPAGE+i);
LCDCMD(LCDCMDVERADDRESS);
for ( j=0;j<64;j++ )
{
LCDWriteLeft(0); //左半屏刷新
Delay(1);
}
LCDCMD(LCDCMDPAGE+i);
LCDCMD(LCDCMDVERADDRESS);
for ( j=0;j<64;j++ )
{
LCDWriteRight(0); //右半屏刷新
Delay(1);
}
}
}
- 11 -。

相关文档
最新文档