定時器/計數器是一種計數裝置,若對内部時鐘脈沖計數,可視為定時器;若對外部時鐘脈沖計數,可視為計數器。
定時器/計數器的應用可以采用中斷的方式當定時或計數達到時産生中斷,另外也可以采用詢問的方式,不斷詢問計數狀态,以控制程序流程。
8051計數寄存器是THx和TLx兩個8位的寄存器,x=1或x=0。
8051的定時器/計數器
8051單片機有2個16位定時器/計數器:定時器0(Timer0)和定時器1(Timer1)簡稱T0和T1,8052在包含了T0、T1還有一個Timer 2(T2)。這三個定時器/計數器都可作為内部定時器或外部計數器。
若是作為内部定時器時,是計數内部的脈沖。以12MHz的計數時鐘脈沖系統為例,将12MHz/12送入定時器,此時定時器所計數的脈沖周期為1us。若采用16位的定時模式,則最多可計數65536個脈沖(即2^16),約0.0655s。
若作為外部計數器時,則是計數由T0或T1引腳送入的脈沖。同樣的,若采用16位的定時模式,最多可計數65536(即2^16)個計數量。
定時器/計數器模式寄存器TMOD定時器/計數器模式寄存器TMOD主要設定定時器/計數器的工作模式、計數信号來源及啟動方式等。
TMOD模式寄存器的低四位T0(0-3)配置定時器/計數器0(Timer0)的工作模式,高四位T1(4-7)配置定時器/計數器1(Timer1)的工作模式,這兩部分的結構類似,隻是控制的對象不同。
我們以高四位為例來了解TMOD模式寄存器的使用,即使用T 1,(T0一樣的用法):
GATE為Timer的門控開關,用來決定Timer 1(T 1)的啟動方式。
若GATE = 0,則隻要 TR1 = 1,即可啟動Timer 1,稱為内部啟動或軟件啟動;
若GATE = 1,則需要 TR1 = 1,還要等待外部中斷引腳INT1為高電平,Timer 1才能啟動工作,稱為外部啟動或硬件啟動。
C/T(Count/Timer)定時器/計數器切換開關:C/T=0為内部定時器,用來計數OSC/12的脈沖;C/T=1為外部計數模式,用來計數由T 1(P3.5)引腳輸入的脈沖;
M0,M1定時/計數模式選擇開關:
Mode0(M1 = 0,M0 = 0):
提供兩個13位定時器/計數器(Timer 0/Timer 1),如前所述,計數量分别存放在TH1和TL1兩個8位計數寄存器裡。其中TH1放置8位,TL1放置5。
如前所述,若要執行定時功能,則C/T設定為0,計數内部脈沖;若要執行計數功能,設置C/T為1,計數外部脈沖信号。
啟動方式為外部啟動時:設定GATE = 1,TR1=1,再等待外部中斷引腳INT1輸入高電平,即可啟動 Timer 1;
啟動方式為内部啟動時:設定GATE = 0,TR1=1,即可啟動 Timer 1;
Mode1(M1 = 0,M0 = 1):
提供兩個16位定時/計數器,計數量分别存放在THx和TLx兩個8位計數寄存器裡。
Mode 1下的定時器/計數器的工作模式切換、啟動方式等與Mode 0 完全一樣,Mode 1計數量更大,所以完全可以替代Mode 0。
Mode 2(M1 = 1,M0 = 0):
提供兩個8位可自動加載的定時器/計數器(Timer 0和 Timer 1),其計數寄存器裡的計數量放置在TLx裡,當改定時器/計數器中斷時,會自動将THx計數寄存器裡的計數量載入到TLx裡。由于計數隻用了8位,所以其最大計數為256。
Mode 2下的定時器/計數器的工作模式切換、啟動方式等與Mode 0 完全一樣。
Mode 3(M1 = 1,M0 = 1):
此工作模式是一種特殊的模式,提供一個8位的定時器/計數器 Timer 0和一個8位的定時器Timer 1。
其中Timer 0除了不具有自動加載功能外,與Mode 2的Timer0幾乎完全一樣。
而Timer 1定時器也幾乎可以被Mode 2的Timer 1所取代。
定時器/計數器控制寄存器TCON寄存器TCON的高四位一共定時器/計數器的啟動開關和中斷時的标志位,低四位為外部中斷觸發控制位和外部中斷請求标志位,如下圖:
TF1:定時器Timer 1中斷(溢出)标志位。當Timer 1時,由硬件自動設定TF1= 1,并向CPU申請中斷。Timer 1中斷結束時,CPU自動對TF1清零。TF1也可以用軟件清零。
TR1:定時器Timer 1啟動開關。TR=1,Timer 1啟動,TR1=0關閉Timer 1。
TF0:定時器T0溢出标志位。其功能與TF1相同。
TR0:定時器T0運行控制位。其功能與TR1相同。
IE1:外部中斷1(INT1)标志位。
IT1:外部中斷1(INT1)觸發方式控制位。
IE0:外部中斷0(INT0)标志位。
IT0:外部中斷0(INT0)觸發方式控制位。
計數寄存器:8051的計數寄存器是THx和TLx兩個8位寄存器,除了Mode 3之外,TH0和TL0是Timer 0所使用的計數寄存器,TH1和TL1是Timer 1所使用的的計數寄存器。若是8052還有Timer 2所使用的TH2和TL2。
8051定時器/計數器是一種正數計數器。當計數到滿(溢出)時,即産生中斷。我們計數時用該模式下的最大計數量減去所需計數,即從終點往前推,比如最大計數量為100,需要計數40,則從60處開始計數。
不同模式下的最大計數量不同,設定方式也有差異。
下面對各個模式下計數寄存器分别做說明:
Mode 0
由于Mode 0 TLx計數寄存器隻使用5位,2^5 = 32,我們要把計數起點的值除以32,其餘數放入TLx計數寄存器;其商放入THx計數寄存器。例如要使用Timer 0計數6000,則:
TL0 = (8192 - 6000)% 32;//取低5位
TH0 = (8192 - 6000)/ 32;//取高8位
Mode 1
在此模式下,TLx和THx計數寄存器都是8位,而2^8=256,同樣使用Timer 0計數6000則
TL0 = (65536 - 6000)% 256;
TH0 = (65536 - 6000)/ 256;
Mode 3
在此模式下,使用TL0計數寄存器作為第一個定時器/計數器的計數量,而TH0計數寄存器作為第二個定時器的計數量,用到哪個就填入哪個。兩個都用到就對TL0、TH0分别填入對應的值。填入方法與Mode 2一樣。
定時器/計數器的使用定時器/計數器有兩種使用方式:中斷和查詢
中斷:包括定時器/計數器中斷的設定、計數量的設定、啟動設定及中斷子程序的編寫
查詢:隻要設定計數量及啟動,然後判斷定時器/計數器的标志位(TFx)是否動作,接着程序流程的跳轉。
中斷設定(關于8051的中斷就不展開了):
中斷的設定包括開啟開關(IE寄存器的設定)、中斷優先級的設定(即IP寄存器的設定)、中斷信号的設定(TCON寄存器的設定)等。例如要開啟中斷總開關及T0開關(IE為中斷啟用寄存器,IP為中斷優先級寄存器):
IE=0x82;//打開中斷總開關及啟用T0中斷
把T0中斷設定高優先級,并設定為内部定時器,軟件啟動方式,采用Mode 1:
IP=0x02;//T0中斷高優先級
TMOD = 0x01;//設定為内部定時器、軟件啟動和Mode 1
計數量設定(略,見上文)
定時器/計數器啟動
TRx=1;// 啟動Timer x
中斷子程序
中斷程序格式:void 函數名 interrupt 數字0—5
0 外部中斷INT0
1 定時器/計數器TF0
2外部中斷INT1
3定時器/計數器TF1
4串行口TI/RI
5定時器/計數器TF2/EXF2(8052才有)
注意區分定時器/計數器的中斷編号與外部中斷編号,定時器 0的中斷編号為 1,定時器 1的中斷編号為 3,定時器 2的中斷編号為 5。
如:
void my_INT (void) interrupt 3 //Timer 1溢出中斷子程序
{
…….//中斷子程序邏輯代碼
}
,