8951定時器的學習筆記
定時器的使用與我之前所說的中斷使用差不多。首先也是設定初始化定時器。先上程式碼:
#include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit led=P1^0; sbit s1=P3^0; sbit s2=P3^1; uchar counter=0; uchar temp=0; uchar flag=0; code uchar a[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void delay(uint t) { uint i; while(t--) { for(i=125;i>0;i--); } } void show() { P2=a[temp/10];s1=1;delay(1);s1=0; P2=a[temp%10];s2=1;delay(1);s2=0; } void main() { TMOD=0x01; //設定T0定時器工作模式 TH0=(65536-50000)/256; TL0=(65536-50000)%256; IT0=1;//設定外部中斷0的觸發方式為低電平觸發 EX0=1;//外部中斷0的開關 ET0=1;//定時器0的中斷設定必須要在啟動定時器之前 TR0=1;//啟用定時器 EA=1; while(1) { show(); } } void ET0_Int(void) interrupt 1 { TH0=(65536-50000)/256;//重灌 在其自身外部中斷中無需設定標誌位歸零!!!!! TL0=(65536-50000)%256; counter++; if(counter%10==0) { led=!led; } if(counter==20) { counter=0; temp++; if(temp==59) temp=0; } } void Ex0_ISR(void) interrupt 0 { flag++; if(flag==1)TR0=1; //啟動定時器0 ,開始計時,數碼管跳轉 if(flag==2)TR0=0; //停止定時器的工作 if(flag==3) { flag=0; temp=0; } }
這個篇程式碼可能被我改的有些複雜,看不懂不要急。 只需要瞭解重點語句就好。
首先是定時器的初始化在main函式裡:
TMOD=0x01; //設定T0定時器工作模式
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
IT0=1;//設定外部中斷0的觸發方式為低電平觸發
EX0=1;//外部中斷0的開關
ET0=1;//定時器0的中斷設定必須要在啟動定時器之前
EA=1;
定時器的初始化比外部終端的初始化語句多一點。
首先是設定工作模式這裡是0x01,這種模式就像一個鬧鐘,設定好時間,它每到時間就“報警”一次。總共有四種工作方式,在此先記這一種。
TMOD=0x01; //設定T0定時器工作模式
上面這句就是設定定時器工作方式。前面說了它這種工作模式工作像鬧鐘,為此要設定他的工作時間間隔。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
哈哈,看不懂吧,不要急,慢慢來。它這種工作方式設定工作時間 還真不好理解。TH和TL中分別有一個H和L表示High和Low的意思就是高位和地位的意思。對於一個數如5201314來說吧,想要把520和1314分開,就要進行運算,想得到520就是:5201314/10000就等於520,而1314=5201314%10000然後把520給高位 1314給低位,只不過這裡必須對256運算。一個數,高位在前,低位在後。對於這個65535是固定的,後面的50000表示50000us(50000us=50ms=0.05s)。這樣他就會每個0.05s執行一次中斷服務程式,也就是這個
void ET0_Int(void) interrupt 1
函式裡面的語句。然後接著解釋程式碼:
IT0=1;//設定外部中斷0的觸發方式為低電平觸發
EX0=1;//外部中斷0的開關
ET0=1;//定時器0的中斷設定必須要在啟動定時器之前
TR0=1;//啟用定時器
EA=1;
這個IT0是外部中斷0的,在這個程式裡我使用了外部中斷0和定時器0。EX0也不多說了他也是外部中斷0的。主要是ET0=1和TR0=1的順序不要寫錯。要是IT0=1,EX0=1,EA=1都看不懂是什麼意思就不要往下看了,先去學習外部中斷。
設定好了,他就是隔0.05s執行那個函式,這個函式裡面有一個counter++和兩個if語句,由此能看出來每次響應中斷服務時候都會對counter進行加一運算。當counter對於20時也就是執行了中斷響應服務20次,前面咱給他設定的時間間隔是0.05s執行了20次的時間就是0.05s×20=1s。所以說if(counter==20)裡的語句每個一秒執行一次。由此看之,設定每個多長時間做什麼,其實就是對執行次數的檢測。同理,另一個if就是每隔0.5s執行一次led=!led語句。
在定時器這部分中,我覺著設定定時時間,這塊不好理解。上面的理解看不懂的可以這樣記憶也行。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
設定時間就用這樣設定,裡面的50000可以變。這裡50000us=0.05s,就是每隔0.05s執行一次中斷服務程式。於是可以自己算,想隔多少秒就把0.05s替換就好。