for(j=0;j<1024;j++)
k++;
}
五、实验结果
可以看到D3-D6这4盏指示灯循环移位闪烁。
通过实验可知:
映射在IO空间地址上的指示灯寄存器在设置时是低有效的,数据的最低位(0001B)对应指示灯D3,次低位(0010B)对应D4,...依次类推。
实验二定时器实验
一、实验目的
1.1.通过实验熟悉VC5416A的定时器;
1.2.掌握VC5416A定时器的控制方法;
1.3.掌握VC5416A的中断结构和对中断的处理流程;
1.4.学会C语言中断程序设计,以及运用中断程序控制程序流程。
二、实验原理
2.1.通用定时器介绍及其控制方法
片内定时器是一个软件可编程定时器,可以用来产生周期的中断信号。
定时器主要由3个寄存器所组成:
定时器寄存器(TIM)、定时器周期寄存器(PRD)和定时器控制寄存器(TCR)。
这3个寄存器都有映象寄存器,它们在数据存储器中的地址分别为24H、25H和26H。
TIM是一个递减计数器;PRD中存放计数值;TCR中有定时器的控制位和状态位:
15—12保留
11--10softfree
9—6PSC定时器预定标计数器
5TRB定时器重新加载位,用来复位片内定时器
4TSS定时器停止状态位,用于停止或启动定时器
3—0TDDR定时器分频系数
在正常工作情况下,当TIM减到0后,PRD中的时间常数自动地加载到TIM。
复位后,定时器控制寄存器(TCR)的停止状态位TSS=0,定时器启动工作,时钟信号CLKOUT加到预定标计数器PSC。
PSC也是一个递减计数器,每当复位或其减到0后,自动地将定时器分频系数TDDR加载到PSC。
PSC在CLKOUT作用下,作减1计数。
当PSC减到0,产生一个借位信号,令TIM作减1计数。
TIM减到0后,产生定时器中断信号TINT,传送到CPU和定时器输出引TOUT。
定时器中断的周期为:
CLKOUT×(TDDR+1)×(PRD+1)
其中,CLKOUT位时钟周期,TDDR和PRD分别为定时器的分频系数和时间常数。
对定时器初始化的步骤如下:
⑴先将TCR中的TSS位置1,关闭定时器。
⑵加载PRD。
⑶重新加载TCR(使TDDR初始化;令TSS位=0,以接通CLKOUT;TRB位值1,以使TIM减到0后重新加载定时器时间常数),启动定时器。
-对中断的处理:
⑴设置INTM=1
⑵将IFR中的TINT位置1,清除尚未处理完的定时器中断。
⑶将IMR中的TINT位置1,开放定时器中断。
⑷将ST1中的INTM位请0,开放所有可屏蔽中断。
2.2.TMS320VC5416中断结构
以下是5416的IMR和IFR寄存器的结构,其中包含了可响应的中断:
2.3.中断响应过程
外设事件要引起CPU中断,必须保证:
IMR相应位被使能(置1),ST1寄存器中的INTM使能(置0)。
当CPU响应中断时,PC指针指向中断向量表中对应中断的地址,进入中断服务子程序。
中断向量表是DSP存放中断服务程序的一段内存区域,大小为80H。
在中断向量表中,每一个中断占用4个字的空间,一般情况是将一条跳转或延时跳转指令存放于此。
中断向量表的位置是可以改变的,修改PMST寄存器中的中断向量表基地址可以实现这一点。
2.4.中断程序设计
程序中应包含中断向量表,5416默认向量表从程序区FF80地址开始存放。
向量表中每项为4个字,存放一个跳转指令,跳转指令中的地址为相应服务程序入口地址;第一个向量表的首项为复位向量,即CPU复位操作完成后自动进入执行的程序入口;程序中包含相应的中断服务程序,应将其入口地址加入相应中断向量表中。
2.5.实验程序分析
本实验设计的程序是在上一个实验基础上修改得来,由于上一实验控制指示灯闪烁的延时控制是用循环计算方法得到的,延时不精确也不均匀,采用中断方式可以实现指示灯的定时闪烁,时间更加准确。
对于定时器的周期寄存器为计数f423H,分频系数定为15,即1,000,000个CPU时钟计数一次,由于DSP工作在8MHz主频(ICETEK-VC5416-A板上DIP开关U2的CLKMD1-3均为OFF时),正好是125ms中断一次,所以在中断服务程序中计算中断4次时改变指示灯状态,实现指示灯亮0.5秒再灭0.5秒,即每秒闪烁1次。
实验程序的工程中包含了两种源代码,主程序采用C语言编制利于控制,中断向量表在vector.asm汇编语言文件中,利于直观地控制存储区分配。
在工程中只需将它们添加进来即可,编译系统会自动识别分别处理完成整合工作。
实验程序的C语言主程序中包含了内嵌汇编语句,提供一种在需要更直接控制DSP状态的
方法,同样的方法也能提高C语言部分程序的计算效率。
2.6.程序流程图
主程序流程图中断服务程序流程图如下:
3、实验代码
/////////////////////////////////////////////////
//ExampleForICETEK-VC5416-EDU//
//CTRVersion:
V4//
//Filename:
Timer.c//
//Project:
Timer.pjt//
//Version:
2.00//
//Writeby:
DanielHawk//
//Company:
RealtimedspCo.Ltd//
////
//AllRightsopened&noOnus2005.06//
/////////////////////////////////////////////////
#defineTIM*(int*)0x24
#definePRD*(int*)0x25
#defineTCR*(int*)0x26
#defineIMR*(int*)0x0
#defineIFR*(int*)0x1
#definePMST*(int*)0x1d
ioportunsignedintport3002,port3003;
#defineDIPport3003
#defineLEDport3002
voidinterrupttime(void);
unsignedintnCount,uWork;
main()
{
nCount=uWork=0;
asm("ssbxINTM");
uWork=PMST;
PMST=uWork&0xff;
IMR=0x8;
TCR=0x41F;
TIM=0;
PRD=0x0f423;
TCR=0x42f;
IFR=0x100;
asm("rsbxINTM");
LED=0xff;
while
(1)
{
}
}
voidinterrupttime(void)
{
nCount++;
if(nCount>=4)
{
LED^=0x55;
nCount=0;
}
}
四、代码分析
//宏定义
#defineTIM*(int*)0x24//TIM寄存器在数据存储器中的地址是0x24
#definePRD*(int*)0x25//PRD寄存器在数据存储器中的地址是0x25
#defineTCR*(int*)0x26//TCR寄存器在数据存储器中的地址是0x26
#defineIMR*(int*)0x0//将IMR中的TINT位置1,开放定时器中断
#defineIFR*(int*)0x1//将IFR中的TINT位置1,清除尚未处理完的定时器中断
#definePMST*(int*)0x1d//PMST寄存器中的中断向量表基地址
ioportunsignedintport3002,port3003;//访问I/O端口
#defineDIPport3003//DIP开关的接口为port3003
#defineLEDport3002//LED开关的接口为port3002
voidinterrupttime(void);//中断调用函数申明
unsignedintnCount,uWork;//定时主函数申明
main()
{
nCount=uWork=0;//初始状态
asm("ssbxINTM");//关中断,进行关键设置时不许打扰
//设置通用定时器
uWork=PMST;//设置PMST寄存器
PMST=uWork&0xff;//中断向量表起始地址=80H
IMR=0x8;//使能TINT
TCR=0x41F;//控制字为0000010000011111B,预分频系数为8
TIM=0;//时钟计数器清0
PRD=0x0f423;//周期寄存器为0f423H
TCR=0x42f;//控制字为0000010000101111B,复位片内定时器、启动定时器
IFR=0x100;//清中断标志位
asm("rsbxINTM");//开中断
LED=0xff;
while
(1)
{
}
}
voidinterrupttime(void)//中断调用函数
{
nCount++;//计数
if(nCount>=4)
{
LED^=0x55;//中断4次时设置指示灯状态
nCount=0;
}
}
五、实验结果
-指示灯在定时器的定时中断中按照设计定时闪烁,改变分频计数器和时钟计数器的计数大小可以调整定时长短。
-使用定时器和中断服务程序可以完成许多需要定时完成的任务,比如DSP定时启动A/D转换,日常生活中的计时器计数、空调的定时启动和关闭等。
-在调试程序时,有时需要指示程序工作的状态,可以利用指示灯的闪烁来达到指示灯灵活的闪烁方式可表达多种状态信息。
实验三AD实验
一、实验目的
1.1掌握ADC芯片的使用方法
1.2掌握DSP控制ADC芯片以及通过端口采集数据的方法
1.3利用定时器中断控制采样的间隔
二、实验原理
2.1.TLV0832模数转换模块特性
带内置采样和保持的8位模数转换模块ADC,最小转换时间为500us。
2个的模拟输入通道(ADIN2—ADIN3)。
2.2.模数转换工作过程
模数转换模块接到启动转换信号后,开始转换第一个通道的数据;经过一个采样时间的延迟后,将采样结果放入转换结果寄存器保存;转换结束,设置标志,也可发出中断;如果为连续转换方式则从新开始转换过程;否则等待下一个启动信号。
2.3.模数转换的程序控制
模数转换相对于计算机来说是一个较为缓慢的过程。
一般采用中断方式启动转换或保存结果,这样在CPU忙于其他工作时可以少占用处理时间。
设计转换程序应首先考虑处理过程如何与模数转换的时间相匹配,根据实际需要选择适当的触发转换的手段,也要能及时地保存结果。
由于TLV0832芯片内的A/D转换精度是8位的,转换结果为16位数据,中间8位是有效值,所以应将读回的数据右移4位后再将高8位清零。
2.4.程序流程图
注意:
TCR中有定时器的控制位和状态位:
15—12保留
11--10softfree
9—6PSC定时器预定标计数器
5TRB定时器重新加载位,用来复位片内定时器
4TSS定时器停止状态位,用于停止或启动定时器
3—0TDDR定时器分频系数
以下是5416的IMR和IFR寄存器的结构,其中包含了可响应的中断:
三、实验代码
///////////////////////////////////////////////////
//ExampleForICETEK-VC5416-EDU//
//CTRVersion:
V4//
//Filename:
ADC.c//
//Project:
ADC.pjt//
//Version:
2.00//
//Writeby:
DanielHawk//
//Company:
RealtimedspCo.Ltd//
////
//AllRightsopened&noOnus2005.06//
///////////////////////////////////////////////////
#include"c5416regs.h"
#defineTIM*(int*)0x24
#definePRD*(int*)0x25
#defineTCR*(int*)0x26
#defineREGISTERCLKMD*(int*)0x58
ioportunsignedintport3006;
voidinterrupttime(void);
voidinitMcBSP2(void);
unsignedintnCount;
intflage;
intuWork;
intinp[256];
intlength;
intchannel;
main()
{
intj;
asm("ssbxINTM");
*(int*)0x58=0x0;
j=PMST;
PMST=j&0xff;
IMR=0x8;
TCR=0x417;
TIM=8;
PRD=0x157;
TCR=0x427;
IFR=0x100;
flage=0;
channel=0;
port3006=1;
*(int*)0x58=0x2004;
initMcBSP2();
asm("rsbxINTM");
while
(1);
}
//定时器中断服务程序,完成:
保存转换结果、启动下次转换
voidinterrupttime(void)
{
if(channel)
{
DXR12=0xe000;
}
else
{
DXR12=0xc000;
}
/*DXR12=0xe000;*/
uWork=DRR12;
uWork=uWork>>4;
uWork&=0xff;
inp[length]=uWork;
length++;
length%=256;
if(length==0)
{
asm("nop");
}
}
voidinitMcBSP2(void)/*configuationtheMcBSP1asSPImode*/
{
SPSA2=SPCR1;
SPSD2=0;
SPSA2=SPCR2;
SPSD2=0;
SPSA2=RCR1;
SPSD2=0x40;
SPSA2=RCR2;
SPSD2=0x01;
SPSA2=XCR1;
SPSD2=0x40;
SPSA2=XCR2;
SPSD2=0x01;
SPSA2=SRGR1;
SPSD2=0x83;
SPSA2=SRGR2;
SPSD2=0x2000;
SPSA2=PCR;
SPSD2=0xA08;
SPSA2=SPCR1;
SPSD2=0x5801;
SPSA2=SPCR2;
SPSD2=0xc1;
}
4、代码分析
#include"c5416regs.h"//使用工具包c5416regs.h
//宏定义
#defineTIM*(int*)0x24//TIM寄存器在数据存储器中的地址是0x24
#definePRD*(int*)0x25//PRD寄存器在数据存储器中的地址是0x25
#defineTCR*(int*)0x26//TCR寄存器在数据存储器中的地址是0x26
#defineREGISTERCLKMD*(int*)0x58//REGISTERCLKMD存放在地址0x58中
//I/O接口接入
ioportunsignedintport3006;
voidinterrupttime(void);//中断调用函数申明
voidinitMcBSP2(void);
unsignedintnCount;
intflage;
intuWork;
intinp[256];/