#include<reg52.h>
#include<math.h>
unsigned char t="0",yichu=0,fenpin;
#define uchar unsigned char
#define uint unsigned int
sbit s0=P2^0;
sbit s1=P2^1;
sbit s2=P2^2;
sbit GATE="P2"^4;
//sbit CLR="P2"^7;
sbit P33=P3^3;
sbit led_wei=P2^7;
sbit led_duan=P2^6;
uchar bin="0";
//uchar code table_wei[]={0x01,0x02,0x04,0x08,0x10,0x20};
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9的共阳极代码
//unsigned char a[5]={0,0,0,0,0};
void delay1(uint z)
{
uint x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}
//定时器0
void t0(void)interrupt 1
{
t++;
yichu=2; //定时器0溢出,yichu=2
}
//计数器1
void t1(void)interrupt 3 //计数器1溢出,yichu=1
{
TCON=0;
yichu=1;
TH1=0xff;
TL1=0xff;
P0=0xff;
}
void delay(void) //1s软件延时
{
unsigned int i="500",j;
while(i)
{
i--;
j=249;
while(j)
{
j--;
}
}
}
display(float f) //以测出的频率串行输出
{
unsigned long x;
unsigned char a[5]={0,0,0,0,0},i=0,j;
if(f!=0)
{
if((f<=99999)&&(f>1)) //正常显示
{
if(f>10000) f="f"+2; //软件修正频率偏差
if(f>30000) f="f"+10;
if(f>40000) f="f"+10;
while(f<9999)
{
f=f*10;
i++;
}
x=f*100;
a[4]=x%10;
if(a[4]>=5)f=f+1; //软件修正频率偏差
x=f;
a[0]=x%10;
a[1]=(x/10)%10;
a[2]=(x/100)%10;
a[3]=(x/1000)%10;
a[4]=(x/10000)%10;
for(j=0;j<5;j++)
{
a[j]=table[a[j]];
}
// a[i+1]++;
//a[0]=0;
// a[0]=0xc0;
}
else
if(f>=100000) //以科学计数法显示
{
f=f+8;
while(f>=99999)
{
f=f/10;
i++;
}
x=f;
a[4]=(unsigned char)((float)((f-x))*10);
if(a[4]>=5) x++; //四舍五入
//x=(x<<6)+(x<<5)+(x<<2);
//x=x*100;
a[0]=x%10+2;
a[1]=(x/10)%10;
a[2]=(x/100)%10;
a[3]=(x/1000)%10;
a[4]=(x/10000)%10;
//a[0]=i+2;
for(j=0;j<5;j++)
{
a[j]=table[a[j]];
}
//a[4]++;
//a[1]=0x80;
}
else
{
x=f*10000; //频率值小于1
if((x%10)>=5)x=x+10; //四舍五入
a[0]=x%10;
x=x/10;
a[1]=x%10;
a[2]=(x/10)%10;
a[3]=(x/100)%10;
a[4]=(x/1000)%10;
for(j=0;j<5;j++)
{
a[j]=table[a[j]];
}
//a[4]++;
//a[0]=0xc0;
}
}
for(j=0;j<5;j++) //串行
{
SBUF=a[j];
while(TI==0);
//TI=0;
}
}
void cepin()
{
unsigned char i;
float sj;
unsigned long js;//时间、计数的拼音首字母
float f; //f为频率
TMOD=0xd9; //开外部中断 方式3时T1停止工作 T0工作在方式1
t=0;
TH0=0;
TL0=0;
TH1=0;
TL1=0;
GATE=0;
TCON=0x50;//开T0
GATE=1;
delay(); //开通1S
GATE=0;
for(i=0;i<250;i++)
{} //延时1ms
sj=((float)(TH0*256+t*65536+TL0))/1000000.0;
js=(long)TH1*256+TL1+1;
f=(js/sj)*fenpin;
display(f);
}
void panduan()
{
float zhouqi;
s0=1; //256分频
s1=1;
s2=1;
TMOD=0x51; //T1计数,方式1. T0定时,方式1
TH0=0xce; //定时器0=12.8ms ce00H=(65536-12800)h
TL0=0;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50; //启动T0,T1
while(yichu==0);
TCON=0;
if(yichu==1) //计数器先溢出:在12.8ms内测得的脉冲过多,说明频率较高 f>2M
{
fenpin="256";//转为测256分频后的频率,
cepin();
}
else //计时器先溢出:100个脉冲的时间比较短,即频率较低,可以减少分频数,即12.8ms中测得脉冲过少.f<2M
{
yichu=0;
s0=0; //128分频
s1=1;
s2=1;
TH0=0xc1; //定时器0=16ms
TL0=0x80;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1) //计数器先溢出:在16ms内测得的脉冲过多,说明频率较高,800k<f<2M
{
fenpin=128;//转为测64分频后的频率
cepin();
}
else
{
yichu=0;
s0=1; //64分频
s1=0;
s2=1;
TH0=0xc1; //定时器0=16ms
TL0=0x80;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1) //f>400kHZ
{
fenpin=64;
cepin();
}
else //计时器先溢出:100个脉冲的时间比较短,即频率较低,用2分频测周期,f<400kHZ.
{
yichu=0;
s0=0; //32分频
s1=0;
s2=1;
TH0=0xb1; //定时器0=20ms
TL0=0xe0;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1) //计数器先溢出:在16ms内测得的脉冲过多,说明频率较高400k>f>160k
{
fenpin=32;//转为测32分频后的频率
cepin();
}
else //f<160k
{
yichu=0;
s0=1; //16分频
s1=1;
s2=0;
TH0=0xc1; //定时器0=16ms
TL0=0x80;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1) //160k>f>100kHZ
{
fenpin=16;
cepin();
}
else //f<100k
{
yichu=0;
s0=1; //2分频
s1=0;
s2=0;
TH0=0xc1; //定时器0=16ms
TL0=0x80;
TH1=0xff; //计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1) //160k>f>12kHZ
{
fenpin=2;
cepin();
}
else //计时器先溢出:100个脉冲的时间比较短,即频率较低,用1分频测周期,f<1kHZ.
{
s0=0; //以下是测周期部分
s1=0;
s2=0;
TH0=0;
TL0=0;
t=0;
TMOD=0x09;
TR0=1;
GATE=1;
while(P33==0);
GATE=0;
while(P33==1);
TR0=0;
zhouqi=(TH0*256+t*65536+TL0)/1000000.0; // ?
if(zhouqi<0.001) //若周期太小,则转为测原频率,即频率大于1kHZ
{
fenpin=1;
s0=0;
s1=0;
s2=0;
cepin();
}
else
{
display((1.0/zhouqi));
}
}
}
}
}
}
}
}
main()
{
IE=0x8a;
while(1)
{
panduan(); //判断原频率属于哪个范围,并调用相应函数测其频率
// delay1(100);
}
}
文章评论(0条评论)
登录后参与讨论