學習目標:I/O口的配置,掌握定時器1的模模式,兩種實現方式,查詢方式和中斷方式
【模模式】:
當定時器運行在模模式,16位計數器從0x0000開始,每個活動時鍾邊沿增加1。當計數器達到T1CC0,寄存器T1CC0H:T1CC0L保存的最終計數值,計數器將復位到0x0000,並繼續遞增。如果定時器開始於T1CC0以上的一個值,當達到最終計數值(0xFFFF)時,設置標志IRCON.T1IF和T1STAT.CH0IF(注意不是T1STAT.OVFIF)。如果設置了相應的中斷屏蔽位TIMIF.OVFIM、T1CCTL0.IM、IEN1.T1EN和總中斷IEN0.EA,計數器溢出將產生一個中斷請求。模模式可以用於周期不是0xFFFF的應用程序。
使用模模式時,必須要開啟通道0的輸出比較功能,所以,此時不僅僅只是簡單的中斷溢出。主要的注意事項如下:
1) 模模式需要開啟通道0的輸出比較模式,否則計數器到了0xFFFF時,才會產生溢出中斷,也就是說如果沒有設置通道0的輸出比較模式,計數器的值到了T1CC0H:T1CC0L設置的比較值后也不會產生溢出中斷。
2) T1的模模式不是普通的溢出中斷,和連續計數模式不同,它必須設置通道0的輸出比較功能,使能中斷時,也是使能通道0的輸出比較中斷屏蔽位。產生中斷時的中斷標志也是通道0的輸出比較中斷標志,而不是計數溢出標志。
計數器的操作展示如下圖:

模模式查詢方式下,初始化程序
1 1 /****************************************************************************** 2 2 *函 數 名:InitT1 3 3 *功 能:定時器1初始化,系統不配置時鍾默認2分頻,即16M 4 4 *入口參數:無 5 5 *出口參數:無 6 6 ******************************************************************************/ 7 7 void InitT1(void) 8 8 { 9 9 T1CTL = 0x0e; //定時器1設置為128分頻,模計數器模式 10 10 T1CC0L = 0xff; //模值1024,定時器1通道0捕獲/比較值低位 11 11 T1CC0H = 0x9f; //定時器1通道0捕獲/比較值高位 12 12 T1CCTL0 = 0x44; //通道0比較功能,並且開通道0中斷 13 13 T1STAT = 0X21; //通道0,中斷有效。這一句在裸機程序中可有可無 14 14 }
1 1 /****************************************************************************** 2 2 *程序入口函數 3 3 ******************************************************************************/ 4 4 int main(void) 5 5 { 6 6 InitClock(); 7 7 InitLED(1); //LED初始化,熄滅LED1 8 8 InitT1(); //定時器1初始化 9 9 10 10 while(1) 11 11 { 12 12 if(T1STAT & (1<<0)) //檢測定時器1通道0是否中斷 13 13 { 14 14 T1STAT &= ~(1<<0); //清中斷標志 15 15 LED1 = !LED1; //LED閃爍 16 16 } 17 17 } 18 18 }
這里判斷的是T1STAT.CH0IF(定時器1通道0中斷標志),經過實驗驗證也可以判斷IRCON.T1IF(定時器1中斷標志)。
定時器初始化程序
1 /****************************************************************************** 2 *函 數 名:InitT1 3 *功 能:定時器1初始化,系統不配置時鍾默認2分頻,即16M 4 *入口參數:無 5 *出口參數:無 6 ******************************************************************************/ 7 void InitT1(void) 8 { 9 T1CTL = 0x0e; //定時器1設置為128分頻,模計數器模式 10 T1CC0L = 0xff; //模值1024,定時器1通道0捕獲/比較值低位 11 T1CC0H = 0x9f; //定時器1通道0捕獲/比較值高位 12 T1CCTL0 = 0x44; //通道0比較功能,並且開通道0中斷 13 T1STAT = 0X21; //通道0,中斷有效。這一句在裸機程序中可有可無 14 TIMIF |= (1<<6); //定時器1溢出中斷使能 15 IEN1 |= (1<<1); //定時器1中斷使能 16 EA = 1; //開總中斷 17 }
中斷服務程序
1 /****************************************************************************** 2 *函 數 名:Timer1_ISR 3 *功 能:定時器1中斷服務程序 4 *入口參數:無 5 *出口參數:無 6 ******************************************************************************/ 7 #pragma vector = T1_VECTOR 8 __interrupt void Timer1_ISR(void) 9 { 10 LED1 = !LED1; 11 IRCON &= ~0x02; 12 T1STAT &= ~0x01; 13 }
第12行產生的中斷是定時器1通道0中斷,而不是定時器1的溢出中斷,故只需要清除T1STAT的第1位,不需要清除第5位

