汇编 定时器DSPWord格式文档下载.docx
《汇编 定时器DSPWord格式文档下载.docx》由会员分享,可在线阅读,更多相关《汇编 定时器DSPWord格式文档下载.docx(20页珍藏版)》请在冰点文库上搜索。
如果是可屏蔽中断,响应必须满足某些条件。
如果是不可屏蔽中断,则CPU立即响应。
(3)准备进入中断服务子程序。
CPU要执行的主要任务有:
●完成当前指令的执行,并冲掉流水线上还未解码的指令
●自动将某些必要的寄存器的值保存到数据堆栈和系统堆栈
●从用户实现设置好的向量地址获取中断向量,该中断向量指向中断服务子程序
(4)执行中断服务子程序。
CPU执行用户编写的ISR。
ISR以一条中断返回指令结束,自动恢复步骤(3)中自动保存的寄存器值。
3.4中断向量表
4.汇编程序
4.1链接命令文件
TMS320C55x链接器有两个功能强大的指令,即MEMORY和SECTIONS。
MEMORY指令允许用户定义一个目标系统的存储器映射,可以命名存储器的各个部分,并且指定开始地址和大小。
SECTIONS指令告诉链接器合成输入段为输出段,并且告诉链接器把这些输出段放在存储器的某个位置。
4.2中断向量表及中断程序
a)程序中应包含中断向量表,VC5509A默认向量表从程序区0地址开始存放,根据IPVD和IPVH的值确定向量表的实际地址。
b)向量表中每项为8个字,存放一个跳转指令,跳转指令中的地址为相应服务程序入口地址。
第一个向量表的首项为复位向量,即CPU复位操作完成后自动进入执行的程序入口。
c)服务程序在服务操作完成后,清除相应中断标志,返回,完成一次中断服务。
4.3汇编源程序(见后)
二.寄存器配置
1.时钟模式寄存器(CLKMD),I/O端口地址0x1c00
MOV#0x5467,PORT(#CLKMD);
0101010001100111
工作在锁定模式下,输出时钟频率如下:
PLLMULT/PLLDIV*输入频率=20*20M=400M;
具体配置如下黑体部分:
位
字段
说明
15
Rsvd
保留
14
IAI
退出Idle状态后,决定PLL是否重新锁定
0PLL将使用与进入Idle状态之前相同的设置进行锁定
1PLL将重新锁定过程
13
IOB
处理失锁
0时钟发生器不中断PLL,PLL继续输出时钟
1时钟发生器切换到旁路模式,重新开始PLL锁相过程
12
TEST
必须保持为0
11~7
PLLMULT
锁定模式下的PLL倍频值,0~31(10100)
6~5
PLLDIV
锁定模式下的PLL分频值,0~3(01)
4
PLLENABLE
使能或关闭PLL
0关闭PLL,进入旁路模式
1使能PLL,进入锁定模式
3~2
BYPASSDIV
旁路下的分频值
00一分频
01二分频
10或11四分频
1
BREAKLN
PLL失锁标志
0PLL已经失锁
1锁定状态或有对CLKMD寄存器的写操作
LOCK
锁定模式标志
0时钟发生器处于旁路模式
1时钟发生器处于锁定模式
2.定时器包括4个寄存器
2.1定时器预定标寄存器PRSC
MOV#0x0002,PORT(#PRSC0);
0000000000000010
数值
15~10
—
9~6
PSC
0h~Fh
预定标计数寄存器
5~4
3~0
TDDR
当PSC重新装入时,将TDDR的内容复制到PSC中
2.2主计数寄存器TIM
MOV#0x0000,PORT(#TIM0);
15~0
TIM
0000h~FFFFh
主计数寄存器
2.3主周期寄存器PRD
MOV#0x1fff,PORT(#PRD0);
0001111111111111
PRD0=0X1FFF;
TDDR=0X0010;
中断信号频率:
内部时钟频率:
400M
TINT频率=400M/(8M*5)=10hz;
改变该寄存器的初始值,可以改变灯亮灭快慢。
PRD
主周期寄存器。
当TIM必须重新装入时,将PRD的内容复制到TIM中
2.4定时器控制寄存器TCR
设置定时器寄存器前,关闭定时器
MOV#0x04f0,PORT(#TCR0);
0000010011110000
设置完成后,开启定时器
MOV#0x00e0,PORT(#TCR0);
0000000011100000
IDLEEN
定时器的Idle使能位。
定时器不能进入idle状态
如果idle状态寄存器中的PERIS=1,定时器进入idle状态
INTEXT
时钟源从内部切换到外部标志位
定时器没有准备好使用外部时钟源
定时器准备使用外部时钟源
ERRTIM
定时器错误标志
没有监测到错误,或ERRTIM已被读取
出错
12~11
FUNC
FUNC=00b
FUNC=01b
FUNC=10b
FUNC=11b
定时器工作模式选择位
TIN/TOUT为高阻态,时钟源是内部CPU时钟
TIN/TOUT为定时器输出,时钟源是内部CPU时钟
TIN/TOUT为通用输出,引脚电平反映的是DATOUT位的值
TIN/TOUT为定时器输入,时钟源是外部时钟
10
TLB
定时器装载位
TIM、PSC不重新装载
将PRD、TDDR分别复制到TIM、PSC中
9
SOFT
在调试中遇到断点时定时器的处理方法
8
FREE
7~6
PWID
00
01
11
定时器输出脉冲的宽度
1个CPU时钟周期
2个CPU时钟周期
4个CPU时钟周期
8个CPU时钟周期
5
ARB
自动重装控制位
ARB清0
每次TIM减为0,PRD装入TIM中,TDDR装入PSC中
TSS
定时器停止状态位
启动定时器
停止定时器
3
C/P
定时器输出时钟/脉冲模式选择
输出脉冲。
脉冲宽度由PWID定义,极性由POLAR定义
输出时钟。
引脚上信号的占空比为50%。
2
POLAR
时钟输出极性位
正极性
负极性
DATOUT
当TIN/TOUT作为通用输出引脚,该位控制引脚上的电平
低电平
高电平
3.中断相关寄存器
定时器中断属于可屏蔽中断需要设置以下寄存器:
因为采用定时器0中断,中断向量地址0x20h;
5000系列dsp的中断向量可以重新定位。
但是它只能被重新定位Page0范围内的任何空间;
(在cmd文件中给出)
3.1IVPD(dsp向量的中断向量指针)
3.2IVPH(主机向量的中断向量指针)
3.3IER0(中断使能寄存器)
3.4IEF0(中断标志寄存器)
3.5DBIER0(调试中断寄存器)
汇编指令:
MOV#0x0d00,mmap(IVPD)
MOV#0x0d00,mmap(IVPH)
MOV#0x10,mmap(IER0)
MOV#0x10,mmap(DBIER0)
MOV#0xffff,mmap(IFR0);
中断标志寄存器清零
三.应用举例
本实验要实现的功能是:
在定时器中断到来时,改变实验板上led灯的亮灭状态,同时,在中断服务程序中,设置了一个变量,可以控制亮灭的时间长短。
实现过程:
(1)对处理器及一些寄存器的初始化,包括时钟,定时器,中断等
.defstart
.globalldbs
.globalncount
lbds.set0x400001
TIM0.set0x1000
PRD0.set0x1001
TCR0.set0x1002
PRSC0.set0x1003
CLKMD.set0x1c00;
时钟控制器地址
;
自定义
ncount.usect"
vars"
1
.sect"
TimerStart"
start:
;
处理器初始化
BCLRC54CM
BCLRAR0LC
BCLRAR1LC
BCLRAR2LC
.C54CM_off
BCLRARMS
.ARMS_off
ncount初始化
MOV#0,*(#ncount)
灯亮初始状态
AMAR*(#lbds),XAR3
MOV#0,*AR3
BSETINTM
InitializationofInterrupt
MOV#0X0d00,mmap(IVPD)
MOV#0x0010,mmap(IER0)
MOV#0x0010,mmap(DBIER0)
MOV#0xffff,mmap(IFR0)
InitializationofClk
MOV#05467h,PORT(#CLKMD)
InitializationofTimer0
MOV#0x04f0,PORT(#TCR0)
MOV#0x0000,PORT(#TIM0)
MOV#0x1fff,PORT(#PRD0)
MOV#0x0002,PORT(#PRSC0)
MOV#0x00e0,PORT(#TCR0)
loop:
Bloop
.end
(2)中断服务程序的编写。
本实验只是简单地通过定时器定时长短来控制led灯的亮灭时间。
在中断程序中主要完成对led等的控制,为了增加可视性,在中断程序中通过一个计数器来延长led的亮灭变化。
具体程序编写如下:
TINT0_Isr:
ncount++
MOV*(#ncount),AR0
ADD#1,AR0
nCount%=16
MOV#16,AR1;
改变该数,可以控制灯亮灭快慢
RPT#(16-1)
SUBC*AR1,AC0,AC0
MOVHI(AC0),*AR3;
AR3-->
余数
BCCTINT0_Isr_end,AR3==#0
L1:
BCLRINTM;
开中断
NOP
RETI
TINT0_Isr_end:
AMAR*(#400001h),XAR3
XOR#1,*AR3
MOV#0,*(#ncount);
商
BL1
(3)cmd文件的编写,完成对目标存储器结构的定位和各控制段的构成和地址分配。
本实验中timer.cmd文件具体安排如下:
main.obj
-otimer.out
-mtimer.map
MEMORY
{
DARAM:
o=0x100,l=0x07f00/*On-chipDRAM*/
SARAM:
o=0x10000,l=0x30000/*On-chipSRAM*/
VECT:
o=0x0d000,l=0x100
}
SECTIONS
.vars:
{}>
DARAM
.vectors:
VECT
TimerInit:
SARAM
TimerStart:
在上面介绍原理及寄存器时,已经把该程序的具体硬件结构和寄存器配置详细说明,在此就不在赘述。
实验程序流程图如下:
四.系统演示及调试
4.1实验调试及结果
●指示灯在定时器的定时中断中按照设计定时闪烁。
通过改变ncount以及定时器的定时时间可以控制闪烁。
●在对程序编译时,总出现“Remarks”错误,这是CCS中最轻级别的提示,不影响程序的正常运行。
●在汇编语言中写入.mmregs语句后,就可以省去对存储器映射寄存器的定义,而且在TI的文档中也有寄存器名和对应地址的表,用的时候直接用即可。
●出现如下错误:
Illegaldirectiveormnemonic(非法指令)
●汇编指令不能直接顶头写,需要与行首有一定间隔。
●用途1:
使用定时器和中断服务程序可以完成许多需要定时完成的任务,比如DSP定时启动A/D转换,日常生活中的计时器计数、空调的定时启动和关闭等。
●用途2:
在调试程序时,有时需要指示程序工作的状态,可以利用指示灯的闪烁来达到,指示灯灵活的闪烁方式可表达多种状态信息。
4.2对实验的扩展
●SIN信号发生器的实现
1)采用查表法,从AD输出任意幅度,任意频率的正弦波与余弦波。
在中断中,写查表变换函数:
C程序如下:
(中断服务程序)
uiData=SIN_Table[Table_Index];
//读表
uiData=uiData<
<
6;
//移位
*P_DAC1=uiData&
0xffc0;
Table_Index+=uiStep;
//加上步进值
if(Table_Index>
=256)Table_Index-=256;
//索引溢出
*P_INT_Clear=0x0400;
//清中断标志
2)正弦表的产生
●数的定标
许多DSP芯片只支持整数运算,如果现在这些芯片上进行小数运算的话,定点小数运算应该是最佳选择了,此外即使芯片支持浮点数,定点小数运算也是最佳的速度选择。
在DSP世界中,由于DSP芯片的限制,经常使用定点小数运算。
所谓定点小数,实际上就是用整数来进行小数运算。
下面先介绍定点小数的一些理论知识,然后以C语言为例,介绍一下定点小数运算的方法。
在TIC5000DSP系列中使用16比特为最小的储存单位,所以我们就用16比特的整数来进行定点小数运算。
现在进入二进制。
我们的定点小数用16位二进制表达,最高位是符号位,那么有效位就是15位。
小数点之后可以有0-15位。
我们把小数点之后有n位叫做Qn,例如小数点之后有12位叫做Q12格式的定点小数,而Q0就是我们所说的整数。
Q12的正数的最大值是0111.111111111111,第一个0是符号位,后面的数都是1,那么这个数是十进制的多少呢,很好运算,就是0x7fff/2^12=7.999755859375。
对于Qn格式的定点小数的表达的数值就它的整数值除以2^n。
在计算机中还是以整数来运算,我们把它想象成实际所表达的值的时候,进行这个运算。
反过来把一个实际所要表达的值x转换Qn型的定点小数的时候,就是x*2^n了。
例如0.2的Q12型定点小数为:
0.2*2^12=819.2,由于这个数要用整数储存,所以是819即0x0333。
因为舍弃了小数部分,所以0x0333不是精确的0.2,实际上它是819/2^12=0.199********5。
●下面是MATLAB产生cos表的过程:
>
pi=3.1415926;
aa=1:
256;
bb=cos(pi/256*aa);
BB=[1,bb];
CC=BB*2^15;
%共257个数据Q15
将MATLAB产生的数据导出,存放在SIN_Table中。
3)DA转换原理
利用专用的数模转换芯片,可以实现将数字信号转换成模拟量输出的功能。
在ICETEK–VC5509-A板上,使用的是TLV7528数模芯片,它可以实现同时转换四路模拟信号输出,并有10位精度,转换时间0.1μs。
其控制方式较为简单:
首先将需要转换的数值通过数据
总线传送到TLV7528上相应寄存器,再发送转换信号,经过一个时间延迟,转换后的模拟量就从TLV7528输出引脚输出。
2.TLV7528与TMS320VC5509A的连接:
由于TMS320VC5509ADSP没有数模转换输出设备,采用外扩数模转换芯片的方法。
在ICETEK–VC5509-A板上选用的是TLV7528。
TLV7528的转换寄存器被映射到了DSP的I/O空间,地址是0-3,控制转换由I/O端口4的写信号控制,这部分在硬件上由译码电路(GAL芯片)完成。
在TLV7528的输出端,为了增加输出功率,经过一级运放再输出到板上插座上。
4)汇编程序大致编写步骤如下:
(1)变量初始化
.refSIN_Table
DA_DATA_1.set0x400006
Table_Index.int1
uiStep.int1
(2)中断服务程序
TimerInit"
.refindex;
在main中定义,在该模块中使用的变量
.defTINT0_Isr;
定义中断程序标识,方便其它模块(中断向量表)调用
.refCOSOFF
.refuiStep
MOV*(#index),AR0;
更新index
ADD#uiStep,AR0
MOVAR0,T0
AMAR*(#0x400006),XAR3;
启动da转换
MOVT0,*AR3;
取表中数送到da口
AND#0X100,AR3;
判断索引溢出
BCCTINT0_Isr_end,AR3==#0
MOV#0,*(#uiStep);
索引溢出,清零
上述程序由于时间原因,暂时写到这里,在不断改进中。
5)预期实验结果可通过示波器或模拟示波器观察: