1. 程式人生 > >DSP2812之定時器

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

IMCLK=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;
}