1. 程式人生 > >8951定時器的學習筆記

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替換就好。