DSP2812之定時器
阿新 • • 發佈:2018-12-16
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): CPU定時器一個週期計數了(PRDH:PRD+1)次,因此CPU定時器一個週期所計量時間為: 通常的應用時,已知要定時的時間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;
}