鳳嬌
(山東科技大學機械電子工程學院 山東 青島 266590)
基于51單片機的脈沖頻率的測量方法
于蘭浩王賀王鳳嬌李家成
(山東科技大學機械電子工程學院山東青島266590)
在現代測控系統(tǒng)中,我們經常需要測量一個脈沖的頻率,如果使用專門的測量儀器,會增加測量成本,而很多單片機的定時器具有捕獲功能,可以測量頻率不是很高的脈沖的頻率,單片機價格低廉,這樣就降低了測控成本。
通常來說,用單片機來測量一個脈沖的頻率:使用兩個定時器,一個定時器來測量脈沖的個數,一個定時器用來定時,用測到的時間比上個數得到一個脈沖的寬度,再求得頻率。這樣做的缺點是浪費了單片機寶貴的硬件資源,編寫程序也比較麻煩。而我們采用單片機定時器2的捕獲功能,實際上在計時的同時計數,這樣節(jié)省了一個定時器/計數器,編寫程序也較為方便。但是需要注意的是,輸入脈沖的最高頻率應低于單片機振蕩頻率的1/24。在一般測控場合,用單片機測量頻率完全能達到要求,故選用stc89c52單片機能符合要求。
單片機的定時器2有三種工作模式:16位自動重裝,16位捕獲,波特率發(fā)生器。捕獲模式的原理是:單片機內部有兩組寄存器,其中(TLX,THX)內部數值按照機器周期增減,當與捕獲功能相關的外部引腳有負跳變時,捕獲便會立即將此時第一組寄存器中的數值準確的獲取,并存入陷阱寄存器(RCAPXL,RCAPXH)中,同時向cpu申請中斷,以方便軟件記錄。當該引腳下一次跳變產生時,便會產生另一次捕獲,再次向cpu申請中斷,軟件再一次記錄數據,根據兩次數據之差便是可以算出脈沖周期。這里需要用到定時器2的控制寄存器T2CON,其地址為C8H。寄存器位如表1所示:
表1
其中,TF2為定時器2溢出標志位。EXF2為定時器2外部標志,當有捕獲產生時,該位置1,申請中斷,在中斷服務程序中需要將該位認為清零。RCLK、TCLK為接受發(fā)送時鐘,在此處不用。EXEN2為定時器2外部使能標志,該位為1,當定時器2未作為串口時鐘使用時,允許T2EX負跳變產生捕獲或重裝。C/T2為定時器/計數器選擇,當該位為0時為定時器。CP/RL2為捕獲/重裝標志,使用捕獲模式需設該位為1.捕獲的原理如圖1所示:
圖1
當EXEN2=1時,外部輸入T2EX(在stc89c51中為p1.1)由1變0時,將定時器2中TH2和TL2的當前值分別裝入RCAP2H和RCAP2L中。此外,T2EX負跳變使EXF2置位,EXF2與TF2一樣也可以引起中斷,這兩個中斷量具有相同中斷地址。在中斷服務程序中,我們可以查詢EXF2與TF2狀態(tài)來確定中斷是由誰引起的。注意這里TH2、TL2沒有自動重裝初值。
在弄清楚了捕獲原理與T2CON寄存器后,對程序進行設計。我們選用KEIL編譯軟件,注意在KEIL軟件的”reg52.h”頭文件里面并沒有對T2CON進行聲明,故我們若用到該寄存器,必須自己單獨進行聲明。由于源程序較長,只將定時器2初始化程序與中斷服務程序編寫如下:
定時器2初始化程序:
void Timer2Init()
{
T2CON=0x0d; //定時器2工作在捕獲模式,由外部輸入信號產生捕獲,啟動定時器
RCAP2L=0x00; //清零
RCAP2H=0x00;
TL2=0x00;TH2=0x00;
ET2=1; //定時器2中斷使能
EA=1; //開總中斷
}
中斷服務程序:
void INT_Timer2()interrupt 5
{
if(TF2)//溢出中斷,進行結算
{
TR2=0; TF2=0; //定時器停止計數,定時器2溢出標志清零
NP1=N; //脈沖個數
N=0; //清零為下一次做準備
if(Cap1>Cap0)
{
frequency=1000000*(NP1-1) /(Cap1-Cap0);//捕獲回來的頻率
}
TL2=0x00;TH2=0x00;TR2=1; //數據重載
}
else //捕獲中斷
{
EXF2=0; //捕獲中斷標志清零
if(N==0)
{
Cap0=RCAP2H; //高8位
Cap0=(Cap0<<8)|RCAP2L;//或上低8位得16位
N=1;
}
else
{
N++;Cap1=RCAP2H;Cap1=(Cap1<<8)|RCAP2L;
}
}
}
用該型號單片機測量脈沖信號的頻率時精度比較高,成本非常低,只要將測得的數據通過數碼管顯示或者傳到上位機,我們便可以獲得該信號的頻率了。