2.1 定时器基本概念
2.1.1 定时器时钟和时钟源
1)定时器时钟
从图2.1可以看出,当TSS(TIMERxTCR[4])=0时,CPU定时器以系统时钟SYSCLKOUT作为时钟源,此时,预定标计数器(PSCH:PSC)以装载的分频值(TDDRH:TDDR)为基数,对每一个时钟源周期开始减计数。预定标计数器(PSCH:PSC)从分频值(TDDRH:TDDR)减至0时,称为一个定时器节拍(定时器时钟),其表达式如式(2.1)。
定时器节拍的倒数为定时器时钟频率,其表达式如式(2.2)所示。
其中,0≤ (TDDRH:TDDR)≤65535。
预定标计数器(PSCH:PSC)减至0时,重新装入定时器分频值(TDDRH:TDDR),且计数器(TIMH:TIM)以装载的周期值(PRDH:PRD)为基数,对每一个定时器时钟节拍减1计数;当计数器(TIMH:TIM)减至0时,定时器周期值(PRDH:PRD)重新装入计数器(TIMH:TIM)并请求一个中断。
图2.1 CPU定时器
2)定时器时钟源
系统时钟(SYSCLKOUT)与外接晶振频率(OSCCLK)之间的关系受锁相环控制寄存器PLLCR[3:0](即DIV)的控制,其关系式如式(2.3)所示。其中:
(1)PLL禁止与否,是通过上电复位期间采样GPIOF14(XPLLDIS)引脚电平来决定的。在上电复位之前,若把GPIOF14强置为低电平(默认状态下GPIOF14 =1),则PLL禁止;否则PLL使能(参见图2.2)。
(2)在PLL使能的条件下(GPIOF14 =1),当DIV=0时,称为PLL旁路。
(3)在PLL使能的条件下(GPIOF14 =1),当DIV≠0时,称为PLL使能。此时DIV整数值允许范围为1≤DIV ≤0。尽管在理论上DIV最大值可达1111b,但是大于10的值都予以保留。在DIV=10时,外部晶振最大只能选择30MHz。由此可以算出SYSCLKOUT=150MHz。
系统时钟频率:
图2.2明晰地表述了系统时钟的来源。由振荡器及锁相环产生的送至CPU的CLKIN时钟,通过CPU之后直接成为系统输出时钟(SYSCLKOUT),同时作为外设的时钟源,即SYSCLKOUT =CLKIN。
图2.2 振荡器及锁相环模块
2.1.2 定时器寄存器
1.定时器寄存器简介
1)计数寄存器(TIMERxTIM)(其中,x=0,1,2,下同)
32位计数寄存器(TIMH:TIM)中,TIM为计数寄存器低16位,TIMH为计数寄存器高16位。每一个定时器时钟周期(TDDRH:TDDR+1)/ SYSCLKOUT,TIM减1,其中,(TDDRH:TDDR)是定时器预定标分频值。当(TIMH:TIM)减到0时,(TIMH:TIM)重装定时器周期值(PRDH: PRD),同时产生定时器中断。
2)周期寄存器(TIMERxPRD)
32位周期寄存器(PRDH:PRD)中,PRD为周期寄存器低16位,PRDH为周期寄存器高16位。当(TIMH:TIM)减到0时,在下一个定时器输入时钟周期开始时,(TIMH:TIM)将重装(PRDH:PRD)的周期值;或者当定时器控制寄存器(TCR)的TRB置位时,(PRDH:PRD)的周期值也装入(TIMH:TIM)。
3)定时器分频寄存器(TDDRH:TDDR)
16位分频寄存器(TDDRH:TDDR)中,TDDR为分频寄存器低8位,TDDRH为分频寄存器高8位。每过一个定时器时钟周期,定时器计数器寄存器(TIMH:TIM)减1。当预定标器计数器(PSCH:PSC)减到0,一个系统时钟周期后,(TDDRH:TDDR)的值重装(PSCH:PSC),同时(TIMH:TIM)减1。无论何时,用软件置定时器重装位(TRB)为1,(TDDRH:TDDR)重装(PSCH:PSC)。
4)预定标计数器低位及高位寄存器(TIMERxTPR,TIMERxTPRH)
定时器预定标计数器低位及高位寄存器结构及位域定义见图2.3及图2.4,它由16位分频寄存器(TDDRH:TDDR)和16位预定标器计数器(PSCH:PSC)组合而成。
图2.3 定时器预定标计数器低位TIMERxTPR(x=0,1或2)
图2.4 定时器预定标计数器高位TIMERxTPRH(x=0,1或2)
注:R为可读;W为可写;-0为复位后的值
5)控制寄存器(TIMERxTCR)
TCR是一个16位的寄存器,为了便于讨论和查阅,将其位域定义标注在图2.5中。
图2.5 控制寄存器(TIMERxTCR,x=0,1,2)
注:R为可读;W为可写;-0为复位后的值;C为写1清0
6)定时器预定标计数器(PSCH:PSC)
16位预定标计数器(PSCH:PSC)中,PSC为预定标计数器低8位,PSCH为预定标计数器高8位。对每一个系统时钟周期,(PSCH:PSC)减1,(PSCH:PSC)从分频值减到0为一个定时器时钟周期,减到0时(TDDRH:TDDR)装入(PSCH:PSC),且(TIMH:TIM)减1。无论何时,用软件置定时器重装位(TRB)为1,也重装(PSCH:PSC)。该计数器可读,但不可直接设置,复位值为0。
2.CPU定时器列表
CPU定时器0/1/2的配置和控制寄存器列表如表2.1所示。
表2.1 CPU定时器0/1/2的配置和控制寄存器
2.1.3 控制定时器速率的几个因素
1)定时器时钟
定时器时钟源即为系统时钟SYSCLKOUT,改变系统时钟SYSCLKOUT可控制定时器速率。
2)定时器周期值的设置
定时器周期寄存器(PRDH:PRD)的周期值用于重装定时器计数器(TIMH:TIM)。周期值的大小决定了(TIMH:TIM)减1到0的快慢。
3)定时器分频器值的设置
定时器分频器(TDDRH:TDDR)的值起到了对系统时钟分频的作用。当(TDDRH:TDDR)=0时,定时器时钟源时钟直接采用系统时钟,不分频,否则分频为:定时器时钟=SYSCLKOUT/((TDDRH:TDDR)+1),参见式(2.2)。
2.1.4 启动定时器0步骤
在通过InitCpuTimers()函数对定时器0进行初始化(默认状态)之后,按ConfigCpuTimer函数中的步骤进行。
1)CPU定时器0时钟配置
CPU定时器的时钟源与系统时钟SYSCLKOUT同步。因此,对定时器时钟源的配置实际上就是对系统时钟SYSCLKOUT的配置。具体配置可参见DSP281x_ SysCtrl.c文件中的InitPll()函数及式(2.3)。
2)设置定时器分频值
通过ConfigCpuTimer函数中下面的指令设置分频值(TDDRH:TDDR)。
CpuTimer0Regs.TPR.all = 0x0080; //TDDR = 0x 0080 CpuTimer0Regs.TPRH.all = 0x0000; //TDDRH= 0x 0000
以上两个值的低8位构成一个16位分频值(TDDRH:TDDR)。根据式(2.2)的计算可得到定时器时钟。
3)周期寄存器(PRDH:PRD)的设置
这个可通过对ConfigCpuTimer函数中后两个形参float Freq及float Period的设置完成。注意:这里Freq及Period并不表示定时器频率及周期,实际定义是两参数的乘积才是定时器0的周期。
4)使能定时器中断
由于本例采用的是定时器0中断,因此,在ConfigCpuTimer函数中必须添加一条使能定时器中断的指令:
Timer->RegsAddr->TCR.bit.TIE = 1; //使能定时器中断
主程序中通过以下4条指令进行相应的中断配置,详细说明参见主程序。
IER |= M_INT1; //使能连接CPU-Timer 0 的INT1 中断 PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能PIE中的TINT0,1 组第 7 个中断 EINT; //使能全局中断 ERTM; //使能实时中断
之后,计数器(TIMH:TIM)以每一个定时器时钟周期递减,当(TIMH:TIM)减到0时,就会发生一个定时器中断请求。
5)启动CPU定时器0
该步骤通过ConfigCpuTimer函数中的如下指令完成:
StartCpuTimer0();//等价于指令:CpuTimer0Regs.TCR.bit.TSS = 0,立即启动CPU定时器 0