⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 频率计.c

📁 单片机的频率计
💻 C
字号:
#include<reg52.h>
unsigned char t=0,yichu=0,fenpin;
sbit B153=P2^0;
sbit A153=P2^1;
sbit GATE=P2^6;
sbit CLR=P2^7;
sbit P33=P3^3;


void t0(void)interrupt 1
{t++;
yichu=2;								//定时器0溢出,yichu=2
}

void t1(void)interrupt 3				//计数器1溢出,yichu=1
{TCON=0;
yichu=1;
TH1=0xff;
TL1=0xff;
}

void delay(void)						//1s软件延时
{unsigned int i=500,j;
while(i)
	{i--;
	j=250;
	while(j)
		{j--;}
	}
}
unsigned char table(unsigned char x)	//软件查表输出
{unsigned char code n[10]={0xee,0x82,0xdc,0xd6,0xb2,0x76,0x7e,0xc2,0xfe,0xf6};
return(n[x]);
}

display(float f)						//以测出的频率串行输出
{unsigned long x;
unsigned char a[5]={0,0,0,0,0},i=0,j;
if(f!=0){
if((f<10000)&&(f>1))					//正常显示
	{if(f>1000)f=f-1;					//软件修正频率偏差
	while(f<1000)
		{f=f*10;
		i++;
		}
	x=f*10;
	a[4]=x%10;
	if(a[4]>=5)f=f+1;;
	x=f;
	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[i+1]++;
	a[0]=0;
	}
else if(f>=10000)						//以科学计数法显示
	{while(f>=1000)
		{f=f/10;
		i++;
		}
	x=f;
	a[4]=(unsigned char)((float)((f-x))*10);
	if(a[4]>=5)x++;						//四舍五入
	a[2]=x%10;
	a[3]=(x/10)%10;
	a[4]=(x/100)%10;
	a[0]=i+2;
	for(j=0;j<5;j++)
		{a[j]=table(a[j]);}
	a[4]++;
	a[1]=0x7c;
	}
else
	{x=f*10000;							//频率值小于1
	if((x%10)>=5)x=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]=0;
	}
	
}
for(j=0;j<5;j++)			//串行
	{SBUF=a[j];
	while(TI==0);}

}

cepin()
{unsigned char i;
float sj;
unsigned long js;//时间、计数的拼音首字母
float f;		//f为频率
TMOD=0xd9;
t=0;
TH0=0;
TL0=0;
TH1=0;
TL1=0;
GATE=0;
TCON=0x50;
GATE=1;
delay();
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);
}



panduan()
{float zhouqi;
B153=1;
A153=1;
TMOD=0x51;		
TH0=0xce;		//定时器0=12.8ms
TL0=0;
TH1=0xff;		//计数器1=100个脉冲
TL1=0x9c;
TCON=0x50;
while(yichu==0);
TCON=0;
if(yichu==1)	//计数器先溢出:在12.8ms内测得的脉冲过多,说明频率较高
	{fenpin=128;//转为测128分频后的频率
	cepin();}
else 			//计时器先溢出:100个脉冲的时间比较短,即频率较低,可以减少分频数
	{yichu=0;
	B153=1;
	A153=0;
	TH0=0xc1;	//定时器0=16ms
	TL0=0x80;
	TH1=0xff;	//计数器1=100个脉冲
	TL1=0x9c;
	TCON=0x50;
	while(yichu==0);
	TCON=0;
	if(yichu==1)   //计数器先溢出:在16ms内测得的脉冲过多,说明频率较高
		{fenpin=16;//转为测16分频后的频率
		cepin();}
	else		 //计时器先溢出:100个脉冲的时间比较短,即频率较低,用2分频测周期
		{B153=0; //以下是测周期部分
		A153=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)	//若周期太小,则转为测原频率
			{fenpin=1;
			B153=0;
			A153=0;
			cepin();}
		else{display((1.0/zhouqi));}
		}
	}
}



main()
{
IE=0x8a;
while(1)
	{
	panduan();	//判断原频率属于哪个范围,并调用相应函数测其频率
	delay();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -