51單片機中斷詳解(下)
一.定時器相關寄存器
工作方式寄存器(TMOD)

該寄存器用于設置定時/計數器的工作方式,低四位用于定時器0,高四位用于定時器1。
GATE:門控位。GATE=0時,只要用軟件使TCON中的TR0或TR1為1,就可以啟動定時/計數器工作;GATA=1時,要用軟件使TR0或TR1為1,同時外部中斷引腳INT0/1也為高電平時,才能啟動定時/計數器工作。即此時定時器的啟動條件,加上了INT0/1引腳為高電平這一條件。
C/T:定時/計數模式選擇位。C/T=0為定時模式;C/T=1為計數模式。

定時器/計數器控制寄存器控制寄存器(TCON)

該寄存器的低4位用于控制外部中斷,已在前面介紹,高4位用于控制定時/計數器的啟動和中斷申請。
TF1:T1溢出中斷請求標志位。T1計數溢出時由硬件自動置TF1為1。CPU響應中斷后TF1由硬件自動清0。
TR1:T1運行控制位。TR1置1時,T1開始工作;TR1置0時,T1停止工作。TR1由軟件置1或清0。所以,用軟件可控制定時/計數器的啟動與停止。
TF0:T0溢出中斷請求標志位,其功能與TF1類同。
TR0:T0運行控制位,其功能與TR1類同。
中斷允許控制寄存器(IE)

ET0:定時/計數器T0中斷允許位;
ET1:定時/計數器T1中斷允許位;
EA :CPU中斷允許(總允許)位。
二.定時器溢出中斷的處理過程
1、設置定時器工作方式
2、為定時器裝入初值
3、定時器中斷允許位置為1
4、開總中斷
5、開定時器,等待產生溢出中斷請求
三.實現簡單時鐘
說明:
1.使用動態數碼管顯示
2.選擇工作方式1,以16位的定時器0進行工作,即TMOD=0x01,中斷編號為1;
3.定時50ms,即每隔50ms產生一次中斷:
TH0=(65536-50000)/256; //16位定時器的高8位
TL0=(65536-50000)%256; //16位定時器的低8位
具體的時間與單片機的晶振有關,請了解機器周期、指令周期、時鐘周期等相關知識。
#include
#define uchar unsigned char
#define uint unsigned int
uchar hour,min,sec;
uchar code wei[8]= {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //共陰極數碼管位選編碼
uchar code duan[11]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x01}; //共陰極數碼管段選編碼
void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void timer0_init()
{
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
TR0=1;
EA=1;
}
void main()
{
uchar i;
timer0_init();
while(1)
{
num[0]=duan[hour/10];
num[1]=duan[hour%10];
num[2]=0x40; //顯示一橫
num[3]=duan[min/10];
num[4]=duan[min%10];
num[5]=0x40; //顯示一橫
num[6]=duan[sec/10];
num[7]=duan[sec%10];
for(i=0; i<8; i++) //顯示部分
{
P0=wei[i]; //位選
P1=num[i]; //段選
delay(2);
P1=0x00; //消隱
}
}
/*啟動定時器后,沒次計數溢出就會進入中斷服務函數,重新賦初值,再進行計數,來達到定時的效果*/
void timer0() interrupt 1 //定時器中斷服務函數
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t++;
if(hour==24)
hour=0;
if(min==60)
{
hour++;
min=0;
}
if(sec==60)
{
min++;
sec=0;
}
if(t==20)
{
sec++;
t=0;
}
}

編輯:admin 最后修改時間:2018-05-18


