【C51】單片機定時器介紹
標準51架構(gòu)的單片機有2個定時器 :T0 和 T1,他們2個的用法幾乎一樣。下面主要講T0定時器的用法。
初步認知定時器 和 計數(shù)器 都是單片機中同一個模塊。他們的實質(zhì)都是: 加法存儲計數(shù)器。對于計數(shù)器很好理解,每來一個信號(信號從P3.4 或者P3.5輸入),就加1,以此達到計數(shù)的目的。
對于定時器,每隔1個機器周期 加 1,假如(只是假如)一個機器周期為 1ms , 當加到1000時,我們就認為經(jīng)過了1s,這就是定時器的原理。
加法存儲寄存器THx & TLx
定時器依賴計數(shù),需要把累計增加的那個量存儲在某個地方,這就是THx和TLx(x 可以是 0 或者1)2個8位寄存器的的職責。
T0和T1都擁有一對加法存儲寄存器。
T0 對應(yīng):TH0,TL0
T1 對應(yīng) : TH1 , TL1
在reg51.h頭文件中我們發(fā)現(xiàn)這4個寄存器的定義:
sfr TL0 = 0x8A; // TL中的L是LOW的意思,代表低位,同理H代表HIGH高位。 sfr TL1 = 0x8B; sfr TH0 = 0x8C; sfr TH1 = 0x8D;
他們可以在程序中直接使用,復位值都是 0 。
當一直累加,使得他們保存不了太大的數(shù)據(jù)而發(fā)生溢出時,就會引發(fā)中斷(后面講中斷)。并且對應(yīng)的TFx溢出標志位會置為1,(沒有溢出的情況下是0)。
如果不使用中斷去處理溢出這個事件,那么我們就必須通過代碼指令讓TFx重置為 0 ,并讓THx和TLx回歸初始值,準備然后進入下一輪周期的計數(shù)。
.... if(TF0==1) //如果T0 溢出了 { TF0=0; //重新初始化 TH0 和 TL0 //說明過了一個溢出周期了 }
2個重要的寄存器:TMOD 和 TCON
復位時所有位全 為 0
TFx:溢出標志位。溢出時置1。正常為0。
TRx:計數(shù)器/定時器 啟動停止控制位 。R是run的意思。 TR0 = 1 開啟定時器0,為TR0 = 0 則停止。
低4位與外部中斷相關(guān),這里用不到,先不用看。
復位時所有位全 為 0
高4位是定時器T1相關(guān)的,低4位是T0 相關(guān)的。
以T0來說明。
GATE: 門控制位
C/T : 定時器/計數(shù)器切換位。 1為計數(shù)器模式, 0 為定時器模式。
②處 C/T = 0 表示為定時器模式,觸發(fā)信號為①處的單片機內(nèi)部時鐘信號。(若②處CT = 1,則觸發(fā)信號為Tn腳,信號從P3.4 或者P3.5輸入單片機)
③處表明,信號能觸發(fā)使加法計數(shù)器加1,還得受④處控制。不然時鐘信號是不能讓加法計數(shù)器累加的。 ④處這個是與門,TRn必須為1,表明我們要開啟定時器。同時GATE為0,通過非門后為1,再通過或門,也是1,那么就讓③處控制起來了。
(若GATE為1,那么,定時器的啟動停止受 TRx和 INTx 共同控制。 )
于是我們需要:
TRn 為 1
GATE 為 0
INTn 為 X(X表示任意的意思,do not care)
加法存儲寄存器的工作模式,是由M0和M1共同來決定的
M1 M0 模式0 1 TH和TL2個組成16位計數(shù)存儲器模式
1 0 TH負責初始化TL,TL計數(shù)。8位重裝模式
0 0 THx的8位和TLx的位5組成13位加法計數(shù)器(很少用)
1 1 基本不用
時鐘周期和機器周期
順便提一下:標準C51的1個機器周期為12個時鐘周期(增強型51單片機的機器周期會短一些,cc2530只有的機器周期只等于1個時鐘周期)。
如果晶振的頻率是11.0592MHz,那么時鐘周期就是 1 / (11.0592x10^6) 秒 (1MHz = 10^6Hz)
那么,無論是定時器,還是計數(shù)器,每隔1個機器周期 ,加法存儲器就1,代表時間經(jīng)過了 12 x 1 / (11.0592x10^6) 秒。這就是我們衡量的基礎(chǔ)依據(jù)。
為THx和TLx賦初始值
若TH0 和 TL0 以 16位 模式工作,那它的計數(shù)范圍為 [0 , 65535 ] , 也就是累加 65536次發(fā)生溢出。 每累加一次是 12 / (11.0592x10^6) 秒。
那么從 0 累加到溢出 歷時 ≈ 0.071s = 71ms 。
我們一般需要延時 10的整數(shù)倍ms,以便用倍數(shù)控制更長的延時時間。所以,我么要給 TH0 和 TL0賦一個初始值,使他們的溢出周期(TH0,TL0從初始值到溢出所用的時間)減少到 10ms,或者1ms。
就像一個瓶子,開始裝了2/3,再來就只能裝1/3就溢出了。
12 / (11.0592x10^6) s ----- 1 次
10x 10-3 s ------ x 次 (求出 x = 9216次 ,計數(shù)9216次后溢出)
65536 - 9216 = 56320 = 二進制( 11011100 00000000)
也就是 TH0 = 11011100 , TL0 = 00000000
代碼例子驗證
#include
8位重裝模式
8位重裝模式是:只有TL0計數(shù),TH0不變,他只為TL0提供初始值。當TL計數(shù)溢出后,TF0就為1,如果繼續(xù)工作,TH0就把自己的值賦給TL0,再開始計數(shù),如此循環(huán)下去。
上面些寫了一個毫秒級的delay函數(shù),下面用8位重裝模式寫一個控制微秒級別的函數(shù)。并控制P0.0的LED實現(xiàn)呼吸燈。
計算方法和上面一樣,大家可以自己算
#include
void delay1ms(uint t); /********************************/ sbit LED = P0^0; void main() { int step = 0; int again = FALSE; while(1) { LED = again?0:1; delay1ms(step); LED = again?1:0;; delay1ms((500-step)); step+=1; if(step>500) { step =0; again = !again; } } } void delay1ms(uint m) //延時t微秒 { int count=0; TMOD = 2; TH0= 255 ; TL0= 255; TR0=1; for(;count!=m;) { if(TF0==1) { TF0=0; //自動重裝 count++; } } TR0=0; }
值得注意的地方
我們應(yīng)該盡量讓溢出周期 越長越好。溢出周期為10ms 的優(yōu)于 1ms 的。因為,在同樣的延時時間下,如100ms,溢出周期為10ms 的 只需要溢出10次,為TH0 和 TL0重新賦值10次,而溢出周期為1ms的要溢出100次,為TH0 和 TL0重新賦值100次。減少溢出次數(shù)和賦值次數(shù),可以減輕單片機的負擔,提高定時的準確性。
/***************************************************/
歡迎轉(zhuǎn)載,請注明出處:
為了獲得更好的閱讀體驗,請訪問原博客地址。
代碼鋼琴家
/***************************************************/
作者:代碼鋼琴家
出處:
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權(quán)利。為了獲得更好的閱讀體驗,請訪問原博客地址。限于本人水平,如果文章和代碼有表述不當之處,還請不吝賜教。
評論
查看更多