DSP2812之定时器

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

猜你喜欢

转载自blog.csdn.net/dby3579/article/details/83216849
今日推荐