89C51單片機(jī)的定時(shí)計(jì)數(shù)功能由特殊功能寄存器TMOD和TCON共同控制。
TMOD沒(méi)有位地址,不能進(jìn)行位操作,其每位的名稱和功能如下:
TMOD:GATE C/T1 M1 M0 GATE C/T1 M1 M0
D7 D6 D5 D4 D3 D2 D1 D0
GATE C/T1 M1 M0 控制定時(shí)計(jì)時(shí)器1;
GATE C/T0 M1 M0 控制定時(shí)計(jì)時(shí)器0;
GATE=0時(shí),定時(shí)計(jì)數(shù)信號(hào)是T0腳狀態(tài)(P3.4)或機(jī)器周期(C/T=0計(jì)機(jī)器周期,即定時(shí),C/T=1,計(jì)T0腳的狀態(tài),即計(jì)數(shù)),計(jì)數(shù)開(kāi)始開(kāi)關(guān)是TR0(0關(guān)閉計(jì)數(shù),1開(kāi)始計(jì)數(shù))。
GATE=1時(shí),定時(shí)計(jì)數(shù)功能由T0腳(P3.4)或者機(jī)器周期確定(C/T=0計(jì)數(shù)機(jī)器周期,即定時(shí),C/T=1,計(jì)數(shù)T0腳的變化狀態(tài),即計(jì)數(shù)),計(jì)數(shù)開(kāi)始開(kāi)關(guān)由TR0(0關(guān)閉計(jì)數(shù),1開(kāi)始計(jì)數(shù))和INT0(管腳P3.2)共同確定。
M1M0是計(jì)數(shù)方式選擇:計(jì)數(shù)在TH0和TL0進(jìn)行。
00為方式0,13位(TH0的8位和TL0的低5位)二進(jìn)制計(jì)數(shù)器,由0可數(shù)到2的13次方-1;
01為方式1,16位二進(jìn)制計(jì)數(shù)器,由0可數(shù)到2的16次方-1;
10為方式2,8位二進(jìn)制計(jì)數(shù)器,TH0放計(jì)數(shù)初值,計(jì)數(shù)在TL0進(jìn)行,溢出后自動(dòng)將
TH0中的初值裝入TL0;
11為方式3,TH0是個(gè)8為計(jì)數(shù)器,HL0是個(gè)8位計(jì)數(shù)器。兩個(gè)計(jì)數(shù)器相互獨(dú)立。
T1和T0功能相同。
特殊功能寄存器TCON,可以位操作,但一般不用位地址,而用位的功能名稱:
位地址:8FH 8EH 8DH 8Ch 8Bh 8Ah 89H 88H
TCON :TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
D7 D6 D5 D4 D3 D2 D1 D0
TF0是T0計(jì)數(shù)標(biāo)志位:定時(shí)計(jì)數(shù)溢出時(shí),該位被自動(dòng)置1,中斷計(jì)數(shù)結(jié)束后自動(dòng)清0.
TR0是計(jì)數(shù)開(kāi)關(guān),GATE=0時(shí),TR0=1打開(kāi)計(jì)數(shù),0關(guān)閉。當(dāng)GATE=1時(shí),和INT0一起控制計(jì)數(shù)器打開(kāi),即GATE=1,TR0=1,INT0=1才可打開(kāi)計(jì)數(shù),否則關(guān)閉。
定時(shí)/計(jì)數(shù)時(shí),由TH0 TL0的值開(kāi)始加1計(jì)數(shù)到FFFFH滿,再計(jì)數(shù)就溢出,如果是定時(shí)/計(jì)數(shù)模式,溢出后將TF0置1,計(jì)數(shù)定時(shí)結(jié)束,如果是中斷模式,中斷請(qǐng)求由硬件給TF0置1,計(jì)數(shù)結(jié)束后,也就是中斷結(jié)束后,自動(dòng)將TF0清0。
/***************定時(shí)器定時(shí)50ms,在計(jì)數(shù)20下為1秒,顯示60秒計(jì)時(shí)(查詢模式)***********/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
int t,k,dat;
void delay(int ms)
{
while(ms--)
{
int i;
for(i=0;i<30;i++);
}
}
void Timer0()
{
if(TF0==1)//查詢TF0為1,說(shuō)明計(jì)數(shù)滿了,計(jì)數(shù)結(jié)束。
{
t++;
TH0=0x3c;//這里是計(jì)數(shù)滿后重新裝入計(jì)數(shù)初值.也可TH0=(65536-5000)/256
TL0=0xb0;//計(jì)數(shù)溢出后再次計(jì)數(shù)從這里開(kāi)始,也可TL0=(65536-5000)%256
/*如果先計(jì)算初值麻煩,還可以用16位二進(jìn)制的最大值65536-定時(shí)計(jì)數(shù)次數(shù)賦值給TH0和TL0,例如定時(shí)40ms,需對(duì)機(jī)器周期計(jì)數(shù)4000下,可以
TH0=(65536-4000)/256;TL0=(65536-4000)%*/
TF0=0;
}
//清除溢出標(biāo)志
}
void T1s()
{
if(t==20)//計(jì)數(shù)一次50ms,20次為1秒
{t=0;
dat++;
if(dat==60)//60次為1分鐘
dat=0;
}
}
{
TMOD=0x01;
/*此設(shè)置(0000 0101)T0的GATE=0,C/T為0,M1M0為01。
GATE=0,關(guān)閉INT0(P3.2)腳對(duì)計(jì)數(shù)開(kāi)始的控制,只由TR0控制開(kāi)始。
C/T=0,定時(shí)功能,計(jì)數(shù)機(jī)器周期的個(gè)數(shù)。
M1M0=01,計(jì)數(shù)方式選擇方式1,16位二進(jìn)制計(jì)數(shù)器,由TH0 TL0開(kāi)始計(jì)數(shù)到FFFFH滿
再計(jì)數(shù)就溢出,如果是定時(shí)/計(jì)數(shù)模式,溢出后將TF0置1,計(jì)數(shù)定時(shí)結(jié)束,如果是中
斷模式清0,有硬件給TF0置1,計(jì)數(shù)結(jié)束,也就是中斷結(jié)束,自動(dòng)將TF0清0.
打開(kāi)計(jì)數(shù)器0中斷將ET0=1,EA=1 */
TH0=0x3c;//設(shè)置計(jì)數(shù)器計(jì)數(shù)初值50ms從3CB0H開(kāi)始計(jì)數(shù)
TL0=0xb0;//第一次從這里的設(shè)置開(kāi)始計(jì)數(shù)
TR0=1;
while(1)
{
Timer0();
T1s();
P0=yu[dat%10];
delay(1);
P2=0x01;
delay(1);
P2=0x00;
P0=yu[dat/10];
delay(1);
P2=0x02;
delay(1);
P2=0x00;
}
}
/*******定時(shí)/計(jì)數(shù)器0中斷應(yīng)用,按鍵沒(méi)按一次數(shù)碼管顯示加1(中斷模式)*************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
int k;
void delay(int ms)
{
while(ms--)
{
int i;
for(i=0;i<30;i++);
}
}
void ddd() interrupt 1
{
TH0=0xff;//這里是計(jì)數(shù)滿后重新裝入計(jì)數(shù)初值
TL0=0xfa;//計(jì)數(shù)溢出后再次計(jì)數(shù)從這里開(kāi)始
delay(5);
if(TF0==0)//計(jì)數(shù)中斷時(shí)TF0由硬件置1,響應(yīng)中斷并開(kāi)始計(jì)數(shù),計(jì)數(shù)產(chǎn)生溢出后自動(dòng)清0,結(jié)束計(jì)數(shù)。
{ //所以,響應(yīng)中斷后,查詢TF0的狀態(tài)可以判斷中斷計(jì)數(shù)是否結(jié)束
if(k==99)
k=0;
else
k++;
}
}
{
TMOD=0x05;
/*此設(shè)置(0000 0101)T0的GATE=0,C/T為1,M1M0為01。
GATE=0,關(guān)閉INT0(P3.2)腳對(duì)計(jì)數(shù)開(kāi)始的控制,只由TR0控制開(kāi)始。
C/T=1,計(jì)數(shù)功能,計(jì)數(shù)管腳T0(P3.4)的狀態(tài)變化。
M1M0=01,計(jì)數(shù)方式選擇方式1,16位二進(jìn)制計(jì)數(shù)器,由TH0 TL0開(kāi)始計(jì)數(shù)到FFFFH滿,再計(jì)數(shù)就溢出,如果是定時(shí)/計(jì)數(shù)模式,溢出后將TF0置1,計(jì)數(shù)定時(shí)結(jié)束,如果是中斷模式清0,有硬件給TF0置1,計(jì)數(shù)結(jié)束,也就是中斷結(jié)束,自動(dòng)將TF0清0.打開(kāi)計(jì)數(shù)器0中斷將ET0=1,EA=1 */
TH0=0xff;//設(shè)置計(jì)數(shù)器計(jì)數(shù)初值
TL0=0xfc;//第一次從這里的設(shè)置開(kāi)始計(jì)數(shù)
ET0=1;
TR0=1;
EA=1;
while(1)
{
P0=yu[k%10];
delay(1);
P2=0x01;
delay(1);
P2=0x00;
P0=yu[k/10];
delay(1);
P2=0x02;
delay(1);
P2=0x00;
}
}

/******用查詢模式計(jì)數(shù)
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
int k;
void delay(int ms)
{
while(ms--)
{
int i;
for(i=0;i<30;i++);
}
}
void jishu()
{
if(TF0==1)//查詢TF0,為1,說(shuō)明計(jì)數(shù)滿了,計(jì)數(shù)結(jié)束。
{
TH0=0xff;//這里是計(jì)數(shù)滿后重新裝入計(jì)數(shù)初值
TL0=0xff;//計(jì)數(shù)溢出后再次計(jì)數(shù)從這里開(kāi)始
delay(5);
if(k==99)
k=0;
else
k++;
}
TF0=0; //清除溢出標(biāo)志
}
{
TMOD=0x05;
/*此設(shè)置(0000 0101)T0的GATE=0,C/T為1,M1M0為01。
GATE=0,關(guān)閉INT0(P3.2)腳對(duì)計(jì)數(shù)開(kāi)始的控制,只由TR0控制開(kāi)始。
C/T=1,計(jì)數(shù)功能,計(jì)數(shù)管腳T0(P3.4)的狀態(tài)變化。
M1M0=01,計(jì)數(shù)方式選擇方式1,16位二進(jìn)制計(jì)數(shù)器,由TH0 TL0開(kāi)始計(jì)數(shù)到FFFFH滿,再計(jì)數(shù)就溢出,如果是定時(shí)/計(jì)數(shù)模式,溢出后將TF0置1,計(jì)數(shù)定時(shí)結(jié)束,如果是中斷模式清0,有硬件給TF0置1,計(jì)數(shù)結(jié)束,也就是中斷結(jié)束,自動(dòng)將TF0清0.打開(kāi)計(jì)數(shù)器0中斷將ET0=1,EA=1 */
TH0=0xff;//設(shè)置計(jì)數(shù)器計(jì)數(shù)初值
TL0=0xff;//第一次從這里的設(shè)置開(kāi)始計(jì)數(shù)
TR0=1;
while(1)
{
jishu();
P0=yu[k%10];
delay(1);
P2=0x01;
delay(1);
P2=0x00;
P0=yu[k/10];
delay(1);
P2=0x02;
delay(1);
P2=0x00;
}
}
/**********************用定時(shí)中斷設(shè)計(jì)秒表及顯示****************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
int k,dat;
void delay(int ms)
{
while(ms--)
{
int i;
for(i=0;i<30;i++);
}
}
void ddd() interrupt 1
{
TH0=(8192-4000)-(8192-4000)%32;//這里是計(jì)數(shù)滿后重新裝入計(jì)數(shù)初值
TL0=(8192-4000)%32;//計(jì)數(shù)溢出后再次計(jì)數(shù)從這里開(kāi)始
delay(5);
if(TF0==0)//計(jì)數(shù)中斷時(shí)TF0由硬件置1,響應(yīng)中斷并開(kāi)始計(jì)數(shù),計(jì)數(shù)產(chǎn)生溢出后自動(dòng)清0,結(jié)束計(jì)數(shù)。
{ //所以,響應(yīng)中斷后,查詢TF0的狀態(tài)可以判斷中斷計(jì)數(shù)是否結(jié)束
if(k==250)
{k=0;
dat++;}
else
k++;
//關(guān)閉T0計(jì)數(shù)器,TR0=0句不能在主程序中,要在查詢函數(shù)或中斷函數(shù)中,否則停不下來(lái)。
}
}
{
TMOD=0x00;
/*此設(shè)置(0000 0101)T0的GATE=0,C/T為1,M1M0為01。
GATE=0,關(guān)閉INT0(P3.2)腳對(duì)計(jì)數(shù)開(kāi)始的控制,只由TR0控制開(kāi)始。
C/T=1,計(jì)數(shù)功能,計(jì)數(shù)管腳T0(P3.4)的狀態(tài)變化。
M1M0=01,計(jì)數(shù)方式選擇方式1,16位二進(jìn)制計(jì)數(shù)器,由TH0 TL0開(kāi)始計(jì)數(shù)到FFFFH滿,再計(jì)數(shù)就溢出,如果是定時(shí)/計(jì)數(shù)模式,溢出后將TF0置1,計(jì)數(shù)定時(shí)結(jié)束,如果是中斷模式清0,有硬件給TF0置1,計(jì)數(shù)結(jié)束,也就是中斷結(jié)束,自動(dòng)將TF0清0.打開(kāi)計(jì)數(shù)器0中斷將ET0=1,EA=1 */
TH0=0xa3;//設(shè)置計(jì)數(shù)器計(jì)數(shù)初值
TL0=0x00;//第一次從這里的設(shè)置開(kāi)始計(jì)數(shù)
ET0=1;
TR0=1;
EA=1;
while(1)
{
P0=yu[dat%10];
delay(1);
P2=0x01;
delay(1);
P2=0x00;
delay(1);
P2=0x02;
delay(1);
P2=0x00;
delay(1);
P2=0x04;
delay(1);
P2=0x00;
delay(1);
P2=0x08;
delay(1);
P2=0x00;
}
}
=====================================================
匯編語(yǔ)言編寫的T0中斷定時(shí)器
ORG 0000H
Ljmp main
ORG 000BH
Ljmp T0ZD
org 0100h
main:mov TMOD,#00h
mov TH0,#83h
mov TL0,#00h
mov r7,#00h
setb EA
setb ET0
setb TR0
mov dptr,#0300h
disp:mov 70h,r3
mov a,70h
mov b,#0ah
div ab
movc a,@a+dptr
mov P0,a
mov P2,#02h
nop
nop
mov P2,#00h
mov a,b
movc a,@a+dptr
mov P0,a
mov P2,#01h
nop
nop
mov P2,#00h
sjmp disp
T0ZD:mov TL0,#00h
mov TH0,#83h
cpl p1.7
cjne r7,#250D,zzz
mov r7,#00h
cjne r3,#60h,ddd
mov r3,#00h
ddd: inc r3
zzz: inc r7
reti
org 0300h
db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh
end
===================================================