一、C54x的片内定时器是一个可编程的定时器,同时可以用于周期性地产生中断,为16位计数器。定时器主要由定时器寄存器TIM、定时周期寄存器PRD、定时控制寄存器TCR(包括分频系数TDDR、预标定计数器PSC、控制位TRB和TSS等)及相应的逻辑控制电路组成。TIM是一个减1计数器,PRD用来存放定时时间常数(TIM寄存器的初值)。
TCR中包括定时器的控制位和状态位,具体如下:
对于上图中的各控制位的功能描述如下:
TDDR:定时器的分频系数,最大预标定值为16,最小为1。用此分频系数对CLKOUT进行分频,以改变定时周期。当PSC(该计数器存放的初值等于TDDR的值)减到0时,用TDDR的值加载到PSC。
TSS:定时器停止状态位,用于启动和停止定时器。TSS为0时定时器启动,TSS为1时定时器停止。
TRB:定时器重新加载位,用于复位片内定时器。TRB为1时,用PRD中的值加载TIM,以及TDDR中的值加载PSC。
PSC:定时器预标定计数器,其标定值为0到16(TDDR的值的范围),当PSC的值减为0时,TDDR的值加载到PSC,TIM减1。
FREE和SOFT:SOFT和FREE为00时定时器立即停止工作;SOFT和FREE为10时,定时器当减为0时停止工作;SOFT为任意值而FREE为1时,定时器继续工作。
二、PLL乘数(锁相环)
锁相环PLL具有频率放大和时钟信号的提纯作用,利用PLL可以为芯片提供高稳定频率的时钟信号,同时还可以对外部时钟频率进行倍频,例如外部时钟为10Mhz,DSP时钟频率为25Mhz,则PLL=25/10 = 2.5。PLL的设置受时钟方式寄存器CLKMD控制,其寄存器内容如下:
对于上面的寄存器设置,下面举几个例子:
若设置为PLL X 1方式,则CLKMD设置为0X03EFH,若设置为PLL X 4方式,则CLKMD设置为0X43EFH,也就是说若设置为PLL X a方式(a为整数),则LCKMD设置为0X(a - 1)3EFH;若设置的PLL乘数为小数,如PLL X 2.5方式(一位小数),则CLKMD设置为0X4BEFH(将十六进制形式的最高位设置为2.5*2 - 1即4,次高位为B则可设置为小数形式的乘数;若设置为PLL X 1.25(两位小数),将CLKMD设置为0X5BEFH(将十六进制的最高位设置为1.25*4即5,次高位设置为B),其他同理。
三、定时器的工作工程
定时器的工作过程是将定时分频系数TDDR和周期PRD分别加载到TCR和PRD寄存器中(TDDR和PRD由计算得出),定时器的基准工作脉冲由CLKOUT(DSP时钟
定时周期 = CLKOUT * ( TDDR +1 ) * ( PRD + 1 )
通过对定时周期的确定,再代入公式即可计算出TDDR和PRD(均为整数,其中TDDR取值为0到15,PRD取值为0到65535)。
四、C54X型DSP芯片定时器使用举例(汇编实现)
DSP的XF端外接LED,利用定时器中断实现LED以每1s的频率闪烁。(DSP的时钟频率为10Mhz,PLL X 1方式)。
关于上述的问题,具体流程是先对堆栈进行设置(堆栈指针SP的设置),接着是PLL设置(CLKMD),再接着是中断向量表指针的设置(IPTR,PMST的高9位),还有就是定时器的设置(TCR、PRD)和定时中断的设置(IFR、IMR),最后是等待中断进入中断服务函数。
对于TDDR和PRD的计算,首先确定了定时周期为0.5s,代入公式发现(PRD + 1) * (TDDR + 1)最大为65536*16,此时该值并不满足T定时/TCLKOUT的值5*10的6次方。这是通过一次中断尝试去实现XF的值的翻转,但无法实现目的。为了实现目的,可通过更多次中断如10次来实现XF的值的翻转,从而定时周期就缩短到了0.05s,这时可以设TDDR为9,则PRD为4999.
主程序:
.mmregs //声明寄存器
.global start //声明全局
.global TINT_ISR
.bss XF_Flag,1 //XF为设置
.bss count,1 //计数变量设置
stack .uset "STACK",10H
.text
start: STM #stack+10H,SP
STM #0,CLKMD
STM #9,AR1
status:LDM CLKMD,A
AND #01H,A
BC status,ANEQ
STM #03EFH,CLKMD //PLL * 1
LDM PMST,A
AND #7FH,A //清零高九位
OR #0080H,A //高九位放入累加器A
STLM A,PMST
STM #10H,TCR
STM #4999,PRD //分频系数设置
STM #29H,TCR //周期数设置
STM #0008H,IFR
STM #0008H,IMR
RSBX INTM
end: B, end //相当while(1),等待中断
TINT_ISR:
PSHM,ST0
BANZ NEXT,*AR1- //AR1不为0时跳转到NEXT
STM #9,AR1 //计数10次
STM #XF_Flag,AR2
BITF *AR2,#01H
BC S01,NTC
RSBX XF //XF端置为0
ST #0,*AR2 //XF状态设为0
B NEXT
S01: SSBX XF //XF端置为1
ST #1,*AR2 //XF状态设为1
NEXT: POPM ST0
RETE