使用內部T2定時器製作時鐘
目標:
使用89c52內部T2定時器製作時鐘,每10ms中斷一次,自動裝載初值,向上計數溢出。
定時器2的資料:
T2的控制寄存器的功能描述如下:
T2CON(T2的控制寄存器),字節地址0C8H:
位地址 0CFH 0CEH 0CDH 0CCH 0CBH 0CAH 0C9H 0C8H
符 號 TF2 EXF2 RCLK TCLK EXEN2 TR2 C/T2 CP/RT2
各位的定義如下:
TF2:定時/計數器2溢出標誌,T2溢出時置位,並申請中斷。只能用軟件清除,但T2作爲波特率發生器使用的時候,(即RCLK=1或TCLK=1),T2溢出時不對TF2置位。
EXF2:當EXEN2=1時,且T2EX引腳(P1.0)出現負跳變而造成T2的捕獲或重裝的時候,EXF2置位並申請中斷。EXF2也是隻能通過軟件來清除的。
RCLK:串行接收時鐘標誌,只能通過軟件的置位或清除;用來選擇T1(RCLK=0)還是T2(RCLK=1)來作爲串行接收的波特率產生器
TCLK:串行發送時鐘標誌,只能通過軟件的置位或清除;用來選擇T1(TCLK=0)還是T2(TCLK=1)來作爲串行發送的波特率產生器
EXEN2:T2的外部允許標誌,只能通過軟件的置位或清除;EXEN2=0:禁止外部時鐘觸發T2;EXEN2=1:當T2未用作串行波特率發生器時,允許外部時鐘觸發T2,當T2EX引腳輸入一個負跳變的時候,將引起T2的捕獲或重裝,並置位EXF2,申請中斷。
TR2:T2的啓動控制標誌;TR2=0:停止T2;TR2=1:啓動T2
C/T2:T2的定時方式或計數方式選擇位。只能通過軟件的置位或清除;C/T2=0:選擇T2爲定時器方式;C/T2=1:選擇T2爲計數器方式,下降沿觸發。
CP/RT2:捕獲/重裝載標誌,只能通過軟件的置位或清除。CP/RT2=0時,選擇重裝載方式,這時若T2溢出(EXEN2=0時)或者T2EX引腳(P1.0)出現負跳變(EXEN2=1時),將會引起T2重裝載;CP/RT2=1時,選擇捕獲方式,這時若T2EX引腳(P1.0)出現負跳變(EXEN2=1時),將會引起T2捕獲操作。但是如果RCLK=1或TCLK=1時,CP/RT2控制位不起作用的,被強制工作於定時器溢出自動重裝載模式。
T2MOD(方式寄存器),字節地址0C9H:
D7 D6 D5 D4 D3 D2 D1 D0
-- -- -- -- -- -- T2OE DCEN
T2OE:T2輸出允許位,當T2OE=1的時候,允許時鐘輸出到P1.0。(僅對80C54/80C58有效)
DCEN:向下計數允許位。DCEN=1是允許T2向下計數,否則向上計數。
T2的數據寄存器TH2、TL2和T0、T1的用法一樣,而捕獲寄存器RCAP2H、RCAP2L只是在捕獲方式下,產生捕獲操作時自動保存TH2、TL2的值。
以上是T2的相關寄存器的描述,其實用法上跟T0、T1是差不多的,只是功能增強了,設置的東西多了而已。
定時/計數器2其實用到最多的就是T2CON這個寄存器啦,它設定的定時和計數的方式。有三種工作方式,捕獲,自動重裝,波特率發生器。下面我是在百度百科裏面找的少許資料:
捕獲方式:
在捕獲方式下,通過T2CON 控制位EXEN2 來選擇兩種方式。如果EXEN2=0,定時器2 是一個16 位定時器或計數器,計數溢出時,對T2CON 的溢出標誌TF2 置位,同時激活中斷。如果EXEN2=1,定時器2 完成相同的操作,而當T2EX 引腳外部輸入信號發生1 至0 負跳變時,也出現TH2 和TL2 中的值分別被捕獲到RCAP2H 和RCAP2L 中。另外,T2EX 引腳信號的跳變使得T2CON 中的EXF2 置位,與TF2 相仿,EXF2 也會激活中斷。捕獲方式如圖4 所示。
自動重裝載(向上或向下計數器)方式:
當定時器2工作於16位自動重裝載方式時,能對其編程爲向上或向下計數方式,這個功能可通過特殊功能寄存器T2CON(見表5)的DCEN 位(允許向下計數)來選擇的。復位時,DCEN 位置“0”,定時器2 默認設置爲向上計數。當DCEN置位時,定時器2 既可向上計數也可向下計數,這取決於T2EX 引腳的值,參見圖5,當DCEN=0 時,定時器2 自動設置爲向上計數,在這種方式下,T2CON 中的EXEN2 控制位有兩種選擇,若EXEN2=0,定時器2 爲向上計數至0FFFFH 溢出,置位TF2 激活中斷,同時把16 位計數寄存器RCAP2H 和RCAP2L重裝載,RCAP2H 和RCAP2L 的值可由軟件預置。若EXEN2=1,定時器2 的16 位重裝載由溢出或外部輸入端T2EX 從1 至0 的下降沿觸發。這個脈衝使EXF2 置位,如果中斷允許,同樣產生中斷。
定時器2 的中斷入口地址是:002BH ——0032H 。
當DCEN=1 時,允許定時器2 向上或向下計數,如圖6 所示。這種方式下,T2EX 引腳控制計數器方向。T2EX 引腳爲邏輯“1”時,定時器向上計數,當計數0FFFFH 向上溢出時,置位TF2,同時把16 位計數寄存器RCAP2H 和RCAP2L重裝載到TH2 和TL2 中。 T2EX 引腳爲邏輯“0”時,定時器2 向下計數,當TH2 和TL2 中的數值等於RCAP2H 和RCAP2L中的值時,計數溢出,置位TF2,同時將0FFFFH 數值重新裝入定時寄存器中。
當定時/計數器2 向上溢出或向下溢出時,置位EXF2 位。
波特率發生器:
當T2CON(表3)中的TCLK 和RCLK 置位時,定時/計數器2 作爲波特率發生器使用。如果定時/計數器2 作爲發送器或接收器,其發送和接收的波特率可以是不同的,定時器1 用於其它功能,如圖7 所示。若RCLK 和TCLK 置位,則定時器2工作於波特率發生器方式。
波特率發生器的方式與自動重裝載方式相仿,在此方式下,TH2 翻轉使定時器2 的寄存器用RCAP2H 和RCAP2L 中的16位數值重新裝載,該數值由軟件設置。
在方式1 和方式3 中,波特率由定時器2 的溢出速率根據下式確定:
方式1和3的波特率=定時器的溢出率/16
定時器既能工作於定時方式也能工作於計數方式,在大多數的應用中,是工作在定時方式(C/T2=0)。定時器2 作爲波特率發生器時,與作爲定時器的操作是不同的,通常作爲定時器時,在每個機器週期(1/12 振盪頻率)寄存器的值加1,而作爲波特率發生器使用時,在每個狀態時間(1/2 振盪頻率)寄存器的值加1。波特率的計算公式如下:
方式1和3的波特率=振盪頻率/{32*[65536-(RCP2H,RCP2L)]}式中(RCAP2H,RCAP2L)是RCAP2H 和RCAP2L中的16 位無符號數。
定時器2 作爲波特率發生器使用的電路如圖7 所示。T2CON 中的RCLK 或TCLK=1 時,波特率工作方式纔有效。在波特率發生器工作方式中,TH2 翻轉不能使TF2 置位,故而不產生中斷。但若EXEN2 置位,且T2EX 端產生由1 至0 的負跳變,則會使EXF2 置位,此時並不能將(RCAP2H,RCAP2L)的內容重新裝入TH2 和TL2 中。所以,當定時器2 作爲波特率發生器使用時,T2EX 可作爲附加的外部中斷源來使用。需要注意的是,當定時器2 工作于波特率器時,作爲定時器運行(TR2=1)時,並不能訪問TH2 和TL2。因爲此時每個狀態時間定時器都會加1,對其讀寫將得到一個不確定的數值。
然而,對RCAP2 則可讀而不可寫,因爲寫入操作將是重新裝載,寫入操作可能令寫和/或重裝載出錯。在訪問定時器2或RCAP2 寄存器之前,應將定時器關閉(清除TR2)。
T2定時器程序編寫流程
T2定時器設置步驟:
第一步:設置T2MOD確定工作方式【向下計數法】
第二步:裝初值【10ms一次中斷】
第三步:中斷運行方式
第四步:開中斷
第五步:中斷服務程序:
項目實測:
中斷服務程序中採用定時器2自動重裝初值,雖然已經完全消除了“裝值”產生的時間誤差,但是在進入中斷,出中斷這個過程中還是產生了時間上的微小誤差。由此帶來的軟件誤差爲每10ms有1us的時間誤差出現。這在程序中已經修正!到此,在軟件上這個程序是絕對精準,但是由於硬件質量及環境等因素影響,依然產生了硬件誤差。
下表是統計了24個小時之後得出的彙總:
說明:在2013年08月26日晚21:33:45開始啓動時鐘測試
起始時間 |
此時北京時間 |
北京時間時間差 |
時鐘上的時間 |
誤差 |
21:33:45 |
7:53:48 |
10:20:03 |
10:20:00 |
-3 |
21:33:45 |
7:58:45 |
10:25:00 |
10:24:57 |
-3 |
21:33:45 |
9:31:15 |
11:57:30 |
11:57:26 |
-4 |
21:33:45 |
9:31:45 |
11:58:00 |
11:57:56 |
-4 |
21:33:45 |
9:33:49 |
12:00:04 |
12:00:00 |
-4 |
21:33:45 |
9:34:09 |
12:00:24 |
12:00:20 |
-4 |
21:33:45 |
15:09:25 |
17:35:40 |
17:35:34 |
-6 |
21:33:45 |
15:09:41 |
17:35:56 |
17:35:50 |
-6 |
21:33:45 |
21:30:25 |
23:56:25 |
23:56:32 |
-7 |
21:33:45 |
21:30:48 |
23:57:03 |
23:56:55 |
-8 |
21:33:45 |
21:31:08 |
23:57:23 |
23:57:15 |
-8 |
由此表記錄的數據及觀察白天可以得出一個結論:硬件誤差是每三個小時時鐘慢一秒鐘。此處是人眼記錄,可能偏差較大,但是不會超過300ms。到此此時鐘硬件誤差也得到修正,實際上還可以繼續修正硬件誤差,只是比較費時費力,需要統計一個月,再統計一年的誤差,再修正。到目前爲止,此時鐘已是相當精準的,未硬件誤差修正之前一年的誤差爲48分鐘6秒,修正之後,可以確保一年的時間誤差在5分鐘之內。