DSP实验指导.docx
《DSP实验指导.docx》由会员分享,可在线阅读,更多相关《DSP实验指导.docx(15页珍藏版)》请在冰豆网上搜索。
DSP实验指导
DSP实验报告
在打开实验箱电源的前提下:
1、打开CCSStudio3.3
2、选择debug,选择connect,如果在左下角显示connecting,表示与仿真器连接正常。
实验一、存储器实验。
实验目的:
了解F2812的内部存储器空间的分配,掌握外扩RAM或FLASH存储器的方法,掌握从外部存储器写入读取数据的方法。
实验过程:
该实验不用改变硬件,实验内容为在数据存储器的指定地址写上特定数据如0xAAAA,然后将该数据搬移到其他位置。
源程序:
(example_dsp281x_mem.c)
voidmain(void)
{
inti;
volatileunsignedint*room=(volatileunsignedint*)0x3f9020;
volatileunsignedint*room2=(volatileunsignedint*)0x3f902F;
建立可变数据类型的两个指针,指向两个地址。
//InitializeSystemControl:
//PLL,WatchDog,enablePeripheralClocks
InitSysCtrl();
对看门狗,系统等进行初始化
//DisableCPUinterrupts
DINT;
禁止中断
//DisableCPUinterruptsandclearallCPUinterruptflags:
IER=0x0000;
禁止中断
IFR=0x0000;
清所有中断标记。
/*将0xAAAA写入从数据空间的地址0x3f9020开始的8个单元中*/
for(i=0;i<8;i++)
{
*room=0xAAAA;
room指针的地址内填上0xAAAA
room++;
}
/*从0x3f9020开始的8个空间读出数据依次写入从0x3f9028开始的8个单元中*/
for(i=0;i<8;i++)
{
*room2=*(room-1);
将room指针减一,然后将其内容填到room2指针的地址内。
room--;
room2--;
}
}
InitSysCtrl()函数,在DSP281x_SysCtrl.c中定义。
其定义如下:
voidInitSysCtrl(void)
{
//OnF2812/F2810TMXsamplespriortorevCthisinitializationwas
//required.ForRevCandafterthisisnolongerrequired
//Disablethewatchdog
DisableDog();
//InitializethePLLCRto0xA
InitPll(0xa);
//Initializetheperipheralclocks
InitPeripheralClocks();
}
以上程序完成关看门狗,初始化时钟,初始化外设时钟。
(外设时钟是片内外设的时钟,分高速和低速)
———————————————————————————————————————
其中
voidInitPeripheralClocks(void)
{
EALLOW;
//HISPCP/LOSPCPprescaleregistersettings,normallyitwillbesettodefaultvalues
SysCtrlRegs.HISPCP.all=0x0001;
SysCtrlRegs.LOSPCP.all=0x0002;
//Peripheralclockenablessetfortheselectedperipherals.
SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=1;
SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1;
SysCtrlRegs.PCLKCR.bit.SCIBENCLK=1;
SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=1;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;
SysCtrlRegs.PCLKCR.bit.ECANENCLK=1;
SysCtrlRegs.PCLKCR.bit.ADCENCLK=1;
EDIS;
}
以上程序完成外设时钟的设置,寄存器的含义见教材或参考书,其中EALLOW表示开保护,EDIS为启动保护,这些是在寄存器操作时必须的。
其中:
SysCtrlRegs是一个结构体,PCLKCR是一个结构体,bit和All是一个联合体。
——————————————————————————————————————
voidInitPll(Uint16val)
{
volatileUint16iVol;
if(SysCtrlRegs.PLLCR.bit.DIV!
=val)
{
EALLOW;
SysCtrlRegs.PLLCR.bit.DIV=val;
EDIS;
设置PLL时钟,在此后Cpu等待PLL锁死,在PLL没有锁死前,CPU将工作在晶振时钟的0.5倍。
当PLL稳定后,CPU才工作于新频率。
软件可以再PLL锁死前继续运行。
但如果对运行时间要求严的话,可以在此加上等待。
在锁相环稳定前,看门狗是不工作的。
DisableDog();
for(iVol=0;iVol<((131072/2)/12);iVol++)
{
}
等待。
}
}
观看实验结果方法:
1、在CCS环境中,进行编译,选择project中的build。
如果没有错,进行下一步。
2、在file中选择loadprogram。
在文件的目录下寻找对应得.Out文件。
3、在view中选择memory。
选择数据,在对话框中输入0x3f9010。
4、在debug目录下选择run,可观察到数据变化。
实验内容:
通过修改上述源程序,
实现在0x3f9020开始的位置放置8个数,0x3211。
在0x3f902f开始的位置放置8个数,0x1111。
将0x3f9020位置开始的8个数和0x3f902f位置开始放置的8个数相加,放到0x3f9010开始的8个地址中。
实验二拨码开关实验
实验目的:
了解GPIO的初始化原理,掌握GPIO的基本操作,掌握如何设定GPIO为通用数字I/O口或是功能引脚,掌握GPIO的相关寄存器的配置方法。
实验过程:
该程序完成将拨码开关的信息读入DSP,然后再将该信息回写,控制led灯。
关键问题:
读入的地址和输出的地址用的同一个地址。
为什么呢?
其拨码开关是通过74LS244和总线相连,灯是通过74LS273相连总线。
读时将273设为无效,244有效,拨码开关的数据上总线。
写时,244无效,273有效,将数据发送出,同时锁存。
需要3根控制线。
按时序操作。
对于本试验箱来讲,DSP将控制信号发给CPLD,在对一个特定地址进行读写时(0x2200),CPLD内部通过编程,实现对读写信号的不同操作。
在DSP读0x2200时,CPLD将244有效。
当DSP写0x2200时,CPLD将244无效,同时273有效,同时开关锁存一次,同时保持锁存。
主要程序如下:
/*******************************头文件****************************/
#include"DSP281x_Device.h"//DSP281xHeaderfileIncludeFile
#include"DSP281x_Examples.h"//DSP281xExamplesIncludeFile
/****************************主程序*******************************/
voidmain(void)
{
unsignedinttemp;
temp=0;
InitSysCtrl();//初始化PLL,WatchDog,使能外围时钟,该初始化文件在"DSP281x_SysCtrl.c"中
DINT;//关闭CPU中断
//InitializePIEcontrolregisterstotheirdefaultstate.
//ThedefaultstateisallPIEinterruptsdisabledandflags
//arecleared.
InitPieCtrl();
IER=0x0000;//关闭中断和清除所有中断标志
IFR=0x0000;
//InitializethePIEvectortablewithpointerstotheshellInterrupt
//ServiceRoutines(ISR).
InitPieVectTable();
for(;;)
{
asm("nop");
temp=*(int*)0x2200&0x00ff;//读入0x2200地址的开关量值并赋给temp
asm("nop");
*(int*)0x2200=temp;//temp值输出0x2200地址的LED灯
asm("nop");
}
}
其中InitPieVectTable()在文件DSP281x_PieVect.c中。
voidInitPieVectTable(void)
{
int16i;
Uint32*Source=(void*)&PieVectTableInit;
在这里取PieVectableInit的地址,
Uint32*Dest=(void*)&PieVectTable;
在这里取PieVectTable的地址
他们都应该是全局变量。
EALLOW;
for(i=0;i<128;i++)
*Dest++=*Source++;
EDIS;
//EnablethePIEVectorTable
PieCtrlRegs.PIECRTL.bit.ENPIE=1;
变量pieVectTableInit在文件DSP281x_PieVect.c中。
PieVectTable在DSP281x_PieVect.h中定义,在最后2行。
他们的具体地址可以由.cmd文件来确定。
实验内容:
通过修改以上程序实现1号开关动作时,2号灯亮,2号开关动作时,3号灯亮,*****,等。
在第8号开关动作时,第1号灯亮。
需要判断是高电平亮,还是低电平亮,可以使用中断调试。
在运行状态,在需要设置断点的位置的右边,双击,就可以产生红点。
表明设置了断点。
在view目录下,打开watchwindow,输入需要观察的变量,就可看到其变化,然后,在debug目录下点run,在断点处,程序会停下来,可以观察temp变量来判断。
实验三、cpu定时器实验
实验目的:
了解CPU定时器的工作原理,掌握F2812的定时器的控制方法,掌握F2812的中断结构以及对中断的处理流程,学会利用C语言设计中断程序。
实验过程:
该实验以中断的方式,标记定时器中断的次数,根据不同的次数,点亮不同的灯。
原程序如下:
/*************************头文件*********************************/
#include"DSP281x_Device.h"//DSP281xHeaderfileIncludeFile
#include"DSP281x_Examples.h"//DSP281xExamplesIncludeFile
/*************************定义函数说明***************************/
//Prototypestatementsforfunctionsfoundwithinthisfile.
interruptvoidcpu_timer0_isr(void);
voidConfigCpuTimer(structCPUTIMER_VARS*Timer,floatFreq,floatPeriod);
该函数在DSp281x_cputimers.c中定义
CpuTimer0也在该文件中定义。
/*************************主程序*********************************/
CpuTimer0是CPUTIMER_VARS的一个对象,CPUTIMER_VARS是一个结构体。
voidmain(void)
{
InitSysCtrl();
DINT;
关中断
InitPieCtrl();
//DisableCPUinterruptsandclearallCPUinterruptflags:
IER=0x0000;
IFR=0x0000;
//InitializethePIEvectortablewithpointerstotheshellInterrupt
InitPieVectTable();
EALLOW;//ThisisneededtowritetoEALLOWprotectedregisters
PieVectTable.TINT0=&cpu_timer0_isr;
将外设中断向量表中的int0,设置为cpu定时器中断服务程序的地址。
EDIS;//ThisisneededtodisablewritetoEALLOWprotectedregisters
InitCpuTimers();//Forthisexample,onlyinitializetheCpuTimers
//ConfigureCPU-Timer0tointerrupteverysecond:
//100MHzCPUFreq,1secondPeriod(inuSeconds)
ConfigCpuTimer(&CpuTimer0,100,1000000);
StartCpuTimer0();
//EnableCPUINT1whichisconnectedtoCPU-Timer0:
IER|=M_INT1;
//EnableTINT0inthePIE:
Group1interrupt7
PieCtrlRegs.PIEIER1.bit.INTx7=1;
//EnableglobalInterruptsandhigherpriorityreal-timedebugevents:
EINT;//EnableGlobalinterruptINTM
ERTM;//EnableGlobalrealtimeinterruptDBGM
for(;;)
{
if(CpuTimer0.InterruptCount<1)
{
asm("nop");
asm("nop");
*(int*)0x2200=0x0081;
}
elseif(CpuTimer0.InterruptCount<2)
{
asm("nop");
asm("nop");
*(int*)0x2200=0x0042;
}
elseif(CpuTimer0.InterruptCount<3)
{
asm("nop");
asm("nop");
*(int*)0x2200=0x0024;
}
elseif(CpuTimer0.InterruptCount<4)
{
asm("nop");
asm("nop");
*(int*)0x2200=0x0018;
}
elseif(CpuTimer0.InterruptCount<5)
{
asm("nop");
asm("nop");
*(int*)0x2200=0x0024;
}
elseif(CpuTimer0.InterruptCount<6)
{
asm("nop");
asm("nop");
*(int*)0x2200=0x0042;
}
elseif(CpuTimer0.InterruptCount<7)
{
asm("nop");
asm("nop");
*(int*)0x2200=0x0081;
}
else
{
CpuTimer0.InterruptCount=0;
}
}
}
以下为中断服务程序。
interruptvoidcpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
//Acknowledgethisinterrupttoreceivemoreinterruptsfromgroup1
PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;
}
voidInitCpuTimers(void)
{
//CPUTimer0
//Initializeaddresspointerstorespectivetimerregisters:
CpuTimer0.RegsAddr=&CpuTimer0Regs;
CpuTimer0Regs在dsp281x_Cputimers.h中定义。
以下初始化PRD到最大值。
CpuTimer0Regs.PRD.all=0xFFFFFFFF;
设置定时的时钟源的分频系数。
CpuTimer0Regs.TPR.all=0;
CpuTimer0Regs.TPRH.all=0;
以下停止定时器的运行。
CpuTimer0Regs.TCR.bit.TSS=1;
//Reloadallcounterregisterwithperiodvalue:
CpuTimer0Regs.TCR.bit.TRB=1;
//Resetinterruptcounters:
CpuTimer0.InterruptCount=0;}
ConfigCpuTimer(&CpuTimer0,100,1000000)定义在
实验内容:
运行该程序,观察灯的变化。
将定时器时间延时一倍。
进一步实验可以完成奇数灯和偶数灯的轮流点亮。
实验四、AD实验
实验目的:
掌握ADC模块顺序采样的运行模式,掌握ADC模块单序列发生器的运行模式,掌握利用软件置位的方式来实现AD采样。
实验过程:
通过信号发生器,产生方波和正玄波,通过DSP自带AD将数据采集到DSP内,通过CCS自带的graph功能,观察采集来的数据。
1.2812CPU板JUMP1的1和2脚短接,拨码开关SW1的第二位置ON;
2.E300板上的开关SW4的第二位置ON,其余OFF.SW7全部置ON。
其余开关全部置OFF。
3.用导线连接E300底板“Signalexpansionunit”的2号孔接口“SIN”到“Signalexpansionunit”的2号孔“AIN0”;“SQU”到“AIN1”.SIN输出正弦波。
SQU输出方波。
4.运行CodeComposerStudio(CCS3.1);(ccs3.1需要“DEBUG→Connect”)
5.用“Project\Open”打开系统项目文件\e300.test\normal\DSP281x_examples\e300_07_ad\Example_281x_e300_AD.pjt。
6.编译全部文件并装载“Debug\Example_281x_AD.out”文件;
7.在加软件断点处加软件断点。
单击“Debug\RUN”运行程序,程序运行到断
8.用下拉菜单中的View/Graph的“Time/Frequency”打开一个图形观察窗口;设置该图形观察窗口的参数设置如下:
观察起始地址为input1和input2,长度为256的存储器单元内的数据,该数据为输入信号经A/D转换之后的数据,数据类型为16位整型;
9.单击“Debug\Animate”运行程序,在图形观察窗口观察A/D转换后的数据波形变化,
input1:
输入通道AIN1孔的方波,input2:
输入通道AIN0孔的正弦波
单击“Debug\Halt”暂停程序运行。
10.实验结束
程序如下:
/*************************头文件*********************************/
#include"DSP281x_Device.h"//DSP281xHeaderfileIncludeFile
#include"DSP281x_Examples.h"//DSP281xExamplesIncludeFile
//Prototypestatementsforfunctionsfoundwithinthisfile.
interruptvoidadc_isr(void);
采用中断方式来处理AD转换,也就是在AD转换完后可以产生中断,然后由DSP处理。
//Globalvariablesusedinthisexample:
Uint16LoopCount;
Uint16ConversionCount;AD转换的次数
Uint16input1[256];
Uint16input2[256];
Uint16Mixing[256];
voidmain(void)
{
InitSysCtrl();
EALLOW;
SysCtrlRegs.PLLCR.all=0x8;
SysCtrlRegs.HISPCP.all=0x3;//HSPCLK=SYSCLKOUT/6
EDIS;
以上程序将高速外设速度设置为系统时钟的6分之1。
AD采用的是高速外设时钟。
禁止中断
DINT;
初始化外设中断控制器
InitPieCtrl();
禁止中断,同时清中断标记和中断允许。
IER=0x0000;
IFR=0x0000;
初始化外设中断控制器向量表。
InitPieVectTable();
将中断服务程序地址填入中