DSP

DSP2812之定时器

2019-07-13 10:50发布

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=TDDRH:TDDR+1X106(s) TIMCLK= frac{TDDRH:TDDR + 1}{X} *10^{-6} (单位s)
CPU定时器一个周期计数了(PRDH:PRD+1)次,因此CPU定时器一个周期所计量时间为:
T=PRDH:PRD+1TDDRH:TDDR+1X106(s) T= (PRDH:PRD + 1)* frac{TDDRH:TDDR + 1}{X} *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; }