本文是基于AT89C51單片機的頻率計的C源程序。該頻率計主要實現的功能有如下幾個:
1. 測試功能
它表明數字頻率計所具備的全部測試功能,一般包括測頻,周期,累計脈沖數,頻率比,時間間隔及自較等功能。
2. 測量范圍
它說明不同功能的有效測量范圍。如測頻率時,測量范圍是數字頻率計處于正常工作條件下,被測信號的頻率范圍,一般用頻率的上,下限值表示,低端大部分從10HZ開始;高端因不同的頻率計而異。因此高端頻率是確定低,中,高速計數器的依據。在測量周期時,測量范圍常用周期的最大值,最小值表示。
3. 輸入特性
數字頻率計一般有2~3個輸入通道,測試不同項目時,被測信號可經不同的通道輸入儀器。輸入特性是表明數字式頻率計于被測信號源相連的一組特性參數,通常包括以下幾個方面。
(1)輸入靈敏度。通常指儀器能正常工作的最小輸入電壓的有效值。常用的數字頻率計的靈敏度在100mV左右。
(2)最大輸入電壓。指儀器所能允許的最大輸入電壓值,被測信號超過該值,則儀器不能保證正常工作,甚至會損壞。
(3)輸入耦合方式。儀器設置AC和DC兩種耦合方式。AC耦合時,被測信號經隔直電容輸入,DC耦合時,被測信號直接進入輸入電路。AC耦合時適用于測量帶有直流電平的信號,DC耦合適用于低頻脈沖或階躍方波信號的測量。
(4)輸入阻抗。為了減輕信號源的負載,數字式頻率計一般采用高頻輸入阻抗。輸入阻抗由輸入電阻和輸入電容兩部分組成。
4. 顯示及工作方式
它表明可顯示的內容,顯示數字的位數,所用的顯示器件以及一次測量完畢顯示測量結果的持續時間。有的還說明電子計數器是“不記憶”顯示方式或“記憶”顯示方式。
5. 輸出
儀器可以直接輸出的標準頻率信號有幾種,而且可以表明輸出測量數據的編碼方式和輸出電平等。
#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;? //重裝載計數器賦初值
RCAP2L=(65536-47850)%256;
ET2=1;??????????? ?//開定時器2中斷
EA=1;?????????????? //開總中斷
TR2=1;???????????
}
?
void display()
{
uchar i;
?????? ?fre=(T1count*65536+TH1*256+TL1);? //頻率計算
?????? ?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]);????? //保存要顯示的數到顯示緩沖區
????????????? ?}??
????????????? ?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]);????? //保存要顯示的數到顯示緩沖區
????????????? ?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; //定時器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]);??? //保存要顯示的數到顯示緩沖區
????????????? ?}??
????????????? ?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]);??? //保存要顯示的數到顯示緩沖區
????????????? ?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)??? //標志位為1,表示進行完了一次1S記數
????????????? {
????????????? flag=0;
????????????? kb=0;
????????????? kx=1;???????????
????????????? clr=0;
????????????? ird=0;
????????????? id=0;
????????????? display1();
????????????? display();
????????????? }
????????????? else
????????????? {
????????????? kb=1;
????????????? kx=0;
????????????? }???? ? ?? ???
????
?????? ?
? }??????? ?? ?
?}
void t1(void) interrupt 3?? ?? // 記數器中斷,加1
?{
?T1count++;
?}
?
void t0(void) interrupt 1?? ?? // 記數器中斷,加1
?{
?T1count1++;
?}
void Timer2() interrupt 5????? //調用定時器2,自動重裝載模式
{
uchar i=0;??????? //定義靜態變量i
TF2=0;??????????? //定時器2的中斷標志要軟件清0
timecount++;??? ???????//計數標志自加1
if(timecount==20)?????????? //判斷是否到1s
?????? {
?????? timecount=0;????????????? //將靜態變量清0???????????????????????????????????????????????
?????? flag=1;
?????? }
}
評論