新版51單片機內(nèi)部有3個16位可編程的定時器/計數(shù)器,即定時器T0,T1,T2。他們既有定時功能又有計數(shù)功能,我們可以通過配置與它們相關(guān)的特殊功能寄存器可以選擇啟用定時功能或計數(shù)功能;其中需要注意的是,這個定時器系統(tǒng)是單片機內(nèi)部的一個獨立的硬件部分,它與CPU和晶振通過內(nèi)部某些控制線連接并起作用,CPU一旦設(shè)置開啟定時器功能后,定時器便在晶振的作用下自動開始計時,當定時器的計數(shù)器計滿后,會產(chǎn)生中斷,即通知CPU該如何處理。
定時器/計數(shù)器的實質(zhì)是加1計數(shù)器(16位),由高8位和低8位兩個寄存器組成。TMOD是定時器/計數(shù)器的工作方式寄存器,確定工作方式和功能;TCON是控制寄存器,控制T0和T1的啟動或停止及設(shè)置溢出標志。其結(jié)構(gòu)框圖如下:
?加1計數(shù)器輸入的計數(shù)脈沖有兩個來源,一個是由系統(tǒng)的時鐘振蕩器輸出脈沖經(jīng)12分頻后送來;另一個是T0或TI引腳輸入的外部脈沖源,每來一個脈沖計數(shù)器加1,當加到計數(shù)器為全1時,再輸入一個脈沖就使計數(shù)器回0,且計數(shù)器的溢出使TCON寄存器中TF0或TF1置1,項CPU發(fā)送中斷請求(定時器/計數(shù)器中斷允許時)。如果定時器/計數(shù)器工作于定時模式,則表示定時時間已到;如果工作于計數(shù)模式,則表示計數(shù)值已滿。
因此,由溢出時計數(shù)器的值Nt - 計數(shù)初值N0 = 加1計數(shù)器的計數(shù)值N
①設(shè)置為定時器模式時,加1計數(shù)器是對內(nèi)部機器周期計數(shù)(1個機器周期等于12個振蕩周期,計數(shù)頻率是晶振頻率的1/12)。計數(shù)值N 乘 機器周期T就是定時時間(機器周器:CPU完成一個基本操作所需時間)。
②設(shè)置為計數(shù)器模式時,外部事件計數(shù)脈沖由T0或T1引腳輸入到計數(shù)器。在每個機器周期的S5P2期間采樣T0或T1電平。當某周期采樣到一高電平輸入,而下一周期又采樣到一低電平時,則計數(shù)器加1,更新的計數(shù)值在下一機器周期的S3P1期間裝入計數(shù)器。
知識點:
①定時器/計數(shù)器工作方式寄存器TMOD,用來確定定時器的工作方式及功能選擇,不能位尋址,單片機復(fù)位時寄存器全部清零。
位序號 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
位符號 | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
紅色高四位為定時器T1,綠色低四位定時器T0。
GATE——門控制位
GATE = 0,定時器/計數(shù)器啟動與停止僅受TCON寄存器中TRX(X = 0,1)控制。
GATE = 1,定時器/計數(shù)器啟動與停止由TOCN寄存器中TRX(X= 0,1)和外部中斷引腳(INT0或INT1)上的電平狀態(tài)來控制。
C/T——定時器模式和計數(shù)器模式選擇位。
C/T = 1,為計數(shù)器模式;C/T = 0,為定時器模式。
M1M0——工作方式選擇位
每個定時器/計時器都有4種工作方式,它們有M1M0設(shè)定,具體情況如下:
M1 | M0 | 工作方式 |
0 | 0 | 方式0,為13位定時器/計數(shù)器 |
0 | 1 | 方式1,為16位定時器/計數(shù)器 |
1 | 0 | 方式2,8位初值自動重裝的8位定時器/計數(shù)器 |
1 | 1 | 方式3,僅適用于T0,分成兩個8位計數(shù)器,T1停止計數(shù) |
②定時器/計數(shù)器控制寄存器TCON,用來控制定時器的啟、停以及標志定時器溢出和中斷情況,可以位尋址,單片機復(fù)位時TCON全部被清零。
位序號 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
位符號 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
位地址 | 8FH | 8EH | 8DH | 8CH | 8BH | 8AH | 89H | 88H |
?TF1——定時器1溢出標志位
當定時器1計滿溢出時,由硬件使TF1置1,并且申請中斷。進入中斷服務(wù)程序后,由硬件自動清零,需要注意的是,如果使用定時器的中斷,那么該位完全不用人為去操作,但是如果使用軟件查詢的方式的話,當查詢到該位置1后,就需要用軟件清零。
TR1——定時器1運行控制位
由軟件清零關(guān)閉定時器1。當GATE = 1,且INT1為高電平時,TR1置1啟動定時器1;當GATE = 0時,TR1置1啟動定時器1。
TF0——定時器0溢出標志,其功能及操作方法同TF1。
TR0——定時器0運行控制位,其功能及操作方法同TR1。
IE1——外部中斷1請求標志、IT1——外部中斷1觸發(fā)方式選擇位。
當IT1 = 0時,為電平觸發(fā)方式,每個機器周期的S5P2采樣INT1引腳,若INT1腳為低電平,則置1,否則IE1清零。
當IT1 = 1時,INT1為跳變沿觸發(fā)方式,當?shù)谝粋€機器周期采樣到INT1為低電平時,則IE1置1。IE1 = 1,表示外部中斷1正在向CPU申請中斷。IE1 = 1,表示外部中斷1正在向CPU申請中斷。當CPU響應(yīng)中斷,轉(zhuǎn)向中斷服務(wù)程序時該位由硬件清零。
IE0——外部中斷0請求標志,IT0——外部中斷0觸發(fā)方式選擇位,該功能操作方法同IE1,IT1。
下面是定時器工作方式1和2的具體工作原理:
方式一
工作原理
采用方式1時,計數(shù)位數(shù)時16位,由TH0作為高八位,TL0 作為低八位,組成16位加一計數(shù)器,在TR0 置1后單片機開始計時,每經(jīng)過一個機器周期單片機輸出一個脈沖使定時器加一,加到16位全為1時會溢出,使TF0 置1,利用此性質(zhì)可以去執(zhí)行相應(yīng)的功能,TF0置1是一個信號。
若 TH0 和 TL0 的初值都為0(即整個定時器的值為0000000000000000),當16位全為1時,單片機一共輸出了65535個脈沖,再來一個脈沖計數(shù)器就溢出,時間經(jīng)過了65536*12/12M秒鐘即為65.536ms。
初值的設(shè)定
那么問題來了,我們想要利用的時間都是1s,2s這種,而不是65.536ms,如果能讓開始計時到TF0 置1這個時間變成50ms這種,就能夠通過幾次計數(shù)溢出達到計時1s鐘的目的,這就到了初值的計算。
由之前的分析可知,單次計時最長為65.536ms,以單次定時50ms(0.05s)為例,需要20次可以定時1s鐘。假設(shè)開始計時時16位定時器的初值為x,由于單片機定時固定到達65536溢出,那么(65536-x)*12/12M = 0.05,可計算得到x = 15536?;癁?6進制為0x3cb0。那么TH0 = 0x3c, TL0 = 0xb0;把15536/256 = 60(0x3c)裝入TH0中,把15536%256 = 176(0xb0)裝入TL0中。
代碼實現(xiàn)
定時1s鐘的代碼如下:
#include<reg52.h>
void main()
{
unsigned char cnt = 0;
TMOD = 0x01; //設(shè)置定時器為工作方式1
TH0 = 0x3c;
TL0 = 0xb0; //設(shè)置初值
TR0 = 1; //打開定時器開關(guān),開始定時
while(1)
{
if(TF0 == 1)
{
TF0 = 0;
TH0 = 0x3c;
TL0 = 0xb0;
//單次計時完成后,TH0 與TL0 的值均為11111111,所以需要對他們重新賦初值
cnt++;
if(cnt == 20)
{
cnt = 0;
//此處填寫定時完成時要執(zhí)行的功能
}
}
}
}
方式二
工作原理
方式2是自動重裝初值的8位計數(shù)方式,在本質(zhì)上是與方式1一樣的。在工作方式2中,TH0 只起到為TL0 重裝初值的作用,并不參與計數(shù)。當TL0 計數(shù)到全為1時再有一個脈沖就會觸發(fā)溢出,TL0 的溢出不僅使TF0 置1,TF0置1是一個信號 ,而且將TH0內(nèi)容重新裝入TL0 ,TH0 內(nèi)容由代碼設(shè)置,重裝時值不變,然后進行新一輪的定時 ,這就是所謂方式2自動重裝初值。
初值的設(shè)定
方式2的初值的計算方式和方式1相同,與方式1不同的是:由于方式2只有TL0 計數(shù),最多可以記256個脈沖(8位從全0編為全1),單次定時最長也就只有0.256ms(方式1為65.536ms)
依然以定時1s鐘為例,單次定時時間為0.2ms,設(shè)初值為x,(256-x)*12/12M = 0.2**10-3(0.2乘10的-3次方,由于格式問題只能打兩個星號……),解得x = 56,化為十六進制為0x38,則TH0 和TL0 的初值均為0x38;
代碼實現(xiàn)
#include<reg52.h>
void main()
{
unsigned int cnt = 0;
TMOD = 0x02;
TH0 = 0x38;
TL0 = 0x38;
TR0 = 1;
if(TF0 == 1)
{
TF0 = 0;
//TH0 = 0x38;
//TL0 = 0x38; 這兩處由于是自動重裝初值,所以單次定時結(jié)束后不需要再賦值
cnt++;
if(cnt == 5000)
{
cnt = 0;//單次定時0.2ms,5000次后定時1s
//此處填寫定時完成時要執(zhí)行的功能
}
}
}
③中斷服務(wù)程序格式:
void T1_time_() interrupt 中斷號
{
中斷服務(wù)程序內(nèi)容
}
中斷函數(shù)不能返回任何值,所以最前面用void;后面緊跟函數(shù)名,名字可以隨便起,但不要與C語言中的關(guān)鍵字相同;中斷函數(shù)不帶任何參數(shù),所以后面的小括號內(nèi)為空;中斷號是指單片機中幾個中斷源的序號,這個必須寫對。
例子:
void T1_time() interrupt 3
{
TH1 = (65536-10000)/256;
TL1 = (65536-10000)%256
}
?上面的代碼是一個定時器1的中斷服務(wù)程序,定時器1的中斷序號為3,因此我們要寫成interrupt 3,服務(wù)程序內(nèi)容是給兩個寄存器裝入初值。
寫代碼總結(jié):
在寫單片機的定時器程序時,在程序開始處需要對定時器及中斷寄存器做初始化配置,通常定時器初始化過程如下:
①對TMOD賦值,以確定T0和T1的工作方式。
②計算初值,并將初值寫入TH0、TL0或TH1、TH1。
③寫中斷方式,則對IE(中斷允許寄存器)賦值,開放中斷,必要時,還得寫中斷優(yōu)先級(IP)。
④使TR0或TR1置位,啟動定時器/計數(shù)器定時或計數(shù)
如果使用軟件查詢方式的話
⑤TF0 = 0;? //清除TF0標志文章來源:http://www.zghlxwxcb.cn/news/detail-409613.html
? ? TF1= 0; //清楚TF1標志文章來源地址http://www.zghlxwxcb.cn/news/detail-409613.html
到了這里,關(guān)于51單片機——定時器中斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!