單片機(jī) 中斷( 定時(shí)器/計(jì)數(shù)器詳說 )
掃描二維碼
隨時(shí)隨地手機(jī)看文章
方式0應(yīng)用
通過設(shè)置TMOD寄存器中的M1M0位00選擇定時(shí)器方式0,方式0的計(jì)數(shù)位數(shù)是13位,對(duì)T0來說,TL0寄存器的低5位(高3位未用)和TH0寄存器的8位組成。TL0的低5位溢出時(shí)向TH0進(jìn)位,TH0溢出時(shí),置位TCON中的TF0標(biāo)志,向cpu發(fā)出中斷請(qǐng)求。其邏輯圖如下
定時(shí)器方式0位13位計(jì)數(shù)器,最多能裝載的個(gè)數(shù) 2的13次方=8192個(gè),當(dāng)TL0和TH0的初始值為0時(shí),最多經(jīng)過8192個(gè)機(jī)器周期該計(jì)數(shù)器就會(huì)溢出一次,向cpu申請(qǐng)中斷。
THX=(8192-N)/32 TLX=(8192-N)%32。機(jī)器周期=12 X (1/時(shí)鐘頻率)
單片機(jī)定時(shí)器程序的步驟: 對(duì)TMOD賦值、計(jì)算初值、中斷方式,對(duì)IE賦值,開放中斷、使TR0或TR1置位,啟動(dòng)定時(shí)器
讓發(fā)光二極管以1s亮滅閃爍 代碼:
#include
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^0; // 假定發(fā)光二極管接P10口
uchar num;
void main()
{
TMOD=0x00; //設(shè)置定時(shí)器0的工作方式為0
TH0=(8192-4607)/32; //裝初值
TL0=(8192-4607)%32;
EA=1; //開總中斷
ET0=1; //開定時(shí)器0中斷
TR0=1; //啟動(dòng)定時(shí)器0
while(1)
{
if( num==20 )
{
num=0;
led1=~led1;
}
}
}
void T0_time() interrupt 1
{
TH0=( 8192-4607 )/32;
TL0=( 8192-4607 )%32;
num++;
}
方式2應(yīng)用
在定時(shí)器的方式0和1中,當(dāng)計(jì)數(shù)溢出后,計(jì)數(shù)器變?yōu)?,因此在循環(huán)定時(shí)過程中反復(fù)的裝初值必然會(huì)影響到定時(shí)的精度。方法2可解決裝初值的問題。通過設(shè)置TMOD寄存器中的M1M0位為10選擇定時(shí)器方式2,方式2被稱為8位初值自動(dòng)重裝的8位定時(shí)器/計(jì)數(shù)器,THX被稱為常數(shù)緩沖器,當(dāng)TLX溢出時(shí),在TFX置1時(shí)的同時(shí),還自動(dòng)的將THX中的常數(shù)重新裝入TLX中,使TLX從初值開始重新計(jì)數(shù),這樣避免了人為軟件重裝初值所帶來的時(shí)間誤差,從而提高定時(shí)精度
代碼,讓發(fā)光二極管以1s亮滅閃爍
#include
#define uint unsigned int
sbit led1=P1^0; //二極管接P1^0口
uint num;
void main()
{
TMOD=0x02;
TH0=6; // TH0、TL0取6和下面的num取3686是為了得到1s的時(shí)間。也可取其他的數(shù)字
TL0=6;
EA=1;
ET0=1;
TR0=1;
while( 1 )
{
if( num==3686 )
{
num=0;
led1=~led1;
}
}
}
void T0_time() interrupt 1
{
num++;
}
方式3應(yīng)用
方式3只適用于定時(shí)器/計(jì)數(shù)器 T0,當(dāng)設(shè)定定時(shí)器T0處于方式3時(shí),定時(shí)器T1不計(jì)數(shù)。方式3將T0分成2個(gè)獨(dú)立的8位計(jì)數(shù)器TL0和TH0,定時(shí)器3的邏輯結(jié)構(gòu)圖
分析上圖可知,定時(shí)器被分成2個(gè)獨(dú)立的計(jì)數(shù)器。其中TL0為正常的8位計(jì)數(shù)器,計(jì)數(shù)溢出后置位TF0,向cpu發(fā)出中斷申請(qǐng),之后再重裝初值。TH0也被固定為一個(gè)8位計(jì)數(shù)器,它占用定時(shí)器T1的中斷請(qǐng)求標(biāo)志TF1和定時(shí)器啟動(dòng)控制位TR1。
代碼 讓第一個(gè)二極管1s閃爍、第二個(gè)二極管0.5s閃爍
#include
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^0; //二極管接一個(gè)P1^0口另一個(gè)接P1^2口
sbit led2=P1^1;
uint num_1,num_2;
void main()
{
TMOD=0x03;
TH0=6; // TH0、TL0取6和下面的num取3686是為了得到1s的時(shí)間。也可取其他的數(shù)字
TL0=6;
EA=1;
ET0=1;
ET1=1;
TR1=1;
TR0=1;
while( 1 )
{
if( num>=3686 )
{
num_1=0;
led1=~led1;
}
if( num_2>=1843 )
{
num_2=0;
led2=~led2;
}
}
}
void TL0_time() interrupt 1
{
TL0=6;
num_1++;
}
void TH0_time() interrupt 3
{
TH0=6;
num_2++;
}