8051單片機定時器/計數器的基本知識
概述:
51單片機內部集成了兩個16位定時/計數器T0和T1,他們可以單獨配置爲定時器或計數器。
當它們被配置爲定時器時,將按照預先設置好的長度運行一段時間後產生一個溢出中斷;
當他們被配置爲計數器時,在單片機的外部中斷引腳上檢測到一個脈衝信號後計數器將加1,如果達到預先設置好的事件數目,就將產生一箇中斷事件。
處於計數工作模式時, 加法計數器對芯片端子T0(P3.4)或T1(P3.5)上的輸入脈衝進行計數;
處於定時器工作模式時,加法計數器對內部機器週期脈衝進行計數。
相關寄存器:
工作方式寄存器:TMOD(地址:0x89)
TMOD不支持位尋址,當單片機初始化後,TMOD的值爲0x00。
TMOD的結構:
bit | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|---|
name | GATE | C/ | M1 | M0 | GATE | C/ | M1 | M0 |
其中bit0-bit3對定時器0進行配置,bit4-bit7對定時器1進行配置
GATE位:定時/計數器的門控位
GATE=0時,定時/計數器的運行只受到控制寄存器TCON中的運行控制位TRx控制;
GATE=1時,定時/計數器的運行收到TRx和外部中斷輸入引腳上的電平雙重控制。也就是定時器的啓動由TRx和INTx共同控制,即TRx=1&&INTx=1時,定時/計數器方可運行。
C/位:定時方式、計數方式選擇位
C/=0時,工作在計數狀態下;
C/=1時,工作在定時狀態下。
定時器/計數器0與定時器/計數器1只在工作方式選擇位上有所差別,差別在定時器/計數器0有工作方式3,定時器/計數器1沒有工作方式3,當定時器/計數器1的工作方式選擇位配置爲工作方式3時,定時器/計數器1停止工作。
M1 | M0 | 工作方式 | 含義 |
---|---|---|---|
0 | 0 | 0 | 13bit不帶自動重裝的計數器 |
0 | 1 | 1 | 16bit不帶自動重裝的計數器 |
1 | 0 | 2 | 自動重裝的8bit計數器 |
1 | 1 | 3 | 獨立的兩個8bit計數器 |
在工作方式2中,數據寄存器THx作爲自動重裝值自動賦值給數據寄存器TLx。
控制寄存器:TCON(地址:0x88)
TCON支持位尋址,用於控制定時器/計數器的啓動與溢出。當單片機初始化後,TMOD的值爲0x00。
TCON的結構:
bit | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|---|
name | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
TFx爲定時器/計數器的溢出標誌位。該位置位則說明單片機檢測到了定時器/計數器的溢出,並且PC自動跳轉到該中斷向量入口,當單片機響應中斷後,該位被硬件自動清除。該位由硬件寫操作,軟件讀操作。
TRx爲定時器/計數器啓動控制位,當該位被置位時,啓動定時器/計數器。該位由軟件寫操作,硬件讀操作。
TCON的bit0-bit3爲外部中斷控制位。
T0數據寄存器:TH0、TL0
T1數據寄存器:TH1、TL1
關於數據寄存器的賦值:
1個計數週期等於1個機器週期
1個機器週期等於12個時鐘週期
MCU主頻:
MCU計數週期:
預設時間:t
定時器/計數器需要運行的次數:num
=,num==
相關應用實例:
實例1:
#include <AT89X52.h>
sbit Signal = P2 ^ 0;
//初始化定時計數器控制寄存器
Timer0_int(void) interrupt 1 using 1 //定時器0中斷服務子程序
{
Signal = ~Signal; //P1.7引腳翻轉
TH0 = 0x1F;
TL0 = 0x08; //重裝初始化值
}
void main()
{
TMOD = 0x00; //定時/計數器的方式和控制寄存器
//不受外部中斷控制,選擇方式0:13bit定時/計數器,工作在定時方式
EA = 1; //中斷允許控制寄存器IE中的第7位bit7:EA中斷允許總控制
ET0 = 1; //中斷允許控制寄存器IE中的第1位bit1:ET0定時器/計數器T0的溢出中斷允許位
TH0 = 0x1F; //這裏是高8位與低5位:0001 1111 xxxx0 1000
TL0 = 0x08; //裝入初始化值
TR0 = 1;
while(1)
{
}
}
實例2:
#include <AT89X52.h>
sbit Signal = P2 ^ 0;
//初始控制寄存器
//TL0中斷服務子函數,使用通用工作寄存器組1
void Timer0(void) interrupt 1 using 1
{
Signal = 0;
TR0 = 0; //停止定時器TL0
TL0 = 0xCE;
}
//TH0中斷服務子函數,佔用定時計數器1的中斷向量,使用通用工作寄存器組2
void Timer1(void) interrupt 3 using 2
{
Signal = 1;
TR0 = 1; //啓動定時器TL0
TH0 = 0x38;
}
main()
{
TMOD = 0x03; //定時/計數器的方式和控制寄存器TMOD
//0000 0011 定時器1工作在模式0、定時器0工作在模式3 ,它們都工作在定時模式
EA = 1;
ET0 = 1;
ET1 = 1;
TH0 = 0x38;
TL0 = 0xCE;
Signal = 1;
TR0 = 1;
TR1 = 1; //啓動兩個定時器
while(1)
{
}
}
實例3:
#include <AT89X52.h>
sbit LED1 = P2^0; //外部LED驅動引腳定義
void Timer0(void) interrupt 1 using 1 //定時計數器0中斷處理函數
{
LED1 = ~LED1; //如果有中斷,LED翻轉
}
main()
{
TMOD = 0x06; //定時/計數器的方式和控制寄存器
//0000 0110 定時計數器0 工作方式2 計數模式
TH0 = 0xFD;
TL0 = 0xFD;
EA = 1;
ET0 = 1; //打開相應中斷
TR0 = 1;
while(1)
{
}
}