//Logo Image
作者:陳明周(2002-10-28),推薦:徐業良(2002-11-04)

單晶片實習—計時模組Timer0之應用

單晶片的計時器最大功用在於可以獨立計時,不受執行指令的影響。例如當單晶片正在執行一個迴圈時,計時器仍然能準確的計算時間,並於指定的時間跳出迴圈或執行其它指令,如此便可在講究執行優先順序的程式裡放入一個時間軸,讓單晶片不光是依流程執行,同時也能依時間的變化而有不同動作。

1.     計時器模組簡介

計時器是單晶片的一項重要功能,它的工作原理是每隔一段固定間隔時間,就累加計時器一次,因此時間即為此“計時器結果”與“間隔時間”的乘積,其最大優點在於能在不受程式流程影響而計算時間。

觸發計時器累加的觸發源稱為時脈(clock),時脈可以是來自單晶片本身的工作時脈(internal clock source)也可以是來自外部接腳的時脈(external clock source)。一般若使用內部時脈稱為「計時器(Timer)」,因為單晶片的內部clock相當準確,可做為計算時間的依據;若使用外部時脈則稱為「計數器(Counter)」,因外部訊號不見得固定時間,累加結果就不具有時間上的意義,只能表示發生的次數。

計時器所能累計的次數有範圍限制,依其位元數而不同,8-bits的計時器的範圍為0~25516-bits的計時器範圍為0~65535。當累計達上限值時,就會發生溢位(overflow),也就是從255跳到0或從65535跳到0的情形,單晶片通常提供一些選項處理溢位發生的狀況。

所有的PIC單晶片都有至少會有一個8-bit的計時器,有些還會更多。PIC16f87x系列單片的計時器共有三個,分別為Timer0Timer1Timer2和「看門狗計時器(Watchdog Timer, WDT)」,各有不同特性,如表1所示。本文將針對Timer0進行範例說明。

1. Timer0Timer1Timer2之特性比較

Timer

Timer0

Timer1

Timer2

Bits(位元數)

8

16

8

Prescaler(預除器)

Yes

Yes

Yes

Postscaler(後除器)

--

--

Yes

Internal Clock Source(支援內部時脈源)

Yes

Yes

Yes

External Clock Source(支援外部時脈源)

Yes

Yes

--

External Clock Edge(時脈觸發方式)

Rising/Falling

Rising

--

External Clock Pin(時脈觸發腳位)

RA4/T0CKI

RC0/T1OSO/T1CK1

--

Interrupt(中斷支援方式)

Overflow

Overflow

PR2 Match

Timer Base

--

Capture/Compare

PWM

2.     計時器程式範例說明

1為一計時器範例程式流程圖,程式開始執行後,會將RA0腳位的電壓轉換成數位訊號,不斷顯示在螢幕上,若按任意鍵則停止A/D取值,顯示程式執行時間,再按任意鍵則A/D取值繼續,計時器重新開始計時,再按任意鍵則螢幕顯示自上次按鍵至此所經歷時間。目地在顯示即使程式在執行一個while迴圈,計時器仍持續計時不受影響。程式使用CCS-C編譯器轉成組合語言並燒入PIC。以下說明此Timer0計時器程式中的指令。

        

(a)主程式                                               (b)計時副時程式

1. 計時器範例程式流程圖

2、圖3為以C語言撰寫之Timer0計時器應用程式,各項指令說明如下。

#define trcc_reset_value 236

Timer0的中斷週期設定,設定此值代表每計數一次為1.024ms,其計算方式如下:

Timer0之中斷週期(ms)

               

               

               

               

其中(由setup_timer r_0(RTCC_INTERNAL|RTCC_DIV_256)所設定),)。

依據此公式計算,如此設訂時Timer0之中斷週期應為1.024ms,不過由於程式經過c-compiler之轉換,因此產生7μs的延遲。

float time_factor=1.031;

時間校正係數。計時器的累加結果再乘上此時間校正係數,即可得真正時間。

#int_rtcc

啟動real-time clock計時器。

void timer0_isr()

啟動timer_0中斷計時程式,其後並將累加結果指向變數time_sec(可自訂)

setup_timer_0(RTCC_INTERNAL | TRCC_DIV_256);

預除器為256

enable_interrupts(INT_RTCC);

設定內部中斷。

enable_interrupts(GLOBAL);

全域中斷。

經過以上的設定後,單晶片之Timer0已啟動,往後之程式可依使用者的不同要求而變化,當須要叫出時間時,只需計算變數time_sectime_factor的乘積即可得,如圖2中的變數interval_time所示。

2. Timer0計時器程式_1

3. Timer0計時器程式_2

參考資料

盧春林編著,PIC16F877微處理器技術精解,國科出版社,2001

何信龍、李雪銀編著,PIC16F877快速上手,全華科技,2000