定時器/計數器介紹
定時/計數器T0和T1分別是由兩個8位的專用寄存器組成,即定時/計數器T0由TH0和TL0組成,T1由TH1和TL1組成。此外,其內部還有2個8位的特殊功能寄存器TMOD和TCON,TMOD負責控制和確定T0和T1的功能和工作模式,TCON用來控制T0和T1啟動或停止計數,同時包含定時/計數器的狀態。
TF1:定時器1溢出標志。定時/計數器溢出時由硬件置位。中斷處理時由硬件清除。或用軟件清除。
TF0:定時器0溢出標志。定時/計數器溢出時由硬件置位。中斷處理時由硬件清除,或用軟件清除。
在現在很多新MCU中,不只有兩個 定時/計數器,例如STC15系列就有四個定時/計數器,但是在使用上操作上是大同小異的。
定時器內部框圖和結構介紹
定時器/計數器有定時器0(簡稱T0),定時器1(簡稱T1),定時器方式寄存器TMOD和定時器控制寄存器TCON四部分組成。該邏輯框圖如下所示。
紅線
TMOD(工作方式寄存器):從該命名就可也知道,該寄存器控制的是選擇哪一個定時器,T0或者T1。用什么方式,作為定時器使用,還是作為計數器使用。這個都將由TMOD對應的位決定。
由TMOD的2位的C/T和6位的C/T位決定。
藍色
TCON(控制寄存器):控制寄存器的高四位負責管理定時器/計數器和中斷申請,低四位則是負責與外部中斷有關的設置。選擇了定時器的工作方式之后,就需要由一個寄存器來允許它是否可以工作,TCON就是這個功能。
黃色
則是外部計數,外部每產生一個脈沖,計數器加1,當計數器都為一,產生一次溢出。由TH0,TL0(值得是定時器0的高八位和低八位)或者TH1,TH0(值得是定時器1的高八位和低八位
進行累計。就比如需要一個計數器,則就需要由該IO進行計數。
紫色
當定時器1和定時器0計數器累計加一,當計數器全為一的時候,長生一次溢出,向TCON中的TF0或者TF1置1。
綠色
由TCON向CPU申請中斷。
黑色
則是外部中斷直接向CPU進行中斷申請;
寄存器介紹
工作方式寄存器TMOD
GATE:門控衛,當GATE=0時候,只需要在軟件上使TCON置TR0或者TR1為1,既可以啟動定時器/計數器。當GATE=1時,不僅需要在軟件上使TCON置TR0或者TR1為1,還需要由外部中斷引腳INT0————或INT1————為高電平的時候,才能啟動定時器/計數器。
C/T-: 定時器/計數器選擇位, C/T-=1時,為計數模式。C/T-=0時,為定時模式。
M1、M0:工作方式設置位。四種工作方式由M1、M0進行設置。如下表
控制寄存器
TCON的高四位用于控制定時/計數器的啟動和中斷申請。低四位與外部中斷相關,在前面的中斷中已經做了介紹。
TF1:T1中斷溢出中斷請求位。計數溢出時由硬件自動置TF1為1。CPU響應中斷了之后,TF1由硬件自動清0。在T1工作的時候,CPU可以隨時查詢TF1的狀態。
TR1:T1運行控制位。當TR1為1時,則表示T1開始工作。當TR1為0時,則表示T1停止工作。TR1需要由軟件置1或者0;
TF0:T0中斷溢出中斷請求位。功能與TF1相同。
TR0: T0運行控制位。功能與TF1相同。
定時/計數器的工作方式
在新的8051結構的單片機中,2個定時/計數器都有四種工作模式,既通過TMOD的M1和M0選擇。但是在傳統的Intel 8051的單片機中,T0有四種工作方式(方式0、1、2、3),T1有三種工作方式(方式0、1、2),以上除了所使用的寄存器,有關的控制位,標志位不同外,在操作方式上是一樣的。以下就以參見的工作方式1(既計數位數是16位)為例。
方式1
方式1的計數方式是16位,TH0作為高八位, TL0作為第八位。其邏輯結構圖如所示。組成了16位的加一計數器,計數個數和計數初值的關系為:
計數的初值在0 ~ 65535之間,計數范圍為1~65536 。
例如,若要求定時器在T0 的工作模式下,定時時間為1ms。當晶振為6MHZ的時,求送入TH0和TL0的值。由于晶振為6MHZ,所以該機械周期為=12/晶振頻率,即為2us。
將X值寫入TH0和TL0時,分別將X值得高八位賦值給TH0,第八位賦值給TL0,格式如下:
TH0=(65536-5000)/256 //定時器的高八位賦值
TL0=(65536-5000)%256 //定時器的第八位賦值
所以一個該程序部分代碼為:
TMOD=0X01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TF0=0;
TR0=1
使用方式1的工作模式,進行1s的延時,通過LED的閃爍呈現出來。
寫法一
#include < reg51.h >
typedef unsigned char u8;
typedef unsigned int u16;
sbit LED=P2^0;
void delay_1s()
{
u8 num=0;
TMOD=0X01;
TR0=1;
while(1)
{
TH0=(65536-18432)/256;
TL0=(65536-18432)%256;
num++;
do
{
TF0=0;
}while(!TF0);
if (num==25)
{
num=0;
break;
}
}
}
int main()
{
while(1)
{
LED=~LED;
delay_1s();
}
}
寫法二
#include < reg51.h >
typedef unsigned char u8;
typedef unsigned int u16;
sbit LED=P2^0;
u8 num;
void TIM0init(void)
{
TMOD=0x01; //設置定時器0為工作方式0
TH0=(65536-18432)/256;
TL0=(65536-18432)%256;
EA=1; //開總中斷
ET0=1; //開定時器中斷
TR0=1; //啟動定時器0
}
void T0_time() interrupt 1
{
TH0=(65536-18432)/256;//重裝初值,如果不重裝,中斷只觸發一次
TL0=(65536-18432)%256;
num++;
}
/*
interrupt 0 指明是外部中斷0;
interrupt 1 指明是定時器中斷0;
interrupt 2 指明是外部中斷1;
interrupt 3 指明是定時器中斷1;
interrupt 4 指明是串行口中斷;
函數名字可以隨便起,但定時器0的中斷號是固定為1的
*/
void main()
{
TIM0init();
while(1)
{
if(num==25) //如果到了25,說明一秒時間到
{
num=0;
LED=~LED; //讓發光管狀態取反
}
}
}
-
單片機
+關注
關注
6037文章
44558瀏覽量
635235 -
mcu
+關注
關注
146文章
17148瀏覽量
351186 -
計數器
+關注
關注
32文章
2256瀏覽量
94562 -
定時器
+關注
關注
23文章
3248瀏覽量
114792 -
80C51單片機
+關注
關注
4文章
34瀏覽量
18340
發布評論請先 登錄
相關推薦
評論