一、晶振的工作原理
壓電效應(yīng):
如圖所示,晶體振蕩器主要由引線構(gòu)成的電極和晶體片構(gòu)成。
當(dāng)我們?cè)诰w兩電極外加電壓后,晶體會(huì)發(fā)生形變,反過來,如果外力使得晶體變形,兩極上又會(huì)產(chǎn)生電壓。
因此當(dāng)我們?cè)诰w兩端施加一個(gè)交變電壓時(shí),隨著電壓正負(fù)的改變,晶體交替形變,進(jìn)而以一定的頻率發(fā)生諧振–單頻振蕩(振蕩頻率固定不變)。
二、晶體單頻振蕩產(chǎn)生時(shí)鐘脈沖
我們知道,脈沖信號(hào)是一個(gè)按一定電壓幅度、一定時(shí)間間隔連續(xù)發(fā)出的信號(hào)。
而我們的晶體振蕩器,既有電壓幅度–晶體兩端施加的電壓,又有時(shí)間間隔–振蕩頻率 f 的倒數(shù)作為周期。因此我們可以通過我們的晶體振蕩器產(chǎn)生一個(gè)穩(wěn)定的時(shí)鐘脈沖信號(hào)來為我們的單片機(jī)提供精準(zhǔn)計(jì)時(shí)。
三、單片機(jī)的時(shí)間單位
現(xiàn)在我們有了由晶體振蕩器產(chǎn)生的精準(zhǔn)時(shí)鐘脈沖,可以給我們的單片機(jī)計(jì)時(shí)了。但對(duì)于單片機(jī)來講,用我們所熟知的時(shí)分秒等計(jì)時(shí)單位來計(jì)時(shí),并不合適。因此我們根據(jù)單片機(jī)的工作特性和原理,引入了時(shí)鐘周期、狀態(tài)周期、機(jī)器周期、指令周期幾個(gè)概念來作為我們單片機(jī)的時(shí)間單位。
1、時(shí)鐘周期
也叫振蕩周期或者晶振周期,即晶振的單位時(shí)間發(fā)出的脈沖數(shù)。如12Mhz晶振的時(shí)鐘周期為1/ f =1/12Mhz,也就是1/12微秒。
時(shí)鐘周期是計(jì)算機(jī)中最基本、最小的時(shí)間單位。
在8051單片機(jī)中把一個(gè)時(shí)鐘周期定義為一個(gè)節(jié)拍(用P表示),二個(gè)節(jié)拍定義為一個(gè)狀態(tài)周期(用S表示)
2、機(jī)器周期
計(jì)算機(jī)中,為了便于管理,常把一條指令的執(zhí)行過程劃分為若干個(gè)階段,每一階段完成一項(xiàng)工作。例如,取指令、存儲(chǔ)器讀、存儲(chǔ)器寫等,這每一項(xiàng)工作稱為一個(gè)基本操作。完成一個(gè)基本操作所需要的時(shí)間稱為機(jī)器周期。51單片機(jī)中一個(gè)機(jī)器周期等于12個(gè)時(shí)鐘周期。
在標(biāo)準(zhǔn)的51單片機(jī)中,一般情況下,一個(gè)機(jī)器周期等于12個(gè)時(shí)鐘周期,也就是機(jī)器周期=12*時(shí)鐘周期,(上面講到的原因)如果是12MHZ,那么機(jī)器周期=1微秒。單片機(jī)工作時(shí),是一條一條地從RoM中取指令,然后一步一步地執(zhí)行。單片機(jī)訪問一次存儲(chǔ)器的時(shí)間,稱之為一個(gè)機(jī)器周期,這是一個(gè)時(shí)間基準(zhǔn)。
機(jī)器周期不僅對(duì)于指令執(zhí)行有著重要的意義,而且機(jī)器周期也是單片機(jī)定時(shí)器和計(jì)數(shù)器的時(shí)間基準(zhǔn)。例如一個(gè)單片機(jī)選擇了12MHZ晶振,那么當(dāng)定時(shí)器的數(shù)值加1時(shí),實(shí)際經(jīng)過的時(shí)間就是1us,這就是單片機(jī)的定時(shí)原理。
3、指令周期
指令周期是執(zhí)行一條指令所需要的時(shí)間,一般由若干個(gè)機(jī)器周期組成。指令不同,所需的機(jī)器周期數(shù)也不同。
對(duì)于一些簡單的的單字節(jié)指令,在取指令周期中,指令取出到指令寄存器后,立即譯碼執(zhí)行,不再需要其它的機(jī)器周期。
對(duì)于一些比較復(fù)雜的指令,例如轉(zhuǎn)移指令、乘法指令,則需要兩個(gè)或者兩個(gè)以上的機(jī)器周期
Part2 定時(shí)計(jì)數(shù)器
在我們的單片機(jī)中,說到時(shí)間就離不開上面所提的時(shí)鐘脈沖。而我們的定時(shí)計(jì)數(shù)器就是對(duì)這些脈沖進(jìn)行計(jì)數(shù),來進(jìn)行時(shí)間計(jì)算的,本質(zhì)上我們的定時(shí)計(jì)數(shù)器是一個(gè)加1計(jì)數(shù)器,也就是每輸入一個(gè)脈沖,計(jì)數(shù)加一。
但要注意的一點(diǎn)是,定時(shí)器和計(jì)數(shù)器是兩個(gè)不同的功能單元。
定時(shí)器是由單片機(jī)自身提供的一個(gè)非常穩(wěn)定的計(jì)數(shù)器(晶振),接受的是內(nèi)部脈沖;
而計(jì)數(shù)器則不同,記錄的是單片機(jī)外部發(fā)生的事情,接受的是外部脈沖。
舉一個(gè)計(jì)數(shù)器的例子,方便大家理解,我現(xiàn)在讓我的計(jì)數(shù)器記錄我的一個(gè)獨(dú)立按鍵按下的次數(shù),那它所接受的脈沖便是我們按鍵按下過程中產(chǎn)生外部脈沖。
這里需要注意的是,計(jì)數(shù)器自動(dòng)加1需要檢測從1到0的下降沿,因此需要兩個(gè)計(jì)數(shù)周期,最高計(jì)數(shù)頻率為24晶振頻率。
由于不同型號(hào)的51單片機(jī)的定時(shí)器個(gè)數(shù)不同,下面以最基礎(chǔ)的8951單片機(jī)為例進(jìn)行闡述
一、定時(shí)計(jì)數(shù)器的寄存器
說了這么多,那單片機(jī)具體應(yīng)該怎么使用呢,別急,咱們還得從最基本的寄存器開始看起。
首先我們來看一下定時(shí)計(jì)數(shù)器的定時(shí)方式寄存器–TMOD
GATE :定時(shí)操作開關(guān)控制位,當(dāng)GATE=1時(shí),INT0或INT1引腳為高電平,同時(shí)TCON中的TR0或TR1控制位為1時(shí),計(jì)時(shí)/計(jì)數(shù)器0或1才開始工作。若GATE=0,則只要將TR0或TR1控制位設(shè)為1,計(jì)時(shí)/計(jì)數(shù)器0或1就開始工作。
C/T :定時(shí)器或計(jì)數(shù)器功能的選擇位。C/T=1為計(jì)數(shù)器,通過外部引腳T0或T1輸入計(jì)數(shù)脈沖。C/T=0時(shí)為定時(shí)器,由內(nèi)部系統(tǒng)時(shí)鐘提供計(jì)時(shí)工作脈沖。
M1 M0:T0、T1工作模式選擇位
設(shè)置好方式,當(dāng)然還有具體的定時(shí)器控制寄存器–TCON
TF1:定時(shí)器T1溢出標(biāo)志,可由程序查詢和清零,TF1也是中斷請(qǐng)求源,當(dāng)CPU響應(yīng)T1中斷時(shí)由硬件清零。
TF0:定時(shí)器T0溢出標(biāo)志,可由程序查詢和清零,TF0也是中斷請(qǐng)求源,當(dāng)CPU響應(yīng)T0中斷時(shí)由硬件清零。
TR1:T1充許計(jì)數(shù)控制位,為1時(shí)充許T1計(jì)數(shù)(定時(shí))。
TR0:T0充許計(jì)數(shù)控制位,為1時(shí)充許T0計(jì)數(shù)(定時(shí))。
下面四個(gè)屬于中斷部分,這里不多做闡述。
IE1:外部中斷1請(qǐng)示源(INT1,P3.3)標(biāo)志。IE1=1,外部中斷1正在向CPU請(qǐng)求中斷,當(dāng)CPU響應(yīng)該中斷時(shí)由硬件清“0”。
IT1:外部中斷源1觸發(fā)方式控制位。此位為1設(shè)置為底電平觸發(fā),為0設(shè)置為下降沿觸發(fā)。
IE0:外部中斷0請(qǐng)示源(INT0,P3.2)標(biāo)志。IE0=1,外部中斷1正在向CPU請(qǐng)求中斷,當(dāng)CPU響應(yīng)該中斷時(shí)由硬件清“0”。
IT0:外部中斷源0觸發(fā)方式控制位。此位為1設(shè)置為底電平觸發(fā),為0設(shè)置為下降沿觸發(fā)。
二、我們來看一下定時(shí)器的4種工作模式
1、工作模式0:
由TL0的低5位和TH0的全部8位共同構(gòu)成一個(gè)13位的定時(shí)器/計(jì)數(shù)器,定時(shí)器/計(jì)數(shù)器啟動(dòng)后,定時(shí)或計(jì)數(shù)脈沖個(gè)數(shù)加到TL0上,從預(yù)先設(shè)置的初值(時(shí)間常數(shù))開始累加,不斷遞增1,當(dāng) TL0計(jì)滿后,向TH0進(jìn)位,直到13位寄存器計(jì)滿溢出,TH0溢出時(shí),置位TCON中的TF0標(biāo)志,向CPU發(fā)出中斷請(qǐng)求。并且定時(shí)器/計(jì)數(shù)器硬件會(huì)自動(dòng)地把13位的寄存器值清0,如果需要進(jìn)一步定時(shí)/計(jì)數(shù),需要使用相關(guān)指令重置時(shí)間常數(shù),并把定時(shí)器/計(jì)數(shù)器的中斷標(biāo)記TF0置0。
2、工作模式1:最常用的定時(shí)器工作模式
模式1與模式0幾乎完全相同,唯一的區(qū)別就是,模式1中的寄存器TH0和TL0共同構(gòu)成的是一個(gè)16位定時(shí)器/計(jì)數(shù)器來參與操作,因此比模式0中的定時(shí)/計(jì)數(shù)范圍更大
3、工作模式2: 工作方式2特別適合于用作較精確的脈沖信號(hào)發(fā)生器。
這種模式又稱為自動(dòng)再裝入預(yù)置數(shù)模式。有時(shí)候,我們的定時(shí)/計(jì)數(shù)操作是需要多次重復(fù)定時(shí)/計(jì)數(shù)的,如果溢出時(shí)不做任何處理,那么,在第二輪定時(shí)/計(jì)數(shù)時(shí)就是從0開始定時(shí)/計(jì)數(shù)了,而這并不是我們想要的。所以,要保證每次溢出之后,再重新開始定時(shí)/計(jì)數(shù)的操作是我們想要的,那就要把預(yù)置數(shù)(時(shí)間常數(shù))重新裝入某個(gè)地方,而重新裝入預(yù)置數(shù)的操作是硬件設(shè)備自動(dòng)完成的,不需要人工干預(yù),所以這種工作模式就叫自動(dòng)再裝入預(yù)置數(shù)方式。在工作模式2中,把自動(dòng)重裝入的預(yù)置數(shù)存放在定時(shí)器/計(jì)數(shù)器的寄存器的高8位中,也就是存放在TH0中,而只留下TL0參與定時(shí)/計(jì)數(shù)操作。
這個(gè)工作模式常用于波特率發(fā)生器(串口通信),T1工作在串口模式2;用于這種方式時(shí),定時(shí)器就是為了提供一個(gè)時(shí)間基準(zhǔn);計(jì)數(shù)溢出之后,不需要做太多的事情,只做一件事就可以,就是重新裝入預(yù)置數(shù),再開始重新計(jì)數(shù),而且中間不需要任何延時(shí)。
4、工作模式3:
方式3只適用于定時(shí)/計(jì)數(shù)器T0,定時(shí)器T1處于方式3時(shí)相當(dāng)于TR1=0,停止計(jì)數(shù)由于定時(shí)器/計(jì)數(shù)器T1沒有工作模式3,如果把定時(shí)器/計(jì)數(shù)器T0設(shè)置為工作模式3,那么TL0和TH0將被分割成兩個(gè)相互獨(dú)立的8位定時(shí)器/計(jì)數(shù)器。
三、定時(shí)計(jì)數(shù)器初值的確定
1、計(jì)數(shù)器計(jì)數(shù)初值確定
計(jì)數(shù)初值C=模-X
注:模為選用定時(shí)方式的最大數(shù)值,如方式一的模為65536
2、定時(shí)器定時(shí)初值
定時(shí)初值C=[t/MC] 注: MC-- 機(jī)器周期,t預(yù)定時(shí)間
3、定時(shí)器不同方式初值
工作方式0:13位定時(shí)器/計(jì)數(shù)器工作模式,最多可計(jì)數(shù)2的13次方次,即:8192次
工作方式1:16位定時(shí)器/計(jì)數(shù)器工作模式,最多可計(jì)數(shù)2的16次方次,即:65536次
工作方式2:8位定時(shí)器/計(jì)數(shù)器工作模式,最多可計(jì)數(shù)2的8次方次,即:256次,
工作方式3:8位定時(shí)器/計(jì)數(shù)器工作模式,最多可計(jì)數(shù)2的8次方次,即:256次
4、定時(shí)計(jì)數(shù)器初值載入寄存器
TH0=(65536-9216)/256
TL0=(65536-9216)%256
四、定時(shí)計(jì)數(shù)器的具體使用
定時(shí):定時(shí)計(jì)數(shù)器作為定時(shí)器使用,配置步驟如下:
1.模式設(shè)置,配置TMOD寄存器
2.定時(shí)器初值設(shè)置 假設(shè)10ms中斷
3.開定時(shí)器中斷
4.開總中斷
5.打開定時(shí)器
#include
sbit led=P1^0;
unsigned int flag;
void main()
{
TMOD=0x01;//1.模式設(shè)置,00000001,采用的是定時(shí)器0,工作與式1(M1=0,M0=1)。
TH0=(65536-10000)/256; //2.定時(shí)器設(shè)置,每隔10毫秒發(fā)起一次中斷。
TL0=(65536-10000)%256;
ET0=1; //3.開定時(shí)器0中斷
EA = 1; //4.開總中斷
TR0=1; //5.打開定時(shí)器
while(1)
{
if(flag==100)
{
led=~led;
flag=0;
}
}
}
void TIM0() interrupt 1 //中斷服務(wù)程序
{
TH0=(65536-10000)/256; //進(jìn)入中斷要重新設(shè)置定時(shí)器處置,要注意。
TL0=(65536-10000)%256;
flag++;
}
計(jì)數(shù):定時(shí)計(jì)數(shù)器作為計(jì)數(shù)器使用,配置步驟如下:
1.模式設(shè)置,配置TMOD寄存器。
2.開計(jì)數(shù)器中斷
3.開總中斷
4.打開計(jì)數(shù)器
通過這簡單的四步,我們就打開了一個(gè)計(jì)數(shù)器,可以對(duì)P3.4或者P3.5進(jìn)行下降沿的脈沖計(jì)數(shù),這里有一點(diǎn)要注意就是計(jì)數(shù)器可以不開中斷,這樣溢出時(shí)只是不會(huì)進(jìn)去中斷服務(wù)程序。
計(jì)數(shù)器示例程序
#include
sbit led=P1^0;
sbit s=P3^4;
unsigned int count;
void main()
{
TMOD=0x05; //1.模式設(shè)置,00000101,采用的是計(jì)數(shù)器0,工作模式1(M1=0,M0=1)。
TH0=0; //計(jì)數(shù)器清零
TL0=0;
ET0=1; //2.開計(jì)數(shù)器0中斷
EA=1; //3.開總中斷
TR0=1; //4.打開計(jì)數(shù)器
led=1;
while(1)
{
count=(TH0<<8)|TL0;
if((count*10000)==50000)//按5下按鍵led狀態(tài)取反
{
led=0;
TH0=0XFF;
TL0=0XFF; //人為的讓計(jì)數(shù)器進(jìn)入中斷
}
}
}
void TIM0() interrupt 1 //中斷服務(wù)程序
{
led=1;
TH0=0;
TL0=0;
}