1硬件連接
定時器是單片機內(nèi)部的特殊功能模塊。
在控制系統(tǒng)中,常常要求有一些實時時鐘以實現(xiàn)定時或者延時控制,如定時中斷、定時檢測、定時掃描等等,也往往要求有計數(shù)器,對外部事件進行計數(shù)。
要實現(xiàn)定時或者延時功能,一般有三種方法:軟件定時,不可編程硬件定時,可編程硬件定時。
軟件定時——讓軟件循環(huán)執(zhí)行一段程序,程序本身并無執(zhí)行目的,而是通過執(zhí)行程序延時固定的時間,也就是以前的程序中經(jīng)常使用的延時程序。這種方法降低了cpu的利用率。
不可編程硬件定時——如外部芯片555 時基電路,通過外部阻容,達到一定的延時功能,改變阻容大小可以改變延時長度。這種定時器取決于硬件,設(shè)定好以后不能通過軟件更改。
可編程定時器——這種定時器的定時值可以通過軟件確定和修改,使用靈活便捷。
本節(jié)所講的定時器為第三種,可編程定時器,51單片機中T0/T1為2個相同的16位定時/計數(shù)器。
定時/計數(shù)器的結(jié)構(gòu):
圖 1 定時/計數(shù)器的結(jié)構(gòu)
TCON控制寄存器:
TCON用于控制外部中斷和定時/計數(shù)器啟動和中斷,低4位用于控制外部中斷,高4位用于控制定時/計數(shù)器T0和T1。
TCON.0~TCON.3(IT0、IE0、IT1、IE1)均為外部中斷相關(guān)位,詳見外部中斷。
TR0(TCON.4):定時/計數(shù)器T0運行控制位。TR0=1時,T0開始工作;TR0=0時,T0停止工作。TR0由軟件置1或清0。所以,用軟件可控制定時/計數(shù)器的啟動與停止。
TF0(TCON.5):定時/計數(shù)器T0溢出中斷請求標(biāo)志位。TF0=1時,申請進去定時器中斷。T0計數(shù)溢出時由硬件自動置TF0為1。CPU響應(yīng)中斷后TF0由硬件自動清0。T0工作時,CPU可隨時查詢TF0的狀態(tài)。所以,TF0可用作查詢測試的標(biāo)志。TF0也可以用軟件置1或清0,同硬件置1或清0的效果一樣。
TR1(TCON.6):定時/計數(shù)器T1運行控制位,其功能與TR0類同。
TF1(TCON.7):定時/計數(shù)器T1溢出中斷請求標(biāo)志位,其功能與TF0類同。
TMOD模式控制寄存器:
圖 3 TMOD模式控制寄存器格式
TMOD用于設(shè)置定時/計數(shù)器的工作方式,低四位用于T0,高四位用于T1
GATE: 門控位。GATE=0時,只要用軟件使TCON中的TR0或TR1為1,就可以啟動
定時/計數(shù)器工作;GATA=1時,要用軟件使TR0或TR1為1,同時外部中斷引腳或也為高電平時,才能啟動定時/計數(shù)器工作。即此時定時器的啟動多了一條件。
M1M0:工作方式設(shè)置位。定時/計數(shù)器有四種工作方式,由M1M0進行設(shè)置。
表1 定時/計數(shù)器工作方式表
2定時/計數(shù)器的工作方式
一、方式0
方式0為13位計數(shù),由TL0的低5位(高3位未用)和TH0的8位組成。TL0的低5位溢出時向TH0進位,TH0溢出時,置位TCON中的TF0標(biāo)志,向CPU發(fā)出中斷請求。
圖 4 方式0工作原理圖
計數(shù)初值計算初值的公式為:
二、方式1
方式1的計數(shù)位數(shù)是16位,由TL0作為低8位、TH0作為高8位,組成了16位加1計數(shù)器。
圖 5 方式1工作原理圖
計數(shù)個數(shù)與計數(shù)初值的關(guān)系為:
三、方式2
方式2為自動重裝初值的8位計數(shù)方式。當(dāng)TL0裝滿溢出時,系統(tǒng)自動將TH0中的數(shù)值裝給TL0,TLO重新開始計數(shù)。
圖 6 方式2工作原理圖
計數(shù)個數(shù)與計數(shù)初值的關(guān)系為:
四、方式3
方式3只適用于定時/計數(shù)器T0,定時器T1處于方式3時相當(dāng)于TR1=0,停止計數(shù)。工作方式3將T0拆分成為兩個獨立的8位定時/計數(shù)器TL0和TH0,兩個計數(shù)器獨立工作。
圖 7 方式3工作原理圖
計數(shù)個數(shù)與計數(shù)初值的關(guān)系為:
3定時器0
#include< reg52.h > //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
sbit LED=P1^2; //定義LED端口
/*------------------------------------------------
定時器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH0=0x00; //給定初值,這里使用定時器最大值從0開始計數(shù)一直到65535溢出
TL0=0x00;
EA=1; //總中斷打開
ET0=1; //定時器中斷打開
TR0=1; //定時器開關(guān)打開
}
/*------------------------------------------------
主程序
------------------------------------------------*/
main()
{
Init_Timer0();
while(1);
}
/*------------------------------------------------
定時器中斷子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 using 1
{
TH0=0x00; //重新賦值
TL0=0x00;
LED=~LED; //指示燈反相,可以看到閃爍
}
定時器0的程序代碼
定時/計數(shù)器0 使用16位定時模式,計數(shù)初值為0,計數(shù)到65536 溢出,中斷程序中LED取反,LED 以65536*2個時鐘周期為周期閃爍。
計數(shù)個數(shù)與計數(shù)初值的關(guān)系為:
4定時器1
#include< reg52.h > //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
sbit LED=P1^3; //定義LED端口
/*------------------------------------------------
定時器初始化子程序
------------------------------------------------*/
void Init_Timer1(void)
{
TMOD |= 0x10; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH1=0x00; //給定初值,這里使用定時器最大值從0開始計數(shù)一直到65535溢出
TL1=0x00;
EA=1; //總中斷打開
ET1=1; //定時器中斷打開
TR1=1; //定時器開關(guān)打開
}
/*------------------------------------------------
主程序
------------------------------------------------*/
main()
{
Init_Timer1();
while(1);
}
/*------------------------------------------------
定時器中斷子程序
------------------------------------------------*/
void Timer1_isr(void) interrupt 3 using 1
{
TH1=0x00; //重新賦值
TL1=0x00;
LED=~LED; //LED閃爍
}
定時1的程序代碼
5 產(chǎn)生1ms方波
#include< reg52.h > //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
sbit OUT=P1^2; //定義OUT輸出端口
/*------------------------------------------------
定時器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH0=(65536-500)/256; //給定初值,這里使用定時器最大值從500開始計數(shù)一直到65535溢出
TL0=(65536-500)%256; //12M晶振計算指令周期1us,1ms方波半個周期500us,即定時500次
EA=1; //總中斷打開
ET0=1; //定時器中斷打開
TR0=1; //定時器開關(guān)打開
}
/*------------------------------------------------
主程序
------------------------------------------------*/
main()
{
Init_Timer0();
while(1);
}
/*------------------------------------------------
定時器中斷子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 using 1
{
TH0=(65536-500)/256; //重新賦值
TL0=(65536-500)*256;
OUT=~OUT; //溢出然后輸出端取反
//用示波器可看到方波輸出
}
圖 10 1ms方波的程序代碼
示波器顯示周期為1ms的方波信號。
6 產(chǎn)生多路不同頻率的方波
#include< reg52.h > //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
/*------------------------------------------------
定時器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH0=(65536-500)/256; //給定初值,這里使用定時器最大值從500開始計數(shù)一直到65535溢出
TL0=(65536-500)%256; //12M晶振計算指令周期1us,1ms方波半個周期500us,即定時500次
EA=1; //總中斷打開
ET0=1; //定時器中斷打開
TR0=1; //定時器開關(guān)打開
}
/*------------------------------------------------
主程序
------------------------------------------------*/
main()
{
Init_Timer0();
while(1);
}
/*------------------------------------------------
定時器中斷子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 using 1
{
static unsigned char i;
TH0=(65536-500)/256; //重新賦值
TL0=(65536-500)*256;
i++;
P1=i; //P1口8路輸出不同頻率,相當(dāng)于一個分頻器,高頻用示波
//器測量,低頻可以直接用led觀測
//P1.0輸出1ms方波,P1.1輸出2ms,p1.2輸出4ms,以此類推
}
圖 11 多路不同頻率方波的程序代碼
中斷部分,相當(dāng)于一個分頻器,在P1 口可以測量出8 路不同頻率的方波。
P1 口測量不同頻率方波,周期依次增大一倍。
-
單片機
+關(guān)注
關(guān)注
6030文章
44489瀏覽量
631974 -
控制系統(tǒng)
+關(guān)注
關(guān)注
41文章
6509瀏覽量
110381 -
計數(shù)器
+關(guān)注
關(guān)注
32文章
2253瀏覽量
94281 -
定時器
+關(guān)注
關(guān)注
23文章
3231瀏覽量
114326
發(fā)布評論請先 登錄
相關(guān)推薦
評論