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

📄 51

📁 51单片机应用系统典型模块开发大全
💻
字号:
#include<reg51.h>
#include <absacc.h>
#define 	uchar   unsigned char
#define 	uint   	unsigned int
#define 	ulong 	unsigned long
uchar t=0,yichu=0,fenpin;
sbit B153=P2^0;							//74153输出B端
sbit A153=P2^1;							//74153输出A端
sbit GATE=P2^6;							//门端
sbit CLR=P2^7;							//清除端
sbit P33=P3^3;							//中断输入
void delay(void);						//1s软件延时
uchar table(uchar x);					//字形代码查表输出
void display(float f);					//以测出的频率串行输出显示
void cepin(void);						//频率测试
void panduan(void);						//频率判断

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

void panduan(void)						//频率判断
{
	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));
			}
		}
	}
}


void cepin(void)						//频率测试
{
	uchar i;
	float sj;
	ulong 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);							//显示
}




void t0(void) interrupt 1				//T0中断服务程序
{
	t++;								//t加1
	yichu=2;							//定时器0溢出,yichu=2
}

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


void display(float f)					//以测出的频率串行输出显示
{
	ulong x;
	uchar i=0,j,a[5]={0,0,0,0,0};
	if(f!=0)							//频率不为0
	{
		if((f<10000)&&(f>1))			//正常显示1~9999
		{
			if(f>1000)
				f=f-1;					//软件修正频率偏差
			while(f<1000)				//数据小时 扩大 并记录指数
			{
				f=f*10;
				i++;
			}
			x=f*10;						//再扩大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;						//指数为0
		}
		else if(f>=10000)				//以科学计数法显示
		{
			while(f>=1000)				//大于1千
			{
				f=f/10;					//除10 缩小10倍 记录指数
				i++;
			}
			x=f;
			a[4]=(uchar)((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);
	}
}

void delay(void)						//1s软件延时
{
	uint i=500,j;
	while(i)
	{
		i--;
		j=250;
		while(j)
		{
			j--;
		}
	}
}

uchar table(uchar x)					//字形代码查表输出
{
	uchar code n[10]={0xee,0x82,0xdc,0xd6,0xb2,0x76,0x7e,0xc2,0xfe,0xf6};
	return(n[x]);
}

⌨️ 快捷键说明

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