51單片機內部一般有兩個計數/定時器,T0 T1,其框圖如下:
其中TH1 TL1用來設定T1的計數初值,TH0 TL0則用來設定T0的。
一、工作模式設置寄存器TMOD,地址爲89H,格式如下圖:
1、GATE——門控位
GATE = 0時,僅由運行控制位TRX(X = 0,1) = 1 來啓動定時/計數器。
GATE = 1時,由TRX(X = 0 , 1) = 1 和 外中斷引腳(INT0 或 INT1)上的高電平共同來啓動
2、M1、M0——工作方式選擇位
0 0——方式0,爲13位定時/計數器;
0 1——方式1,爲16位定時/計數器;
1 0——方式2,8位初值自動重裝載,將TH和TL分開,TH自動重新裝入TL;
1 1——方式2,僅適用於T0,分成兩個8位計數器,T1停止工作。
3、C/-T——計數器模式和定時器模式選擇位
0——爲定時器;1——爲計數器,計數器對外部輸入引腳(P3.4和P3.5)的外部脈衝(負跳變)計數。
二、控制寄存器TCON,地址爲88H~8FH
低四位與外部中斷有關。
1、TF1、TF0——T1、T0計數溢出標誌位
溢出時由硬件自動將其置1,可以由程序查詢,該位確定溢出。非中斷模式下,軟件清零;中斷方式時,此位爲中斷源,
進入中斷服務函數後由硬件自動清零。
2、TR1、TR0——計數運行控制位
1——和GATE位配合(看GATE位設置),啓動計數定時器;
0——停止定時/計數器。該位有軟件置位或者清0。
工作方式1框圖:
三、初值計算
1、機器週期 = 具體晶振頻率 / 分頻數 的倒數
2、初值 = 溢出值 - 機器週期 * 定時時間
假設T0初值爲5000,則應該這麼設置:
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
一個編程例子:
TMOD = 0X01; //設置t0爲16位(01)計時模式,以TR0來啓動計時器
//計算初值
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
EA = 1; //開總中斷
ET0 = 1;//開定時器0中斷
TR0 = 1; //啓動T0
while (1);
定時器中斷服務函數;
void timer0_service(void) interrupt 1 (T1 時這裏應爲3)
{
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256; //打算繼續定時下去時,進入中斷服務函數後,重新設定一下初值。
times++; //這可以產生更大的定時
if (times == 20) {
times = 0;
led = !led;
}
}