|
|
51單片機(jī)共有兩個(gè)16位可編程的定時(shí)器/計(jì)數(shù)器,即定時(shí)器T0和定時(shí)器T1。它們既有定時(shí)功能又有計(jì)數(shù)功能,通過設(shè)置一些相關(guān)的特殊功能寄存器就可以選擇啟用哪一個(gè)功能。定時(shí)器系統(tǒng)是單片機(jī)內(nèi)部一個(gè)獨(dú)立硬件部分,與CPU和晶振之間通過內(nèi)部某些控制線連接并相互作用,CPU一旦啟動(dòng)定時(shí)功能,定時(shí)器便會(huì)在晶振的作用下自動(dòng)計(jì)時(shí),當(dāng)定時(shí)器計(jì)數(shù)器積滿之后就會(huì)產(chǎn)生中斷,通知CPU接下來做什么。
定時(shí)器或計(jì)數(shù)器實(shí)質(zhì)是加一計(jì)數(shù)器(16位)(其輸入脈沖有兩個(gè)來源,一是由系統(tǒng)時(shí)鐘振蕩器輸出脈沖經(jīng)過十二分頻后送來;另外是T0或T1引腳輸入的外部脈沖源,每來一個(gè)脈沖計(jì)數(shù)器加1,當(dāng)加到計(jì)數(shù)器全為1時(shí),在輸入一個(gè)脈沖就可使計(jì)數(shù)器回零,計(jì)數(shù)器的溢出是的TCON寄存器中TF0或TF1置1,向CPU發(fā)出中斷請(qǐng)求,如果定時(shí)或計(jì)數(shù)器工作于定時(shí)模式,則表示定時(shí)時(shí)間到了,如果是計(jì)數(shù)則表示計(jì)數(shù)值已滿)由高八位和低八位兩個(gè)寄存器組成。
TMOD:定時(shí)器/計(jì)數(shù)器模式控制寄存器(TIMER/COUNTER MODE CONTROL REGISTER) ,確定工作方式和功能
TCON:控制寄存器,控制T0,T1的啟動(dòng)和停止及設(shè)置溢出標(biāo)志。
定時(shí)器/計(jì)數(shù)器模式控制寄存器TMOD是一個(gè)逐位定義的8位寄存器,但只能使用字節(jié)尋址,其字節(jié)地址為89H。其格式為:其中低四位定義定時(shí)器/計(jì)數(shù)器C/T0,高四位定義定時(shí)器/計(jì)數(shù)器C/T1,各位的說明:
GATE——門控制。
GATE=1時(shí),由外部中斷引腳INT0、INT1來啟動(dòng)定時(shí)器T0、T1。 當(dāng)INT0引腳為高電平時(shí)TR0置位,啟動(dòng)定時(shí)器T0; 當(dāng)INT1引腳為高電平時(shí)TR1置位,啟動(dòng)定時(shí)器T1。 GATE=0時(shí),僅由TR0,TR1置位分別啟動(dòng)定時(shí)器T0、T1。
C/T——功能選擇位
C/T=0時(shí)為定時(shí)功能,C/T=1時(shí)為計(jì)數(shù)功能。 置位時(shí)選擇計(jì)數(shù)功能,清零時(shí)選擇定時(shí)功能。
M0、M1——方式選擇功能
由于有2位,因此有4種工作方式:
M1M0 工作方式計(jì)數(shù)器模式 TMOD(設(shè)置定時(shí)器模式)
0 0 方式0 13位計(jì)數(shù)器 TMOD=0x00
0 1 方式1 16位計(jì)數(shù)器 TMOD=0x01
1 0 方式2 自動(dòng)重裝8位計(jì)數(shù)器 TMOD=0x02
1 1 方式3 T0分為2個(gè)8位獨(dú)立計(jì)數(shù)器,T1為無中斷重裝8位計(jì)數(shù)器 TMOD=0x03 單片機(jī)定時(shí)器0設(shè)置為工作方式1為TMOD=0x01
TCON: 定時(shí)器/計(jì)數(shù)器控制寄存器(TIMER/COUNTER CONTROL REGISTER)
TMOD分成2段,TCON控制更加精細(xì),分成四段,在本文中只要用到高四段。 TF0(TF1)——計(jì)數(shù)溢出標(biāo)志位,當(dāng)計(jì)數(shù)器計(jì)數(shù)溢出時(shí),該位置1。
TR0(TR1)——定時(shí)器運(yùn)行控制位 當(dāng)TR0(TR1)=0 停止定時(shí)器/計(jì)數(shù)器工作 當(dāng)TR0(TR1)=1 啟動(dòng)定時(shí)器/計(jì)數(shù)器工作
IE0(IE1)——外中斷請(qǐng)求標(biāo)志位
IT0(IT1)——外中斷請(qǐng)求信號(hào)方式控制位 當(dāng)IT0(IT1)=1 脈沖方式(后沿負(fù)跳有效)
當(dāng)IT0(IT1)=0 電平方式(低電平有效)此位由軟件置1或清0。
TF0(TF1)——計(jì)數(shù)溢出標(biāo)志位
當(dāng)計(jì)數(shù)器產(chǎn)生計(jì)數(shù)溢出時(shí),此位由硬件置1。當(dāng)轉(zhuǎn)向中斷服務(wù)時(shí),再有硬件自動(dòng)清0。計(jì)數(shù)溢出的標(biāo)志位的使用有兩種情況:采用中斷方式時(shí),作中斷請(qǐng)求標(biāo)志位來使用;采用查詢方式時(shí),作查詢狀態(tài)位來使用。注意記憶方法,理解單詞原形,就絕對(duì)不會(huì)把TF和TR搞混。TF的F也就是溢出Over Flow的F。TR的R就是運(yùn)行Run。默認(rèn)是0不運(yùn)行,當(dāng)然要置1才運(yùn)行
//在寫單片機(jī)定時(shí)器程序時(shí)候,在程序開始出需要對(duì)定時(shí)器及中斷寄存器做初始化設(shè)置,通常初始化過程如下:對(duì)TMOD賦值,以確定T0和T1的工作方式; 計(jì)算初值,并將初值寫入TH0,TL0或者TH1,TL1; 中斷方式時(shí),則對(duì)IE賦值,開放中斷 使TR0或TR1置位,啟動(dòng)定時(shí)器/計(jì)數(shù)器定時(shí)或者計(jì)數(shù)。
//實(shí)現(xiàn)led燈一秒亮滅閃爍
//實(shí)現(xiàn)led燈一秒亮滅閃爍#define uhar unsinged char #define uint unsinged intuchar num;void main(){ TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1(M1 M0為01) TH0=(65536-45872)/256;//裝初值11.0582晶振定時(shí)50ms數(shù)為45872 TL0=(65536-45872)%256; EA=1;//開總中斷 ET0=1;//開定時(shí)器0中斷 TR0=1;//啟動(dòng)定時(shí)器0 while(1);//程序停止在這里等待中斷發(fā)生}void T0_time() interrupt 1{ TMOD=0x01;//重裝初值 TH0=(65536-45872)/256; num++;//num每加一次判斷一次是否到20次 if(num==20)//如果到了20次,說明1秒時(shí)間到 { num=0;//num清0重新計(jì)數(shù) led=~led1; }}
編寫單片機(jī)定時(shí)器程序的步驟:
1.對(duì)TMOD賦值,以確定T0和T1的工作方式。
2.計(jì)算初值,并將初值寫入TH0,TL0或TH1,TL1。
3.中斷方式時(shí),對(duì)IE賦值,開放中斷。
4.使TR0或TR1置位,啟動(dòng)定時(shí)器/計(jì)數(shù)器定時(shí)或計(jì)數(shù)。
1.定時(shí)器使用方法
1.時(shí)間的計(jì)算
要實(shí)現(xiàn)定時(shí)50ms,(65536-T0)x12/12000000=0.05s得T0=15536即0x3c要實(shí)現(xiàn)定時(shí)tms,可以利用(65536-t)x12/12000000= txE-3;求出t,即可。
2.對(duì)TMOD賦值,以確定T0和T1的工作方式
//例子TMOD=0x01; //0b00000001 用的是定時(shí)器0,工作在方式1(16位寄存器)TMOD:定時(shí)器/計(jì)數(shù)器模式控制寄存器GATE=1時(shí),由外部中斷引腳INT0、INT1來啟動(dòng)定時(shí)器T0、T1。 當(dāng)INT0引腳為高電平時(shí)TR0置位,啟動(dòng)定時(shí)器T0; 當(dāng)INT1引腳為高電平時(shí)TR1置位,啟動(dòng)定時(shí)器T1。 GATE=0時(shí),僅由TR0,TR1置位分別啟動(dòng)定時(shí)器T0、T1。 Ⅱ,C/T——功能選擇位 C/T=0時(shí)為定時(shí)功能,C/T=1時(shí)為計(jì)數(shù)功能。 置位時(shí)選擇計(jì)數(shù)功能,清零時(shí)選擇定時(shí)功能。 Ⅲ,M0、M1——方式選擇功能 由于有2位,因此有4種工作方式 M1 M0 工作方式 計(jì)數(shù)器模式 TMOD(設(shè)置定時(shí)器模式) 0 0 方式0 13位計(jì)數(shù)器 TMOD=0x00 0 1 方式1 16位計(jì)數(shù)器 TMOD=0x01 1 0 方式2 自動(dòng)重裝8位計(jì)數(shù)器 TMOD=0x02 1 1 方式3 T0分為2個(gè)8位獨(dú)立計(jì)數(shù)器,T1為無中斷重裝8位計(jì)數(shù)器 TMOD=0x03
/**********************************************************************************************定時(shí)器1的初始化函數(shù)************************************************************************************************/void timer1_init() //這里是定時(shí)器1初始化函數(shù){ TMOD |= 0x10; //TMOD里 MO 置1 TMOD &= 0xdf; //TOOD里 M1 清零 定時(shí)器選擇為 16位定時(shí)模式 TH1 = 0xFC; //下面2句是 定時(shí)器的初值 也就是你定時(shí)器需要定時(shí)的時(shí)間 TL1 = 0x67; TR1 = 1; //啟動(dòng)定時(shí)器 }
3.計(jì)算初值,并將初值寫入TH0,TL0或TH1,TL1。
TH0=(65536-50000)/256; //裝定時(shí)器初值高8位TL0=(65536-50000)%256; //裝定時(shí)器初值低8位 TH0=(65536-T0)/256 ;//裝定時(shí)器初值高8位TL0=(65536-T0)%256 ;//裝定時(shí)器初值低8位//其中T0是需要計(jì)算的時(shí)間//一般編程過程并直接計(jì)算T0的值,直接寫讓單片機(jī)自己去計(jì)算
4.中斷方式時(shí),對(duì)IE賦值,開放中斷。
EA=1; //開 總中斷ET0=1; //開 定時(shí)器0中斷 EA=1;開 總中斷 EA=0;關(guān)閉 總中斷 ET0=1;開 定時(shí)器0中斷 ET0=0;關(guān)閉 定時(shí)器0中斷 EA=1;開 總中斷 EA=0;關(guān)閉 總中斷 ET1=1;開 定時(shí)器1中斷 ET1=0;關(guān)閉 定時(shí)器1中斷 /*********** //TR0=1;//啟動(dòng)定時(shí)器0 TR0=1;//關(guān)閉定時(shí)器0 ************/
5.//定時(shí)器初始化
/************************************定時(shí)器初始化案例******************************************/void timer0Init(){ TMOD=0x01; //0b00000001 用的是定時(shí)器0,工作在方式1(16位寄存器) TH0=(65536-50000)/256; //裝定時(shí)器初值高8位 TL0=(65536-50000)%256; //裝定時(shí)器初值低8位 EA=1;//開總中斷 ET0=1; //開定時(shí)器0中斷 //TR0=1;//啟動(dòng)定時(shí)器0 TR0=1;//關(guān)閉定時(shí)器0}
6..一般使用定時(shí)器的代碼步驟
//實(shí)現(xiàn)led燈一秒亮滅閃爍#define uhar unsinged char #define uint unsinged intuchar num;void main(){ TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1(M1 M0為01) TH0=(65536-45872)/256;//裝初值11.0582晶振定時(shí)50ms數(shù)為45872 TL0=(65536-45872)%256; EA=1;//開總中斷 ET0=1;//開定時(shí)器0中斷 TR0=1;//啟動(dòng)定時(shí)器0 while(1);//程序停止在這里等待中斷發(fā)生}void T0_time() interrupt 1{ TMOD=0x01;//重裝初值 TH0=(65536-45872)/256; num++;//num每加一次判斷一次是否到20次 if(num==20)//如果到了20次,說明1秒時(shí)間到 { num=0;//num清0重新計(jì)數(shù) led=~led1; }}
/定時(shí)器0中斷函數(shù)#define uhar unsinged char void T0/T1_time() interrupt 1//使用定時(shí)器中斷1{ TMOD=0X01;//選擇了定時(shí)器0 方式1 //可以設(shè)置TMOD=0x00;0x01;0x10;0x11;共四組方式 TH0=(65536-T0)/256; //裝定時(shí)器初值高8位 TL0=(65536-T0)%256; //裝定時(shí)器初值低8位 //T0是需要計(jì)算的時(shí)間 uchar count=0; if(count==X) { count=0; //清0重新計(jì)數(shù) 執(zhí)行程序代碼 } //其中X是需要計(jì)算次數(shù),比如讓定時(shí)器定時(shí)個(gè)1s; //則需要定時(shí)器一個(gè)50ms的時(shí)間; //如果要達(dá)成1s則需要執(zhí)行20次; //讓定時(shí)器定時(shí)個(gè)50ms時(shí)間,需要這樣去寫 //TH0=(65536-50000)/256; //TL0=(65536-50000)%256; //讓定時(shí)器定時(shí)個(gè)T0時(shí)間,需要這樣去寫 // //TH0=(65536-T0乘10的3次方)/256; //TL0=(65536-T0乘10的3次方)%256; }void main(){ timer0Init();//初始化 //執(zhí)行程序代碼,完成相應(yīng)的功能; while(1) { //執(zhí)行程序代碼,完成相應(yīng)的功能; }}void T0_time() interrupt 1{ TMOD=0x01;//重裝初值 TH0=(65536-45872)/256; num++;//num每加一次判斷一次是否到20次 if(num==20)//如果到了20次,說明1秒時(shí)間到 { num=0;//num清0重新計(jì)數(shù) led=~led1; }}
/*************************網(wǎng)上程序******************************/
/*************************網(wǎng)上程序******************************/#include"reg51.h"sbit led=P1^1;#define uchar unsigned char//#define uint unsigned intuchar num;//定義全局變量void t0Iint()//定時(shí)器0的初始化函數(shù){ TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1(M1 M0為01) TH0=(65536-50000)/256;//裝初值11.0582晶振定時(shí)50ms數(shù)為45872 TL0=(65536-50000)%256; EA=1;//開總中斷 ET0=1;//開定時(shí)器0中斷}void main(){ t0Iint(); //TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1(M1 M0為01) // TH0=(65536-50000)/256;//裝初值11.0582晶振定時(shí)50ms數(shù)為45872 //TL0=(65536-50000)%256; //EA=1;//開總中斷 //ET0=1;//開定時(shí)器0中斷 TR0=1;//啟動(dòng)定時(shí)器0 while(1);//程序停止在這里等待中斷發(fā)生}void T0_time() interrupt 1{ //TMOD=0x01;//重裝初值 //TH0=(65536-50000)/256; num++;//num每加一次判斷一次是否到20次 if(num==20)//如果到了20次,說明1秒時(shí)間到 { num=0;//num清0重新計(jì)數(shù) led=~led; }}
模板
/**********該程序經(jīng)過處理更容易懂和套模板利用********************************************/#include"reg51.h"sbit led=P1^1;//定義一個(gè)LED燈為1.1引腳#define uchar unsigned char//#define uint unsigned intuchar num;//定義全局變量void timer0Iint()//定時(shí)器0的初始化函數(shù){ TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1(M1 M0為01) TH0=(65536-50000)/256;//裝初值11.0582晶振定時(shí)50ms數(shù)為45872 TL0=(65536-50000)%256; EA=1;//開總中斷 ET0=1;//開定時(shí)器0中斷}void T0_time() interrupt 1{ num++;//num每加一次判斷一次是否到20次 if(num==20)//如果到了20次,說明1秒時(shí)間到 { num=0;//num清0重新計(jì)數(shù) led=~led; }}void main(){ timer0Iint(); TR0=1;//啟動(dòng)定時(shí)器0//該步驟也可在初始化寫 while(1) { }//程序停止在這里等待中斷發(fā)生
|
|