基于AT89C51單片機(jī)的頻率計(jì)的C源程序及頻率計(jì)實(shí)現(xiàn)的主要功能
本文是基于AT89C51單片機(jī)的頻率計(jì)的C源程序。該頻率計(jì)主要實(shí)現(xiàn)的功能有如下幾個(gè):
1. 測試功能
它表明數(shù)字頻率計(jì)所具備的全部測試功能,一般包括測頻,周期,累計(jì)脈沖數(shù),頻率比,時(shí)間間隔及自較等功能。
2. 測量范圍
它說明不同功能的有效測量范圍。如測頻率時(shí),測量范圍是數(shù)字頻率計(jì)處于正常工作條件下,被測信號(hào)的頻率范圍,一般用頻率的上,下限值表示,低端大部分從10Hz開始;高端因不同的頻率計(jì)而異。因此高端頻率是確定低,中,高速計(jì)數(shù)器的依據(jù)。在測量周期時(shí),測量范圍常用周期的最大值,最小值表示。
3. 輸入特性
數(shù)字頻率計(jì)一般有2~3個(gè)輸入通道,測試不同項(xiàng)目時(shí),被測信號(hào)可經(jīng)不同的通道輸入儀器。輸入特性是表明數(shù)字式頻率計(jì)于被測信號(hào)源相連的一組特性參數(shù),通常包括以下幾個(gè)方面。
?。?)輸入靈敏度。通常指儀器能正常工作的最小輸入電壓的有效值。常用的數(shù)字頻率計(jì)的靈敏度在100mV左右。
(2)最大輸入電壓。指儀器所能允許的最大輸入電壓值,被測信號(hào)超過該值,則儀器不能保證正常工作,甚至?xí)p壞。
?。?)輸入耦合方式。儀器設(shè)置AC和DC兩種耦合方式。AC耦合時(shí),被測信號(hào)經(jīng)隔直電容輸入,DC耦合時(shí),被測信號(hào)直接進(jìn)入輸入電路。AC耦合時(shí)適用于測量帶有直流電平的信號(hào),DC耦合適用于低頻脈沖或階躍方波信號(hào)的測量。
?。?)輸入阻抗。為了減輕信號(hào)源的負(fù)載,數(shù)字式頻率計(jì)一般采用高頻輸入阻抗。輸入阻抗由輸入電阻和輸入電容兩部分組成。
4. 顯示及工作方式
它表明可顯示的內(nèi)容,顯示數(shù)字的位數(shù),所用的顯示器件以及一次測量完畢顯示測量結(jié)果的持續(xù)時(shí)間。有的還說明電子計(jì)數(shù)器是“不記憶”顯示方式或“記憶”顯示方式。
5. 輸出
儀器可以直接輸出的標(biāo)準(zhǔn)頻率信號(hào)有幾種,而且可以表明輸出測量數(shù)據(jù)的編碼方式和輸出電平等。
C語言程序
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar temp[8]={0,0,0,0,0,0,0,0};
uchar temp1[8]={0,0,0,0,0,0,0,0};
uchar T1count,timecount,T1count1,timer,yushu,yushu1;
long fre,frx;
float zhou;
bit flag;
bit flag1;
void delay(uchar);
bit result;
sbit ird=P1^1;
sbit id=P1^0;
sbit clr=P1^2;
sbit en=P1^5;
sbit rw=P1^6;
sbit rs=P1^7;
sbit rd=P3^7;
sbit kb=P1^3;
sbit kx=P1^4;
sbit A0=P3^6;
sbit A1=P3^7;
bit start;
uchar code tab1[]="fre: ";
uchar code tab2[]="frx: ";
void delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
panduan_bz()
{
rs = 0;
rw = 1;
en = 1;
result = (bit)(P2&0x80);
en = 0;
return(result);
}
void write_com(uchar com)
{
while(panduan_bz());
rs = 0;
rw = 0;
en = 0;
P2=com;
delay(5);
en = 1;
delay(5);
en = 0;
}
void write_dat(uchar dat)
{
while(panduan_bz());
rs = 1;
rw = 0;
en = 0;
P2=dat;
delay(5);
en = 1;
delay(5);
en = 0;
}
void init()
{
uchar num;
en = 0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<16;num++)
{
write_dat(tab1[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_dat(tab2[num]);
delay(5);
}
}
void init1()
{
ird=1;
id=1;
TMOD=0x55;
TH1=0;
TL1=0; //初值為0
TH0=0;
TL0=0;
TR0=1;
TR1=1;
IE=0x8a;
RCAP2H=(65536-47850)/256; //重裝載計(jì)數(shù)器賦初值
RCAP2L=(65536-47850)%256;
ET2=1; //開定時(shí)器2中斷
EA=1; //開總中斷
TR2=1;
}
void display()
{
uchar i;
fre=(T1count*65536+TH1*256+TL1); //頻率計(jì)算
temp[0]=fre/10000000;
temp[1]=fre%10000000/1000000;
temp[2]=fre%10000000%1000000%1000000/100000;
temp[3]=fre%10000000%1000000%1000000%100000/10000;
temp[4]=fre%10000000%1000000%1000000%100000%10000/1000;
temp[5]=fre%10000000%1000000%1000000%100000%10000%1000/100;
temp[6]=fre%10000000%1000000%1000000%100000%10000%1000%100/10;
temp[7]=fre%10000000%1000000%1000000%100000%10000%1000%100%10;
if(fre<=999)
{
write_com(0x80+4);
for(i=0;i<8;i++)
{
write_dat(0x30+temp[i]); //保存要顯示的數(shù)到顯示緩沖區(qū)
}
write_dat('H');
write_dat('z');
write_dat(' ');
write_dat(' ');
}
else if(fre>=1000)
{
write_com(0x80+4);
for(i=0;i<8;i++)
{
write_dat(0x30+temp[i]); //保存要顯示的數(shù)到顯示緩沖區(qū)
if(i==4)
{
write_dat('.');
}
}
write_dat('K');
write_dat('H');
write_dat('z');
}
T1count=0;
timecount=0;
TH1=0;
TL1=0;
TH0=0;
TL0=0; //定時(shí)器0重新裝值,保證精確(不加的話只是最多差0.001s,0.1%)
}
void display1()
{
uchar j;
float zhou;
zhou=((T1count1*65536+TH0*256+TL0)*1.0549);
frx=(long)((zhou)*256);
temp1[0]=frx/10000000;
temp1[1]=frx%10000000/1000000;
temp1[2]=frx%10000000%1000000%1000000/100000;
temp1[3]=frx%10000000%1000000%1000000%100000/10000;
temp1[4]=frx%10000000%1000000%1000000%100000%10000/1000;
temp1[5]=frx%10000000%1000000%1000000%100000%10000%1000/100;
temp1[6]=frx%10000000%1000000%1000000%100000%10000%1000%100/10;
temp1[7]=frx%10000000%1000000%1000000%100000%10000%1000%100%10;
if(frx<=999)
{
write_com(0x80+0x40+4);
for(j=0;j<8;j++)
{
write_dat(0x30+temp1[j]); //保存要顯示的數(shù)到顯示緩沖區(qū)
}
write_dat('H');
write_dat('z');
write_dat(' ');
write_dat(' ');
}
else if(frx>=1000)
{ // frx=frx/1000;
write_com(0x80+0x40+4);
for(j=0;j<8;j++)
{
write_dat(0x30+temp1[j]); //保存要顯示的數(shù)到顯示緩沖區(qū)
if(j==4)
{
write_dat('.');
}
}
write_dat('K');
write_dat('H');
write_dat('z');
}
}
void main(void)
{
init();
init1();
while(1)
{
rd=0;
ird=1;
if(flag==1) //標(biāo)志位為1,表示進(jìn)行完了一次1S記數(shù)
{
flag=0;
kb=0;
kx=1;
clr=0;
ird=0;
id=0;
display1();
display();
}
else
{
kb=1;
kx=0;
}
}
}
void t1(void) interrupt 3 // 記數(shù)器中斷,加1
{
T1count++;
}
void t0(void) interrupt 1 // 記數(shù)器中斷,加1
{
T1count1++;
}
void Timer2() interrupt 5 //調(diào)用定時(shí)器2,自動(dòng)重裝載模式
{
uchar i=0; //定義靜態(tài)變量i
TF2=0; //定時(shí)器2的中斷標(biāo)志要軟件清0
timecount++; //計(jì)數(shù)標(biāo)志自加1
if(timecount==20) //判斷是否到1s
{
timecount=0; //將靜態(tài)變量清0
flag=1;
}
}