DSP TMS320F2812芯片内部有3个32位的CPU定时器-Timer0、Timer1、Timer2,其中CPU定时器1,2被系统保留,定时器0供用户使用。
定时器工作原理说明
CPU定时器的工作原理如下图所示
所包含的寄存器主要有
预定标寄存器TPR、
计数器寄存器TIM、
周期寄存器PRD、
控制寄存器TCR;前3个寄存器都是16位的,因此用2个寄存器来表示32位,表示为XXXH:XXX。其中TPR寄存器中又分为分频器TDDR和PSC,分别占据TPR的高8位和低8位。而TDDRH和PSCH分别占据TPRH的高8位和低8位。
- 预定标计数器PSC:PSCH:PSC,采用两个8位表示16位,PSC为TPR寄存器的低8位,PSCH为TPRH寄存器的低8位。每隔一个SYSCLKOUT脉冲,预定标计数器PSC中的计数值减1,当PSC中的值减为0时,就会输出一个TIMCLK到TIMH:TIM,从而TIMH:TIM减1。
- 分频器TDDR:TDDRH:TDDR,采用两个8位表示16位,TDDR为TPR寄存器的高8位,TDDRH为TPRH寄存器的高8位。PSC中的值减小到0或初始重装载时,将TDDR中的值重新装载到PSC,进行新一轮的递减。
- 计数器寄存器TIM:当PSC输出一个TIMCLK到TIM时,TIM减1,当TIM减小到0后,便会产生一个中断信号。
- 周期寄存器PRD:PRDH:PRD,采用两个16位的寄存器表示32位,该寄存器设置定时器的周期值,每当TIM减小到0或初始重装载时,将PRD寄存器中的值装载到TIM,开始新一轮的计数。
因此,如果想用定时器来计量一段时间,需要设置的寄存器只有两个:一个是周期寄存器PRDH:PRD;一个是分频器TDDRH:TRRD。
TDDR决定了发送一个TIMCLK的时间,假设系统时钟SYSCLKOUT的值为X(单位MHZ):
TIMCLK=XTDDRH:TDDR+1∗10−6(单位s)
CPU定时器一个周期计数了(PRDH:PRD+1)次,因此CPU定时器一个周期所计量时间为:
T=(PRDH:PRD+1)∗XTDDRH:TDDR+1∗10−6(单位s)
通常的应用时,已知要定时的时间T和CPU的系统时钟X,且通常将TDDRH:TDDR寄存器的值设置为0,则要实现时间T,必须将PRDH:PRD寄存器的值设置为T*X,其中,T单位为us,X单位为MHZ。
定时器代码实例
InitCpuTimers(); // 初始化CPU定时器
ConfigCpuTimer(&CpuTimer0, 150, 1000000); //配置CPU定时器,系统时钟选择150MHZ,定时时间选择1S
void InitCpuTimers(void)
{
// CPU Timer 0
// 将CPU Timer 0的寄存器地址赋值给CpuTimer0结构体:
CpuTimer0.RegsAddr = &CpuTimer0Regs;
// 初始化周期寄存器为32位的最大值:
CpuTimer0Regs.PRD.all = 0xFFFFFFFF;
// 初始化分频器PDDR为0,每一个TIMCLK时间为1/150 us:
CpuTimer0Regs.TPR.all = 0;
CpuTimer0Regs.TPRH.all = 0;
// 确保定时器是停止状态:
CpuTimer0Regs.TCR.bit.TSS = 1;
// 重新把PRD加载到TIM,把TDDR加载到PSC:
CpuTimer0Regs.TCR.bit.TRB = 1;
// 重置中断计数:
CpuTimer0.InterruptCount = 0;
}
void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)
{
Uint32 temp
// 初始化定时器计数值:
Timer->CPUFreqInMHz = Freq; //CPU系统时间为150Mhz
Timer->PeriodInUSec = Period; //定时器定时周期为1s,Period=1000000
temp = (long) (Freq * Period);
Timer->RegsAddr->PRD.all = temp; //PRD周期寄存器值为Freq*Period,即150*1000000
// 初始化分频器PDDR为0,每一个TIMCLK时间为1/150 us,则总时间T=150 * 1000000 * 1 / (150 *1000000) = 1s
Timer->RegsAddr->TPR.all = 0;
Timer->RegsAddr->TPRH.all = 0;
// 初始化计时器控制寄存器:
Timer->RegsAddr->TCR.bit.TSS = 1; // 1 = 停止计数器, 0 = 开始/重置计数器
Timer->RegsAddr->TCR.bit.TRB = 1; // 1 = 重新装载TIM和PSC
Timer->RegsAddr->TCR.bit.SOFT = 0; // 1 = 定时器在TIM递减到0后停止,0 = 在下一个TIM递减操作完成后停止(硬停止)
Timer->RegsAddr->TCR.bit.FREE = 0; // 1 = 仿真中遇到断点,定时器继续运行,SOFT不起作用,0 = SOFT起作用
Timer->RegsAddr->TCR.bit.TIE = 1; // 0 = 定时器中断不使能 1 = 定时器中断使能
// 重置中断计数器
Timer->InterruptCount = 0;
}