定時器 / 計數器 LED 應用
STC12C5410AD 系列單片機有 6 個計時器, 其中計時器 0 和計時器 1 兩個 16 位計時器, 與傳統 8051 的計時器完全相容, 也可以設置為 1T 模式, 當在計時器 1 做串列傳輸速率發生器時, 計時器 0 可以當兩個 8 位計時器用 ( 另外 4 路 PCA/PWM 可以再實現 4 個 16 位計時器 ) 當計時器 / 計數器工作在定時模式時, 特殊功能寄存器 AUXR 中的 T0x12 和 T1x12 分別決定是系統時鐘 /12 還是系統時鐘 /1( 不分頻 ) 後讓 T0 和 T1 進行計數 計時器 / 計數器 0 有 4 種工作模式 : 模式 0(13 位計時器 / 計數器 ), 模式 1(16 位計時器 / 計數器模式 ), 模式 2(8 位元自動重裝模式 ), 模式 3( 兩個 8 位計時器 / 計數器 ) 計時器 / 計數器 1 除模式 3 外, 其他工作模式與計時器 / 計數器 0 相同,T1 在模式 3 時無效, 停止計數
計時器 / 計數器的相關寄存器
除 12 T0x12=0 除 1 T0x12=1 Timer C/T=0 Counter C/T=1 ( 從 P3.5(T1),P3.4(T0) 腳輸入 ) 開始計數 :TR=1 且 (INT0=1 或 GATE=0) 當計數到最大 111 時, 再 +1 為 000, 產生 overflow, 設定 TF 旗標, 然後執行中斷
計時器 / 計數器控制寄存器 TCON TF1/TF0: 計時器 / 計數器 T1/T0 溢出標誌 T1/T0 被允許計數以後, 從初值開始加 1 計數 當最高位產生溢出時由硬體置 1 TF1/TF0, 向 CPU 請求中斷, 一直保持到 CPU 回應中斷時, 才由硬體清 0 TF1/TF0(TF1/TF0 也可由程式查詢清 0 ) TR1/TR0: 計時器 T1/T0 的運行控制位 該位元由軟體置位元和清零 當 GATE(TMOD.7/3)=0,TR1/TR0=1 時就允許 T1/T0 開始計數,TR1/TR0=0 時禁止 T1/T0 計數 當 GATE(TMOD.7/3)=1, TR1/TR0=1 且 INT1/0 輸入高電平時, 才允許 T1/T0 計數
計時器 / 計數器控制寄存器 TCON IE1/IE0: 外部中斷 1 請求源 (INT1(P3.3)/INT0(P3.2)) 標誌 IE1/IE0=1, 外部中斷向 CPU 請求中斷, 當 CPU 回應該中斷時由硬體清 0 IE1/IE0 IT1/IT0: 外部中斷 1 觸發方式控制位元 IT1/IT0=0 時, 外部中斷 1 為低電平觸發方式, 當 INT1(P3.3)/INT0(P3.2) 輸入低電平時, 置位 IE1/IE0 採用低電平觸發方式時, 外部中斷源 ( 輸入到 INT1/INT0) 必須保持低電平有效, 直到該中斷被 CPU 回應, 同時在該中斷服務程式執行完之前, 外部中斷源必須被清除 (P3.3/P3.2 要變高 ), 否則將產生另一次中斷 當 IT1/0=1 時, 則外部中斷 1/0(INT1/0) 埠由 1 0 下降沿跳變, 啟動插斷要求標誌位元 IE1/IE0, 向主機請求中斷處理
定時器 / 計數器工作模式寄存器 TMOD GATE:TMOD.7(T1)/TMOD.3(T0) 當 GATE=0, 則 TR=1, 開始計數當 GATE=1, 則 TR=1 且 INT=1, 開始計數 C/T:TMOD.6(T1)/TMOD.2(T0) C/T=0, 用作定時器 ( 從內部系統時鐘輸入 ) C/T=1, 用作計數器 ( 從 P3.5(T1),P3.4(T0) 腳輸入 )
設定定時器 TH & TL TH 和 TL 的設定值為定時器的起始值, 每進來一個脈波 +1, 直到 111 再 +1, 產生 overflow, 然後中斷 如果是模式 1(16bit) 可以計數到 65536 個脈波 若使用 12M 震盪器, 除以 12, 每秒可數 10 6 個脈波 每 ms 可數 10 3 個脈波 每個脈波時間為 10-6 秒 10000 個脈波為 10-2 秒
定時器 / 計數器工作模式寄存器 TMOD M1/M0:TMOD.5/TMOD.4,TMOD.1/TMOD.0 M1 M0 計時器 / 計數器 0 模式選擇 0 0 13 位計時器 / 計數器, 相容 8048 定時模式,TL0 只用低 5 位參與分頻,TH0 整個 8 位全用 0 1 16 位計時器 / 計數器,TL0 TH0 全用 1 0 8 位自動重裝載計時器, 當溢出時將 TH0 存放的值自動 重裝入 TL0 1 1 計時器 0 此時作為雙 8 位計時器 / 計數器 TL0 作為一個 8 位計時器 / 計數器, 通過標準計時器 0 的控制位控制 TH0 僅作為一個 8 位計時器, 由計時器 1 的控制位控制
輔助寄存器 AUXR 計時器 0 和計時器 1 復位後是傳統 8051 的速度, 即 12 分頻, 藉由寄存器 AUXR, 將 T0,T1 設置為 1T T0x12/T1x12: 計時器 0/1 速度控制位 0: 計時器 0 速度是 8051 單片機計時器的速度, 即 12 分頻 ; 1: 計時器 0 速度是 8051 單片機計時器速度的 12 倍, 即不分頻 UART_M0x6: 串口模式 0 的通信速度設置位 0:UART 串口模式 0 的速度是傳統 8051 單片機串口的速度, 即 12 分頻 ; 1 :UART 串口模式 0 的速度是傳統 8051 單片機串口速度的 6 倍, 即 2 分頻
WAKE_CLKO: 時鐘輸出和掉電喚醒 寄存器 T0_PIN_IE /T1_PIN_IE: 掉電模式下, 允許 T0(P3.4)/ T1(P3.5) 腳下降沿置 T0/T1 中斷標誌, 也能使 T0/T1 腳喚醒 powerdown. 0: 禁止 T0(P3.4)/T1(P3.5) 腳下降沿置 T0/T1 中斷標誌, 也禁止 T0/T1 腳喚醒 powerdown ; 1: 允許 T0(P3.4)/T1(P3.5) 腳下降沿置 T0/T1 中斷標誌, 也允許 T0/T1 腳喚醒 powerdown
WAKE_CLKO: 時鐘輸出和掉電喚醒 寄存器 T0CLK0/T1CLKO: 是否允許將 T0(P3.4)/T1(P3.5) 腳配置為計時器 T1 的時鐘輸出 CLKOUT0/CLKOUT1 1: 允許將 T0(P3.4)/T1(P3.5) 腳配置為計時器 T0/T1 的時鐘輸出 CLKOUT0/CLKOUT1, 此時計時器 T0/T1 只能工作在模式 2(8 位元自動重裝模式 ),CLKOUT1 輸出時鐘頻率 = T0/T1 溢出率 /2 T0/T1 工作在 1T 模式時的輸出頻率 =SYSclk/(256 - TH1)/2 T0/T1 工作在 12T 模式時的輸出頻率 =SYSclk/12/(256-TH1)/2 0: 不允許將 T0(P3.4)/T1(P3.5) 腳配置為計時器 T0/T1 的時鐘輸出 CLKOUT1
TIMER 0/1 模式 0(13 位計時器 / 計數器 ) T0 的速率由特殊功能寄存器 AUXR 中的 T0x12 决定, 如果 T0x12=0,T0 则工作在 12T 模式 ; 如果 T0x12=1,T0 则工作在 T1 模式
TIMER 0/1 模式 1(16 位計時器 / 計數器 ) TL0 的 8 位溢出向 TH0 進位,TH0 計數溢出置位 TCON 中的溢出標志位 TF0 當 GATE=0(TMOD.3) 時, 如 TR0=1, 則計時器計數 GATE=1 時, 允許由外部輸入 INT0 控制定時器 0, 這樣可實現脈寬測量 當 C/T=0 時, 多路開關連接到系統時鐘的分頻輸出,T0 對時鐘週期計數,T0 工作在定時方式 當 C/T=1 時, 多路開關連接到外部脈衝輸入 P3.4/T0, 即 T0 工作在計數方式
TIMER0 使用 16bits 模式 #define FOSC 11059200L //clock 11.0592M #define MODE 1T //Timer clock mode, comment this line is 12T mode #ifdef MODE 1T #define T1ms (65536-FOSC/1000) //1ms timer calculation method in 1T mode #else #define T1ms (65536-FOSC/12/1000) //1ms timer calculation method in 12T mode #endif #define T1msH T1ms/256 #define T1msL T1ms%256
主程式 void main(){ AUXR = 0x80; // TMOD = 0x01; //set timer0 as mode1 (16-bit) TL0 = T1msL; //initial timer0 low byte TH0 = T1ms H; //initial timer0 high byte TR0 = 1; //timer0 start running ET0 = 1; //enable timer0 interrupt EA = 1; //open global interrupt switch }
TIMER0 中斷程式 /* Timer0 interrupt routine */ void tm0_1ms() interrupt 1 using 1 { TL0 = T1msL; //reload timer0 low byte TH0 = T1msH; //reload timer0 high byte // 每次中斷為 1ms, 要設定 1 秒可使用 count 計數 1000 次 if (count-- == 0) //1ms * 1000 -> 1s { count = 1000; //reset counter P2^0 =! P2^0; //work LED flash } }
TIMER 0/1 模式 2(8 位元自動重裝模式 ) TL0 的溢出不僅置位 TF0, 而且 TH0 容重新入 TL0, TH0 內容由軟件預置, 重裝時 TH0 內容不變
TIMER 0/1 模式 2(8 位元自動重裝模式 ) 在此模式下, 當 T0CLKO/WAKE_CLKO.0=1 時, P1.0/ADC0 管腳配置定時器 0 的時鐘輸出 CLKOUT0 輸出時鐘頻率 = T0 溢出率 /2 如果 C/T=0, 定時器 / 計數器 T0 對內部系統計數, 則 : T0 工作在 1T 模式 (AUXR.7/T0x12=1) 的輸出時鐘頻率 =(SYSclk)/(256-TH0)/2 T0 工作在 12T 模式 (AUXR.7/T0x12=0) 的輸出時鐘頻率 =(SYSclk)/12/(256-TH0)/2 如果 C/T=1, 定時器 / 計數器 T0 對外部脈衝輸入 (P1.0ADC0) 計數, 則 : 輸出時鐘頻率 = (T0_Pin_CLK) / (256-TH0) / 2
TIMER0 使用 8bits 模式 #include "reg51.h" sfr AUXR = 0x8e; //Auxiliary register //T0 interrupt service routine void t0int( ) interrupt 1 //T0 interrupt (location at 000BH) {. }
void main() { AUXR = 0x80; //timer0 work in 1T mode TMOD = 0x06; //set timer0 as counter mode2 (8-bit auto-reload) TL0 = TH0 = 0xff; //fill with 0xff to count one time TR0 = 1; //timer0 start run ET0 = 1; //enable T0 interrupt EA = 1; //open global interrupt switch while (1); }
模式 3( 兩個 8 位元數目器 ) 模式只適用於定時器計數器 0 對計時器 0, 此模式下計時器 0 的 TL0 及 TH0 作為 2 個獨立的 8 位元數目器 下圖為模式 3 時的定時器 0 邏輯圖 TL0 佔用計時器 0 的控制位 :C/T GATE TR0 INT0 及 TF0 TH0 限定為計時器功能 ( 計數器週期 ), 佔用計時器 1 的 TR1 及 TF1 此時,TH0 控制計時器 1 中斷
範例 5-1 功能要求 : 1. 亮偶數 LED 燈, 其他關閉, 延遲 0.5 秒 2. 亮奇數 LED 燈, 其他關閉, 延遲 0.5 秒 3. 使用 TIMER0, 中斷 電路說明 : 8 顆 LED 接在 P2, 低電位亮, 高電位不亮
範例 5-1
範例 5-1
範例 5-1
範例 5-2 功能要求 : 1. LED0 亮, 其他關閉, 延遲 0.5 秒 ; 依序點亮 LED0-LED7 2. LED7 亮之後, 按相反順序, 依序點亮 LED7-LED0 3. 使用 TIMER0, 中斷 電路說明 : 8 顆 LED 接在 P2, 低電位亮, 高電位不亮
範例 5-2
範例 5-2
範例 5-2
作業 5-1 LED 從 0-7 週而復始的顯示
作業 5-2 LED 週而復始的依序亮 0-7, 1-6, 2-5, 3-4, 4-3, 5-2, 6-1, 7-0
作業 5-3 1. LED 依序亮 0-7 2. LED7 亮, 且 LED 依序亮 0-6 3. LED6,7 亮, 且 LED 依序亮 0-5 4. LED5,6,7 亮, 且 LED 依序亮 0-4 5. LED4,5,6,7 亮, 且 LED 依序亮 0-3 6. LED3,4,5,6,7 亮, 且 LED 依序亮 0-2 7. LED2,3,4,5,6,7 亮, 且 LED 依序亮 0-1 8. LED1,2,3,4,5,6,7 亮, 且 LED0 亮 9. 週而復始由 1-8
作業 5-4 1. 週而復始顯示 0-0xFF, 即 0=00000000 1=00000001 2=00000010 3=00000011 4=00000100 5=00000101 6=00000110 7=00000111 8=00001000 FF=11111111 2. 使用 TIMER0 的中斷計時
~ END ~