定時(shí)器中斷—頻率計(jì)程序
/*注:定時(shí)器中斷的例子,簡單的頻率計(jì),初學(xué)者留意各引腳電
壓極性和電壓值,不可超出5V,我們只是做學(xué)習(xí)實(shí)驗(yàn),不要
超出51hei單片機(jī)學(xué)習(xí)板的承受范圍,否則要求對(duì)電子非常熟悉,
不然會(huì)燒壞芯片,版權(quán):www.51hei.com,注意:P1.3與P1.7要相連接
如果是測量外部頻率要共地.
*/
#includereg52.h> //頭文件
#includeintrins.h>
#define uchar unsigned char//宏定義
#define uint unsigned int
sbit Fin=P1^3; //測量頻率管腳
sbit Fout=P1^7; //發(fā)生頻率管腳
uchar code table[]={0x3f,0x06,0x5b,//數(shù)碼管顯示的數(shù)值
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,};
void display(uchar *lp,uchar lc); //顯示子函數(shù)
void delay(); //延時(shí)子函數(shù)
void mee_F(); //測頻率子函數(shù)
void mee_T(); //測周期子函數(shù)
void Fry_mee(); //測頻測周選擇的子函數(shù)
uchar l_tmpdata[8]; //程序顯示的緩沖區(qū)
bit int_flag; //中斷事件相應(yīng)的標(biāo)志
uint fry; //保存的頻率值
void init() ;
void main() //主函數(shù)
{
init(); // 調(diào)用初始化函數(shù)
}
void init() //初始化函數(shù)
{
uint tmp; //數(shù)據(jù)轉(zhuǎn)換緩沖區(qū)
uint i=2000;//顯示延時(shí),提高亮度
EA=1; //打開總中斷
TMOD=0x11;//工作方式3
TH0=256-(50000/256); //裝入初值
TL0=256-(50000%256);
TH1=256-500/256;
TL0=256-500%256;
ET0=1; //定時(shí)器0開
ET1=1; //定時(shí)器1開
TR1=1; //啟動(dòng)定時(shí)器1
while(1)
{
Fry_mee();//開始測量
l_tmpdata[0]=tmp/10000; //測量完后將整數(shù)分離出來
tmp=tmp%10000; //進(jìn)行顯示
l_tmpdata[1]=tmp/1000;
tmp=tmp%1000;
l_tmpdata[2]=tmp/100;
tmp=tmp%100;
l_tmpdata[3]=tmp/10;
l_tmpdata[4]=tmp%10;
while(i--) //顯示延時(shí),提高亮度
{
display(l_tmpdata,5); //用數(shù)字顯示頻率
}
i=2000; //從新裝入初值
}
}
void time0() interrupt 1 //定時(shí)器0的中斷函數(shù)
{
int_flag=1; //中斷標(biāo)志
}
void time1() interrupt 3 //定時(shí)器1的中斷函數(shù),用來產(chǎn)生頻率
{
TH1=(65536-1000)/256; //從新賦值
TL1=(65536-1000)%256;
Fout=!Fout; //?反,產(chǎn)生頻率,即頻率發(fā)生器
}
void Fry_mee()
{
if(fry2000) //?于2k的,側(cè)周
mee_T();
else if(fry>=2000) //大于2k的,測頻
mee_F();
}
//測頻原理:用一個(gè)標(biāo)準(zhǔn)的50ms計(jì)數(shù)中斷,對(duì)被測信號(hào)計(jì)數(shù)
void mee_F() //測頻子函數(shù)
{
bit lhj_old=1,lhj_new=1; //定義起始狀態(tài)
uint f_count=0;//計(jì)數(shù)變量
int_flag=0;
TH0=(65536-50000)/256;//定時(shí)器,初值50ms
TL0=(65536-50000)%256;
TR0=1; //啟動(dòng)定時(shí)器0
while(1) //死循環(huán),測頻
{
lhj_new=Fin; //?現(xiàn)在頻率引腳的狀態(tài)
if(lhj_old!=lhj_new) //與前一刻的值比較
f_count++;
lhj_old=lhj_new; //將新值賦給舊值
if(int_flag) //如果到了定時(shí)時(shí)間
{
TR0=0; //關(guān)閉定時(shí)器0
fry=f_count*10; //計(jì)算頻率,f_count=f_count*20/2
//一個(gè)周期有2個(gè)跳變,20個(gè)周期為1s
return; //返回
}
}
}
//測周原理:以被測信號(hào)的一個(gè)周期為中斷源,對(duì)單片機(jī)及其
//周期進(jìn)行計(jì)數(shù)讀?定時(shí)器的值為計(jì)數(shù)值
void mee_T() //測周子函數(shù)
{
bit lhj_old=0,lhj_new=0; //定義初始狀態(tài)
uchar temp_flag=0;
uint t_count; //計(jì)數(shù)變量
TH0=0; //賦初始值
TL0=0;
while(1) //死循環(huán),測周
{
lhj_new=Fin; //取現(xiàn)在的頻率發(fā)聲引腳的狀態(tài)
if(lhj_old!lhj_new) //當(dāng)下降沿來臨時(shí),啟動(dòng)定時(shí)器
{
temp_flag++;
TR0=1; //啟動(dòng)定時(shí)器并開始計(jì)數(shù)
}
if(temp_flag==2)
{
TR0=0; //停止計(jì)數(shù)
t_count=TH0*256+TL0;//取得當(dāng)前的計(jì)數(shù)值
fry=1000000/t_count;//計(jì)算頻率,這個(gè)1000000是
//晶振12M經(jīng)12分頻的計(jì)數(shù)脈沖
return; //返回
}
lhj_old=lhj_new;
}
}
void display(uchar *lp,uchar lc) //顯示子函數(shù)
{
uchar i;
P2=0;
P1=0xf8;
for(i=0;ilc;i++)
{
P2=table[lp[i]];
delay();
if(i==7)
break;
P2=0;
P1++;
}
}
void delay() //延時(shí)子函數(shù)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
評(píng)論