第六章 計時/計數器
§ 6-1 計時/計數器的功能
在8051單晶片的內部有2個計時/計數器,可接收外界輸入的驅動信號,而能產生一個輸出信號以供讀取外界輸入信號發生的次數。如果這個外界輸入信號代表某一事件發生的次數,則計時/計數器即是在作事件的計數;如果這個外界輸入信號是一個固定頻率的信號,則計時/計數器則可用以作計算時間的工作。因此,8051單晶片的計時/計數器為一體兩面,完全取決於驅動信號的特質而定。
§ 6-2 計時/計數器的驅動與使用
Timer0與Timer1是8051單晶片的兩個16位元計時/計數器,其計數值是存放於兩個8位元暫存器中,Timer0的計數是由TH0(High byte)及TL0(Low byte)來執行,Timer1的計數是由TH1(High byte)及TL1(Low byte)來執行。其位址分別位於SFR內部記憶體的8CH、8AH、8DH及8BH中,如第四章之SFR記憶體圖所示。在程式撰寫上,編輯器允許直接使用暫存器的名稱TH0、TL0、TH1及TL1,亦可直接使用其暫存器位址,來作直接定址。
在使用8051單晶片計時/計數器前須先設定計時/計數器模式控制暫存器(Timer/counter Mode Control Register,簡稱TMOD)及計時/計數器控制暫存器(Timer/counter Control Register,簡稱TCON)兩個暫存器,此二暫存器分別用來決定Timer0及Timer1的工作模式及中斷執行的控制設定。
§ 6-3 TMOD模式控制暫存器之設定
Timer的計時時脈來源有兩種,一種是8051單晶片的內部時脈,一種是從T0與T1接腳所輸入的外部時脈。在8051單晶片接收時脈計時/計數時,會在每個機械週期值由〝1〞變為〝0〞時,將Timer的值累加1。而8051單晶片對時脈來源的選擇是由TMOD暫存器中的C/T位元來決定。當C/T設定為1時,Timer使用外部時脈;當C/T設定為0時,Timer使用內部時脈。TMOD的結構如下:
當TCON暫存器中的TR0(或TR1)為1時,則Timer0(或Timer1)由TMOD暫存器的GATE位元與INT0(或INT1)接腳構成Timer的軟體控制;當TCON暫存器中的TR0(或TR1)為0時,則Timer0(或Timer1)將停止計時/計數。若以布林帶數表示則為Y=(GATE+INTx)。Timer0與Timer1一共有四種模式,是由TMOD暫存器中的M0與M1位元來設定。以下為四種工作模式:
1. 模式0:(M1=M0=0,13位元計時/計數器)
將Timer設定為模式0時,會形成一個13位元計時/計數器,計時/計數暫存器是由THx的8位元與TLx的低5位元所組成。當TR0(或TR1)設定為1時,計時/計數器開始作動,若13個位元由全部為〝1〞變為全部為〝0〞時,則會將Timer溢位旗號TFx設定為1。結合IE暫存器(中斷致能暫存器,Interrupt Enable Register)致能Timer0(或Timer1),則8051單晶片會擷取TF0(或TF1)的資料,以偵測是否要產生中斷。當8051單晶片執行中斷副程式時會自動將TF0(或TF1)清除為0。將在下一章介紹8051單晶片中斷服務。
Timer工作模式0時,13位元計時/計數值最大為8192(2的13次方),因此,THx的值應為計時/計數值除以32的商,TLx的值則為計時/計數值除以32的餘數。若計時/計數值為5000時,即
TL0 = # (8192-5000)×MOD×32
TH0 = # (8192-5000)/32
則程式可寫為:
MOV TL0,# (8192-5000)×MOD×32
MOV TH0,# (8192-5000)/32
2. 模式1:(M1=0,M0=1,16位元計時/計數器)
模式0與模式1的動作幾乎相同,兩者之間的差別在於Timer工作在模式1時是16位元的計時/計數器。模式1計時/計數最大值為65536(2的16次方),因此,THx的值應為計時/計數值除以256的商,TLx的值則為計時/計數值除以256的餘數。若計時/計數值為5000時,即
TH0 = # (65536-5000)/256
TL0 = # (65536-5000)×MOD×256
則程式可寫為:
MOV TH0,# (65536-5000)/256
MOV TL0,# (65536-5000)×MOD×256
或寫成:
MOV TH0,# > (65536-5000)
MOV TL0,# < (65536-5000)
其中,〝<〞符號是通知編譯器將後面的值取16位元的低位元組,而〝>〞符號是通知編譯器將後面的值取16位元的高位元組。
3. 模式2:(M1=1,M0=0,8位元自動重新載入計時器)
將Timer設定成模式2時,會形成一個8位元自動重新載入計時/計數器。當計時/計數完畢後會產生TFx溢位旗號設定為1,並會將THx的值自動載入TLx中,因此,THx的值須事先由軟體設定。此模式適合用在需要固定時間的計時。
模式2計時/計數最大值為256(2的8次方),因此計時/計數值須同時存放於THx與TLx中。若計時/計數值為200時,即
TH0 = # (256-200)
TL0 = # (256-200)
則程式可寫成
MOV TH0,# (256-200)
MOV TL0,# (256-200)
4. 模式3:(M1=1,M0=1,兩個8位元的計時器)
Timer在模式3時,會將TH0與TL0分成兩個獨立的8位元計時器。TL0的計時器使用Timer0的控制信號,即C/T、GATE、TR0、INT0與TF0。而TH0則為計數機械週期的計數器,且使用Timer1的TR1及TF1做控制信號,因此TH0是控制Timer1計時/計數器。若使用Timer0的TL0計時/計數值為200時,即
TL0 = # (256-200)
則程式可寫成
MOV TL0,# (256-200)
TMOD暫存器在各種情形下的設定值:
1. Timer0做計時器
|
模式 |
功能 |
內部控制 |
外部控制 |
|
0 |
13位元計時器 |
00000000B |
00001000B |
|
1 |
16位元計時器 |
00000001B |
00001001B |
|
2 |
8位元自動重新載入 |
00000010B |
00001010B |
|
3 |
兩個8位元計時器 |
00000011B |
00001011B |
2. Timer0做計數器
|
模式 |
功能 |
內部控制 |
外部控制 |
|
0 |
13位元計數器 |
00000100B |
00001100B |
|
1 |
16位元計數器 |
00000101B |
00001101B |
|
2 |
8位元自動重新載入 |
00000110B |
00001110B |
|
3 |
一個8位元計數器 |
00000111B |
00001111B |
3. Timer1 做計時器
|
模式 |
功能 |
內部控制 |
外部控制 |
|
0 |
13位元計時器 |
00000000B |
10000000B |
|
1 |
16位元計時器 |
00010000B |
10010000B |
|
2 |
8位元自動重新載入 |
00100000B |
10100000B |
|
3 |
(TH0計時器) |
00110000B |
10110000B |
4. Timer1 做計數器
|
模式 |
功能 |
內部控制 |
外部控制 |
|
0 |
13位元計數器 |
01000000B |
11000000B |
|
1 |
16位元計數器 |
01010000B |
11010000B |
|
2 |
8位元自動重新載入 |
01100000B |
11100000B |
|
3 |
無 |
---- |
---- |
§ 6-4 TCON控制暫存器之設定
TCON為Timer的計時控制暫存器,其結構如下:
§ 6-5 計時/計數器實例
1. 利用模式1做為計時,其電路圖如下:
;
;
本程式以計時方式掃描驅動,以P0.0為0.05秒的閃爍,
;
P1到P3分別為秒分時的輸出
;
;
應用指令:
;
位元設定指令SETB用以設定位元為1
;
比較跳躍指令CJNE若暫存器與參數值比較不相等實則跳躍
;
位元為1時清除並跳躍指令JBC若暫存器位元為1則清除並跳躍
;
;
動作: P0.0之LED閃爍20Hz, 秒分時以十進制二進位法顯示
;
說明: 利用Timer0做0.05秒計時, 並為求執行時間控制, 進位累加.
;
顯示秒. 顯示分與顯示時分四次迴路執行, 以求可分別在0.05秒內
;
執行完畢
;
ORG 00H
JMP START
ORG 30H
MOV
SP,#30H
;將堆疊指標重新指向
START: MOV TMOD,#01
;設定16位元計時模式
MOV P0,#0
;將埠0設定為全滅
MOV R6,#0
;頻率記數初值設定為0
MOV R0,#0
;時R2分R1秒R0初值設定為0
MOV R1,#0
MOV R2,#0
LOOP: MOV TL0,#<(65536-46079)
;儲存16位元之低8位元
MOV TH0,#>(65536-46079) ;儲存16位元之高8位元
SETB TR0
;啟動計時
CJNE R6,#20,SHOW
MOV R6,#0
SEC INC R0
CJNE R0,#60,WAIT
MOV R0,#0
INC R1
CJNE R1,#60,WAIT
MOV R1,#0
INC R2
CJNE R2,#12,WAIT
MOV R2,#0
JMP WAIT
SHOW: CJNE R6,#10,SHOW1
MOV A,R0
CALL BCD
;呼叫轉換為二進位時進制副程式
MOV P1,A
SHOW1: CJNE R6,#11,SHOW2
MOV A,R1
CALL BCD
;呼叫轉換為二進位時進制副程式
MOV P2,A
SHOW2: CJNE R6,#12,WAIT
MOV A,R2
CALL BCD
;呼叫轉換為二進位時進制副程式
MOV P3,A
WAIT: JBC TF0,OVERFLOW
;測試是否計時完畢產生溢位
JMP WAIT
;否, 則持續測試溢位之發生
OVERFLOW:
CPL P0.0
PASS: CLR TR0
INC R6
JMP LOOP
BCD: MOV R3,A
MOV B,#10
DIV AB
MOV R4,B
MOV B,#16
MUL AB
ADD A,R4
RET
END
程式說明:此程式時分秒由零開始計時,顯示時分秒在P1、P2與P3,以二進制十進位方式(BCD)顯示。
練習: 1. 在本程式加上輸入目前的時分秒,做為計時初始值。
2. 將本程式之二進制十進位(BCD)副程式,利用〝DA A〞指令改寫。
2. 利用模式2做為計數,利用外部控制方式。其電路圖如下:
;
;
本程式設定Timer0 Timer1為模式2計數使用,分別由輸入埠T0 T1輸入計數值5與3
;
P0與P1分別為計數完成次數之輸出
;
;
說明: 暫存器R0用以計數Timer0完成次數,
;
暫存器R1用以計數Timer1完成次數,
;
ORG 00H
JMP INIT ;規避00H至2FH間之中斷向量執行位址
ORG 30H
INIT:
MOV SP,#30H
;將堆疊指標重新指向
MOV TMOD,#66H ;設定Timer0與Timer1為模式2計數方式
MOV TL0,#(256-5) ;設定計數5次
MOV TH0,#(256-5) ;儲存計數次
MOV TL1,#(256-3) ;設定計數3次
MOV TH1,#(256-3) ;儲存計數次
MOV R0,#0
MOV R1,#0
SETB TR0
;開始計數
SETB TR1
;開始計數
WAIT: JBC TF0,OVERFLOW0 ;等待計數5完畢
JBC TF1,OVERFLOW1 ;等待計數3完畢
JMP WAIT
OVERFLOW0:
INC R0
MOV P0,R0
JMP WAIT
OVERFLOW1:
INC R1
MOV P1,R1
JMP WAIT
END
程式說明:本程式分別由T0、T1接腳輸入計數次數,Timer0與Timer1則分別設定為5與3做為計數溢位值。每當完成5次或3次,發生溢位,則會在P0與P1顯示值累加1(以二進制方式顯示亮燈)。