通過前面的定時器理論了解到,使用一個定時器,要經過下面四步:
1、設置定時器/計數器的工作模式TMOD(常用的是模式1:TMOD=0x01);
2、裝入預置數到THx和TLx中(THx=TLx=MAX(8192/65536/256)-計數次數);
3、如果工作在中斷方式,則需要開定時器/計數器的中斷TCON中的標志位:TF0/TF1=0/1;
4、啟動定時器/計數器:TR0/TR1=1;
//1、設置定時器/計數器的工作模式TMOD(常用的是模式1:TMOD=0x01); //2、裝入預置數到THx和TLx中(THx=TLx=MAX(8192/65536/256)-計數次數); //3、如果工作在中斷方式,則需要開定時器/計數器的中斷TCON中的標志位:TF0/TF1=0/1; //4、啟動定時器/計數器:TR0/TR1=1; // 內容:通過定時讓LED燈閃爍 #include<reg52.h> sbit LED=P0^2; //定義LED端口 //定時器初始化子程序 void Init_Timer0(void) { TMOD = 0x01; //使用模式1,16位定時器 TH0=0x00; //給定初值,這里使用定時器最大值從0開始計數一直到65535溢出 TL0=0x00; EA=1; //總中斷打開 89C52必需要有 ET0=1; //定時器中斷打開 TR0=1; //使用定時器0 } main()//主程序 { Init_Timer0(); while(1); } //定時器中斷子程序 //interrupt和using都是C51的關鍵字。C51中斷過程通過使用interrupt關鍵字和中斷號(0到31)來實現。 //using關鍵字用來指定中斷服務程序使用的寄存器組。 //用法是:using后跟一個0到3的數,對應着4組工作寄存器。 void Timer0_isr(void) interrupt 1 using 1 { TH0=0x00; //重新賦值 TL0=0x00; LED=~LED; //指示燈反相,可以看到閃爍 }
65536 * 1us = 65.536ms,也就是說上面的程序每經過65.536ms改變P0^2的狀態。
那么如何實現1s的精確定時呢,在工作方式1下,我們將計數初什設置為0x3CB0(15536),當計數到上限65536時,經過了50000個脈沖,即 50000 * 1us = 50ms,如果經過這樣的計時20次,就正好達到了1s,為驗證是否正確,可將上面的代碼修改如下:
//1、設置定時器/計數器的工作模式TMOD(常用的是模式1:TMOD=0x01); //2、裝入預置數到THx和TLx中(THx=TLx=MAX(8192/65536/256)-計數次數); //3、如果工作在中斷方式,則需要開定時器/計數器的中斷TCON中的標志位:TF0/TF1=0/1; //4、啟動定時器/計數器:TR0/TR1=1; // 內容:通過定時讓LED燈閃爍 #include<reg52.h> sbit LED=P0^2; //定義LED端口 unsigned int tm=0; //定時器初始化子程序 void Init_Timer0(void) { TMOD = 0x01; //使用模式1,16位定時器 TH0=0x3C; //給定初值,這里使用定時器最大值從0開始計數一直到65535溢出 TL0=0xB0; EA=1; //總中斷打開 89C52必需要有 ET0=1; //定時器中斷打開 TR0=1; //使用定時器0 } main()//主程序 { Init_Timer0(); while(1); } //定時器中斷子程序 //interrupt和using都是C51的關鍵字。C51中斷過程通過使用interrupt關鍵字和中斷號(0到31)來實現。 //using關鍵字用來指定中斷服務程序使用的寄存器組。 //用法是:using后跟一個0到3的數,對應着4組工作寄存器。 void Timer0_isr(void) interrupt 1 using 1 { TH0=0x3C; //重新賦值 3CB0 = 15536 TL0=0xB0; tm = tm + 1; if (tm == 20) // 20次達到1s { tm = 0; LED=~LED; //指示燈反相,可以看到閃爍 } }
編譯下載到單片機后,測試和預期一致,LED亮滅的狀態分別持續1s。