一、學習定時器之前需要明白:
1、51單片機有兩組定時器/計數器,因為既可以定時,又可以計數,故稱之為定時器/計數器。
2、定時器/計數器和單片機的CPU是相互獨立的。定時器/計數器工作的過程是自動完成的,不需要CPU的參與。
3、51單片機中的定時器/計數器是根據機器內部的時鍾或者是外部脈沖信號對寄存器中的數據加1
4、有了定時器/計數器之后,可以增加單片機的效率,一些簡單的重復加1的工作可以交給定時器/計數器處理。CPU轉而處理一些復雜的事情。 同時可以實現精確定時作用
二、定時計數器 工作原理
定時計數器實質上是一個加1計數器。它隨着計數器的輸入脈沖進行自加1,也就是每來一個脈沖,計數器就自動加1,,當加到計數器為全1時,再輸入一個脈沖就使計數器回零,且計數器的溢出相 應的中斷標志位置1,向CPU發出中斷請求(定時/數器中斷允許時)
如果定時計數器工作於定時模式,則表示定時時間已到;如果工作於計數模式,則表示計數值已滿。可見,由溢出時計數器的值減去計數初值才是加1計數器的計數值。
三、定時計數器的結構:
由 加1計數器(16位,即2個字節),由高8位和低8位兩個寄存器 THx 和 TLx 組成。
TMOD是定時/計數器的工作方式寄存器,確定工作方式和功能;
TCON是控制寄存器,控制T0、T1的啟動和停止及設置溢出標志
四、定時計數器的控制
51單片機定時/計數器的工作由兩個特殊功能寄存器控制。TMOD用於設置其工作方式;TCON用於控制其啟動和中斷申請。
【1】工作方式寄存器 TMOD
工作方式寄存器TMOD用於設置定時計數器的工作方式,低四位用於T0,高四位用於T1。其格式如下
1、GATE是門控位
Δ 當GATE=0時,用於控制定時器的啟動是否受外部中斷源信號的影響。只要用軟件使 TCON 中的 TR0 或 TR1 為1,就可以啟動定時計數器工作; (常用此方法)
Δ當GATA=1時,要用軟件使 TR0 或 TR1 為1,同時外部中斷引腳 INT0/1 (如下圖 中斷系統部分圖 )也為高電平時,才能啟動定時/計數器工作。即此時定時器的啟動條件,加上了 INT0/1 引腳為高電平這一條件
2、 C/T : 定時/計數模式選擇位( C/T=0為定時模式; C/T=1為計數模式)
3、M1M0 :工作方式設置位 ,定時/計數器有四種工作方式(如下圖):
[通常用 方式1(16位定時計數器)和方式2(8位自動重裝定時計數器,常用於計算頻率和串口通信使用)]
【2】控制寄存器 TCON
TCON的低4位用於控制外部中斷(在中斷系統已介紹),TCON的高4位用於控制 定時計數器的啟動和中斷中請。其格式如下
1、TF1(TCON.7) : T1溢出中斷請求標志位.
T1 計數溢出時由硬件自動置 TF1 為1。CPU響應中斷后 TF1 由硬件自動清0。
T1工作時,CPU可隨時查詢 TF1 的狀態(TF1可用作查詢測試的標志).
TF1 也可以用軟件置1或清0,同硬件置1或清0的效果一樣。
2、TR 1(TCON6): T1 運行控制位.
TR1 置1時,T1開始工作;TR置0時T1停止工作
TR1 由軟件置1或清0 (所以,用軟件可控制定時計數器的啟動與停止)
3、TF0 (TCON5): T0 溢出中斷請求標志位,其功能與 TF1 類同。
4、TR0 (TCON4): T0運行控制位,其功能與 TR 1類同。
五、定時計數器的工作方式
【1】方式 0 (13位計數)
1、若為定時器 T1:由TL0 的低5位(高3位未用)和 TH0 的8位組成 ;
TL0的低5位溢出時,向 TH0 進位;TH0溢出時,置位 TCON 中的 TF0 標志(置1),向CPU發出中斷請求。
2、若為定時器 T2:TH1 溢出時,置位 TCON 中的 TF1 ( 與定時器 T1類同)
♦定時器模式
Δ 計算公式:N=t/Tcy ;計數初值計算的公式為:X=2^13-N.(定時器為 13 位)
定時器的初值還可以采用計數個數直接取補法獲得。
Δ 計數模式時,計數脈沖是T0(單片機 P3 口的T0引腳)上的外部脈沖。
Δ 門控位GATE(有特殊的作用):
當GATE=0時,經反相后使或門輸出為1,此時僅由TRO控制與門的開啟,與門輸出 1時,控制開關接通,計數開始;
當GATE=1時,由外中斷引腳信號控制或門的輸出,此時控制與門的開啟由外中斷引腳信號和TRO共同控制。當TRO=1時,外中斷引腳信號 引腳的高電平啟動計數,外中斷引腳信號 引腳的低電平停止計數。(此方式常用
來測量外中斷引腳上正脈沖的寬度)→看下圖
【2】方式 1(計數位數是16位)
定時器T1:由TL0作為低8位,TH0 作為高8位,組成了16位加1計數器(定時器T2 類同)
計數個數與計數初值的關系:X=2^16-N
【3】方式 2 (自動重裝初值的8位計數方式)
計數個數與計數初值的關系: X=2^8- N . (該方式適合用作較精確的脈沖信號發生器)
【4】方式 3 (只適用於定時計數器 T0)
定時器 T1 處於方式3時,相當於 TR1=0,停止計數
工作方式3 將 T0 分成為兩個獨立的 8位計數器 TL0 和 TH0
六、使用定時器的程序
初始化程序應完成:
1、對TMOD賦值,以確定 T0 和 T1 的工作方式(以及方式 0、1、2、3?定時器還是計數器模式?)
2、計算初值,並將其寫入TH0、TL0 或TH1、 TL1
3、中斷方式時,則對總中斷 EA 賦值,開放定時器中斷
4、使 TR0 或 TR1 置位,啟動定時計數器 定時或計數
七、與CPU 時序有關的知識
振盪周期:為單片機提供定時信號的振盪源的周期( 晶振周期或外加振盪周期)→T(振盪) =1/ f= 1/12MHZ
狀態周期:2個振盪周期為1個狀態周期,用S表示。振盪周期又稱S周期或時鍾周期 .→T(狀態)=1/6MHZ
機器周期:1個機器周期含6個狀態周期,12個振盪周期。 → T(機器)=12/12MHZ = 1 us (微秒)
指令周期:完成1條指令所占用的全部時間,它以機器周期為單位
八、計數器初值的計算
1、機器周期也就是CPU完成一個基本操作所需要的時間
2、機器周期=1/單片機的時鍾頻率
3、51單片機內部時鍾頻率是外部時鍾的12分頻。也就 是說當外部晶振的頻率輸入到單片機里面的時候要進行12分頻。比如說你用的是12MHZ的晶振,那么 單片機內部的時鍾頻率就是12/12MHZ,當你使用 12MHZ的外部晶振的時候。機器周期=1/1M=1us.
4、定時1ms的初值是多少呢,1ms/1us=1000.也就是要計數1000個數,初值=65535-1000+1(因為實際上計數器計數到66636才溢出)=64536(十進制)=FC18H (十六進制)
單片機工作方式為1 由公式X=2^16-N (N = 1000)得 X= 65536 - 1000=64536
九、程序示例(定時器 0 實現功能:D1小燈循環點亮1秒,熄滅1秒)
#include "reg52.h" //此文件中定義了單片機的一些特殊功能寄存器 typedef unsigned int u16; //對數據類型進行聲明定義 typedef unsigned char u8; sbit led=P2^0; //定義P20口是led

GATE =0; C/T=0 為定時模式; M1M0為01 即工作方式1(16位定時計數器)
程序:
void Timer0Init() { TMOD|=0X01;//或運算(看上圖)選擇為定時器 0 模式,工作方式1,僅用TR0打開啟動。 TH0=0XFC; //給定時器賦初值,定時1ms TL0=0X18; (看下圖) →(打開 常用輔助開發軟件→51定時器計算→選擇 定時器工作方式 →晶振頻率 12 MHZ→ 選擇定時時長,即可得到類似 FC18H) ET0=1;//打開定時器0中斷允許(中斷系統的內容) EA=1;//打開總中斷 TR0=1;//打開定時器 }


void main() { Timer0Init(); //定時器0初始化 while(1); } void Timer0() interrupt 1 //(中斷號)中斷函數 { static u16 i; TH0=0XFC; //給定時器賦初值,定時1ms TL0=0X18; i++; // i 增加一次,定時1ms if(i==1000) // i累加了1000, 則定時了 1s { i=0; led=~led; // led 翻轉較簡單,可放在 中斷里 } }