一、前言 TMR0 計(jì)時(shí)器 實(shí)際上 TMR0 計(jì)時(shí)器的應(yīng)用很廣。很少程式不用到它。它非常方便,而且很容易用來(lái)撰寫(xiě)產(chǎn)生任意期 間的脈沖的程式或副程式(subroutine)、測(cè)量時(shí)間,或是計(jì)數(shù)外部脈沖 (事件),幾乎沒(méi)有什么限制。 TMR0 計(jì)時(shí)器模組是 8 位元的計(jì)時(shí)器/計(jì)數(shù)器,具有下列特性: ● 8 位元計(jì)時(shí)器/計(jì)數(shù)器; ● 8 位元 prescaler (與 Watchdog timer 共享); ● 可程式的內(nèi)部或外部時(shí)脈來(lái)源 (Programmable internal or external clock sources); ● 溢位中斷 (Interrupt on overflow); 及 ● 可程式選擇的外部時(shí)脈邊緣 (Programmable external clock edge selection)。
二、原理與暫存器設(shè)定說(shuō)明 原理: OPTION_REG 暫存器
可以看出,PSA 位元的邏輯狀態(tài)決定 prescaler 指派給 TMR0 或是 watchdog timer。 另外,值得一提的是: ● 當(dāng) prescaler 指派給 TMR0 時(shí),任何對(duì) TMR0 暫存器的寫(xiě)入動(dòng)作將會(huì)清除 prescaler; ● 當(dāng) prescaler 指派給 watchdog timer 時(shí),CLRWDT 指令將同時(shí)清除 prescaler 與 WDT; ● 當(dāng) TMR0 作為計(jì)時(shí)器用時(shí),對(duì) TMR0 的寫(xiě)入動(dòng)作不會(huì)讓脈沖計(jì)數(shù)立即開(kāi)始,而會(huì)有兩個(gè)指令周期 的延遲。因此,有必要調(diào)整寫(xiě)到TMR0 的值; ● 當(dāng)微控制器被設(shè)成睡眠模式時(shí),振蕩器便會(huì)關(guān)閉。因?yàn)闆](méi)得計(jì)數(shù)脈沖,所以就不會(huì)發(fā)生溢位 (overflow)。這就是為什么 TMR0 溢位不能將微控制器從睡眠模式中喚醒的原因; ● 當(dāng)用作不含 prescaler 的外部時(shí)脈計(jì)數(shù)器時(shí) (external clock counter),最小的脈沖長(zhǎng)度或兩個(gè)脈 沖之間的間歇必須是 2 Tosc + 20 nS. Tosc 是振蕩訊號(hào)周期 (oscillator signal period); ● 當(dāng)用作含 presacler 的外部計(jì)數(shù)器時(shí),最小的脈沖長(zhǎng)度或兩個(gè)脈沖之間的間歇必須是 10nS; ● 8 位元 prescaler 暫存器不提供給使用者,這表示不能直接讀寫(xiě) prescaler 暫存器; 當(dāng)從 TMR0 將 prescaler 指派給 watchdog timer 時(shí),必須按下列指令次序執(zhí)行以免發(fā)生重置 (reset): view source print? 01 BANKSEL TMR0 02 CLRWDT ;CLEAR WDT 03 CLRF TMR0 ;CLEAR TMR0 AND PRESCALER 04 BANKSEL OPTION_REG 05 BSF OPTION_REG,PSA ;PRESCALER IS ASSIGNED TO THE WDT 06 CLRWDT ;CLEAR WDT 07 MOVLW b’11111000’ ;SELECT BITS PS2,PS1,PS0 AND CLEAR 08 ANDWF OPTION_REG,W ;THEM BY INSTRUCTION “LOGICAL AND” 09 IORLW b’00000101’ ;BITS PS2, PS1, AND PS0 SET 10 MOVWF OPTION_REG ;PRESCALER RATE TO 1:32 ● 同樣的,當(dāng)從 WDT 將 prescaler 指派給 TMR0 時(shí),必須按下列指令次序執(zhí)行以免發(fā)生重置: view source print? 1 BANKSEL TMR0 2 CLRWDT ;CLEAR WDT AND PRESCALER 3 BANKSEL OPTION_REG 4 MOVLW b’11110000’ ;SELECT ONLY BITS PSA,PS2,PS1,PS0 5 ANDWF OPTION_REG,W ;CLEAR THEM AFTERWARDS BY INSTRUCTION 6 ;“LOGICAL AND” 7 IORLW b’00000011’ ;PRESCALER RATE IS 1:16 8 MOVWF OPTION_REG 暫存器設(shè)定說(shuō)明: 為了恰當(dāng)?shù)厥褂?TMR0,必須: 1、要選擇模式: ● 計(jì)時(shí)器模式是借由 OPTION_REG 暫存器的 T0CS 來(lái)選擇。 (T0CS: 0=timer, 1=counter); ● 使用的時(shí)候,必須借由清除 OPTION_REG 暫存器的 PSA 位元將 prescaler 指派給 TMR0。 prescaler 比率 (Prescaler rate) 的設(shè)定是透過(guò)OPTION_REG 暫存器的 PS2-PS0 位元,及 ● 使用中斷時(shí),必須設(shè)定 INTCON 暫存器的 GIE 與 TMR0IE 位元。 2、要測(cè)量時(shí)間: ● 重設(shè) TMR0 暫存器或?qū)懭胍阎闹档?TMR0; ● 經(jīng)過(guò)時(shí)間 (單位是毫秒,當(dāng)使用 4 MHz 石英晶體時(shí)) 的獲得方式是透過(guò)讀取 TMR0 暫存器 ● 每當(dāng) TMR0 暫存器溢位時(shí),INTCON 暫存器的 TMR0IF 旗號(hào)便會(huì)自動(dòng)豎起來(lái),如果中斷有啟用, 會(huì)引發(fā)中斷。 3、要計(jì)數(shù)脈沖: ● 位于 RA4 腳位,要計(jì)數(shù)的脈沖極性 (polarity) 的選擇是透過(guò)設(shè)定 OPTION_REG 暫存器的 T0SE 位元 (T0SE: 0=負(fù)向緣, 1=正向緣); 及 ● 脈沖數(shù)可從 TMR0 暫存器中取得。如同計(jì)時(shí)器模式,presacler 和中斷的用法是一樣的。
三、程式與電路圖
程式: // FOSC=16MHz Fcy=4Mhz Tcy=1/Fcy #include __CONFIG ( FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF ); //配置位元設(shè)置為外接晶振 __CONFIG ( BOR4V_BOR40V & WRT_OFF ); unsigned char data=0;//定義變數(shù)data并賦值為0 main() { unsigned int i=0;//定義i為無(wú)符號(hào)整形并賦值為0 T0CS=0; // 選通Fosc/4 PSA=0; //設(shè)定為用TIMER0,而不是WDT PS2=0; //1:16 預(yù)除4倍,數(shù)完250次=(4MHz/1)*250=1ms PS1=1;//PS2,PS1,PS0為除頻設(shè)置 PS0=1; T0IF=0;//設(shè)置溢位初始值為0 TMR0=6; //預(yù)設(shè)TMR0=6,運(yùn)行250次會(huì)進(jìn)位 TRISD=0;// 埠初始化D0--D7設(shè)置為輸出 PORTD=0; //D埠輸出低電頻,8個(gè)LED全滅掉 data=0b00000001;//data賦值為1 while(1) // 主回圈必須是閉環(huán) { if(T0IF==1)//如果溢位為1則執(zhí)行if下語(yǔ)句 { T0IF=0; //if成立將溢位再次置0 i++; //i=i+1 if(i==1000) //i=1000時(shí)執(zhí)行下面語(yǔ)句 { i=0; //i重新置0,進(jìn)行下一輪計(jì)時(shí) data=data<<1; //data左移1位 if(data==0) //如果data=0時(shí)執(zhí)行下面語(yǔ)句 data=0b00000001; //data重新置為1 PORTD=data; //D埠輸出資料為data TMR0=6;//使TMR0等于6 } } } }
電路圖:
四、結(jié)論
程序打包下載:http://www.torrancerestoration.com/bbs/dpj-50261-1.html
|