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

📄 freq.c

📁 基于单片机的数字频率相位 计
💻 C
字号:
/* Note:Your choice is C IDE */
#include "stdio.h"
#include <intrins.h>   // 外部函数头文件
#include<reg52.h>
#include<string.h>
#include<LCD1602.h>

#define uchar  unsigned char 
#define uint unsigned int

sbit ctr=P1^1;  //选择T0信号输入
  
uint freq;		//初步频率
uint cnt;		//定时重载次数
uint per;		//采样周期数
uint ave;		//采样值取平均数
uint per_0;		//暂存per
int ave_0;		//暂存ave
int per_1;		//暂存per
uint ave_1;		//暂存ave
uint xdata a[256]={0};  //相位脉冲采样的数据
uint xdata b[256]={0};  //周期采样的数据
uchar idata  str[]={"Meng  long"} ;
float peri;		//计算后的周期
float frq;		//计算后的频率
float pha;		//计算后的相位
float cnt1;		//求平均后的高电平采样值
float cnt2;		//求平均后的周期采样值
bit flag;		//判断是内部脉冲还是外部脉冲采样
bit end0,end1,end_0,end_1;
									   	
void  delay_ms(uint t) //延时函数
{
	unsigned char t2=2000;
	while(t--)while(t2--);  
}

void init_T0(void)	//初始化T0
{
	TMOD=0x15;
	TL0=0;
	TH0=0;
	cnt=0;	
}

void init_T1(void)	//初始化T1
{
//	TL1=0xDC;
//	TH1=0x0B;
	TL1=0xB0;
	TH1=0x3C;
}

void freq_1(void)   //频率初步测量
{
	ctr=1;
	init_T0();
	init_T1();
	IE=0x8A;
	TR0=1;
	TR1=1;
	while(cnt<40);
	if(cnt==40)
		{
			delay_ms(26);
			if(freq<=5)
				{
					per=2;ave=1;flag=0;
				}
			else if(freq<=20)
				{
					per=8;ave=1;flag=0;
				}
			else if(freq<=75)
				{
					per=32;ave=1;flag=0;
				}
			else if(freq<=280)
				{
					per=128;ave=1;flag=0;
				}
			else if(freq<=1100)
				{
					per=2;ave=1;flag=1;
				}
			else if(freq<=4000)
				{
					per=8;ave=4;flag=1;
				}
			else if(freq<=15000)
				{
					per=32;ave=16;flag=1;
				}
			else if(freq<=70000)
				{
					per=128;ave=64;flag=1;
				}
			else 
				{
					per=256;ave=256;flag=1;
				}
		}
	else
		{
			per=256;ave=256;
		}
	IE=0;
}


void cnt0(void) interrupt 1   //定时器/计数器0溢出中断函数
{
	TR0=0;
	TR1=0;
	cnt=41;
}

void time1(void) interrupt 3  //定时器/计数器1溢出中断函数
{
	if(cnt<40)            //T1是否需要关闭再开启??
	{
		TR0=0;
		TR1=0;
		cnt++;
		init_T1();
		TR0=1;
		TR1=1;
	}
	else 
	{
		TR0=0;
		TR1=0;
		freq=TH0*256+TL0;
	}
}

void pha_1(void)	//高电平采样
{	
	int i=0;
	float a_=0;
	float b_=0;
	cnt1=0;cnt2=0;
	per_0=per;ave_0=ave;
	per_1=per;ave_1=ave;
	end0=end1=end_0=end_1=0;
	TMOD=0x99;

	//采样相位差
	EX0=1;
	if(flag==0)	ctr=0;	
	else		ctr=1;
	
	TH0=0;TL0=0;																		
	IT0=1;
	while(end0==0)
	{
		while(INT0==1);
		while(INT0==0);
		while(INT0==1)
		{
			TR0=1;
			EA=1;
		}
		while(end_0==0);
	}
	EA=0;
	EX0=0;

	//采样周期
	EX1=1;
	if(flag==0)	ctr=0;		
	else	    ctr=1;
	
	TH1=0;TL1=0;																		
	IT1=1;
	while(end1==0)
	{
		while(INT1==1);
		while(INT1==0);
		while(INT1==1)
		{
			TR1=1;
			EA=1;
		}
		while(end_1==0);
	}

	//求均值
	for(i=0;i<ave;i++)
		{
			a_=a[i]/ave;
			cnt1=cnt1+a_;
			b_=b[i]/ave;
			cnt2=cnt2+b_;
		}
	EA=0;
	EX1=0;

}


void cyc0(void) interrupt 0// 外部中断1函数
{
	EA=0;TR0=0;		
	per_0--;
	if(per_0==0)
	{
		ave_0--;
		a[ave_0]=TH0*256+TL0+1; //读取数据
		TH0=0;TL0=0;
		per_0=per;
		if(ave_0==0)
		{
			end0=1;
		}
	}	
	end_0=1;
}
void cyc1(void) interrupt 2 //外部中断1函数
{
	EA=0;TR1=0;		
	per_1--;
	if(per_1==0)
	{
		ave_1--;
		b[ave_1]=TH1*256+TL1+1; //读取数据
		TH1=0;TL1=0;
		per_1=per;
		if(ave_1==0)
		{
			end1=1;
		}
	}	
	end_1=1;
}

/*void pha_1(void)	//高电平采样
{	
	
	uint i;
	per_0=per;ave_0=ave;
	per_1=per;ave_1=ave;	
	if(flag==0)
	{
		ctr=0;
//		TMOD=0xDD;
		TMOD=0xD0;
		IE=0x85;	
	}
	else
	{
		ctr=1;
//		TMOD=0x99;
		TMOD=0x90;
		IE=0x85;
	}
	TH0=0;TH1=0;TL0=0;TL1=0;
	IT0=1;IT1=1;
//	INT0=1;INT1=1;		   //有疑问
//	TR0=1;
	while(INT1==0)INT1=1;TR1=1;
//	while(ave_0!=-1||ave_1!=-1);
//	if(ave_0==-1&&ave_1==-1)
	while(ave_0!=-1||ave_1!=-1);
	if(ave_0==-1&&ave_1==-1)
	{
		EA=0;
		for(i=0;i<ave;i++)
		{
			a_=a[i]/ave;
			b_=b[i]/ave;
			cnt1=cnt1+a_;
			cnt2=cnt2+b_;
		}
	}
}*/
/*
void cyc0(void) interrupt 0 //外部中断0函数
{
	per_0--;
	if(per_0==0)
	{
		ave_0--;
		a[ave_0]=TH0*256+TL0; //读取数据
		TH0=0;TL0=0;
		per_0=per;
	}
	if(ave_0==0)
	{
		TR0=0;
		EX0=0;
		ave_0--;
	}
} */

/*void cyc1(void) interrupt 2 //外部中断1函数
{
	per_1--;
	if(per_1==0)
	{
		ave_1--;
		b[ave_1]=TH0*256+TL0; //读取数据
		TH1=0;TL1=0;
		per_1=per;
	}
	if(ave_1==0)
	{
		TR1=0;
		EX1=0;
		ave_1--;
	}
}										
 */
void LCD_write_3xs(int x,int y,int xs) //三位小数显示函数
{
	if(xs==0) 
	{
		LCD_write_char(x,y,'0');
		LCD_write_char(x+1,y,'0');
		LCD_write_char(x+2,y,'0');
	}
	else if(xs<10) 
		{
			LCD_write_char(x,y,'0');
			LCD_write_char(x+1,y,'0');
			LCD_write_int(x+2,y,xs);
		}	
	else if(xs<100)
		{
			LCD_write_char(x,y,'0');
			LCD_write_int(x+1,y,xs); 
		}
	else LCD_write_int(x,y,xs);
}

void LCD_write_2xs(int x,int y,int xs) //两位小数显示函数
{
	if(xs==0) 
	{
		LCD_write_char(x,y,'0');
		LCD_write_char(x+1,y,'0');
	}
	else if(xs<10) 
		{
			LCD_write_char(x,y,'0');
			LCD_write_int(x+1,y,xs);
		}	
	else 	LCD_write_int(x,y,xs); 
}

void LCD_dis(void)	//显示函数(整数部分为零调试未成功)
{
	int peri1,peri2;
	int frq1,frq2;
	uint pha1,pha2,pha_;
	long frq_,peri_;
	LCD_write_string(0,0,"f=");
	LCD_write_string(0,1,"T=");
	LCD_write_string(12,0,"P=");
	if(frq<1000)
	{
		frq_=frq*100;
		frq1=frq_/100;frq2=(frq_%100);
		if(frq1<10)
		{
			LCD_write_int(2,0,frq1);
			LCD_write_char(3,0,'.');
			LCD_write_2xs(4,0,frq2);
			LCD_write_string(6,0,"Hz");
			LCD_write_string(8,0,"   ");
		}
		else if(frq1<100)
		{
			LCD_write_int(2,0,frq1);
			LCD_write_char(4,0,'.');
			LCD_write_2xs(5,0,frq2);
			LCD_write_string(7,0,"Hz");
			LCD_write_string(9,0,"  ");
		}
		else 
		{
			LCD_write_int(2,0,frq1);
			LCD_write_char(5,0,'.');
			LCD_write_2xs(6,0,frq2);
			LCD_write_string(8,0,"Hz");
			LCD_write_string(10,0," ");
		}

		peri_=peri*1000000;
		peri1=peri_/1000;peri2=peri_%1000;
		if(peri1<10)
		{
			LCD_write_int(2,1,peri1);
			LCD_write_char(3,1,'.');
			LCD_write_3xs(4,1,peri2);
			LCD_write_char(7,1,'m');
			LCD_write_string(8,1,"   ");
		}
		else if(peri1<100)
		{
			LCD_write_int(2,1,peri1);
			LCD_write_char(4,1,'.');
			LCD_write_3xs(5,1,peri2);
			LCD_write_char(8,1,'m');
			LCD_write_string(9,0," ");
			LCD_write_string(10,1,"  ");
		}
		else
		{
			LCD_write_int(2,1,peri1);
			LCD_write_char(5,1,'.');
			LCD_write_3xs(6,1,peri2);
			LCD_write_char(9,1,'m');
			LCD_write_string(11,1," ");
		}		
	}
		
	else	
	{
		frq_=frq;
		frq1=frq_/1000;frq2=frq_%1000;

		if(frq1<10)
		{
			LCD_write_int(2,0,frq1);
			LCD_write_char(3,0,'.');
			LCD_write_3xs(4,0,frq2);
			LCD_write_string(7,0,"k");
			LCD_write_string(8,0,"    ");
		}
		else if(frq1<100)
		{
			LCD_write_int(2,0,frq1);
			LCD_write_char(4,0,'.');
			LCD_write_3xs(5,0,frq2);
			LCD_write_string(8,0,"k");
			LCD_write_string(9,0,"   ");
		}
		else if(frq1<1000)
		{
			LCD_write_int(2,0,frq1);
			LCD_write_char(5,0,'.');
			LCD_write_3xs(6,0,frq2);
			LCD_write_string(9,0,"k");
			LCD_write_string(10,0,"  ");
		}
		else
		{
			LCD_write_int(2,0,frq1);
			LCD_write_char(6,0,'.');
			LCD_write_3xs(7,0,frq2);
			LCD_write_string(10,0,"k");
			LCD_write_string(11,0," ");
		}
		
		peri_=peri*100000000;
		peri1=peri_/100;peri2=peri_%100;

		if(peri1==0) 
			{
				LCD_write_char(2,1,'0');
				LCD_write_char(3,1,'.');
				LCD_write_2xs(4,1,peri2);
				LCD_write_char(6,1,'u');
				LCD_write_string(7,1,"     ");
			}
		else if(peri1<10)
		{	
			LCD_write_int(2,1,peri1);
			LCD_write_char(3,1,'.');
			LCD_write_2xs(4,1,peri2);
			LCD_write_char(6,1,'u');
			LCD_write_string(7,1,"     ");
		}
		else if(peri1<100)
		{
			LCD_write_int(2,1,peri1);
			LCD_write_char(4,1,'.');
			LCD_write_2xs(5,1,peri2);
			LCD_write_char(7,1,'u');
			LCD_write_string(8,1,"    ");
		}
		else
		{
			LCD_write_int(2,1,peri1);
			LCD_write_char(5,1,'.');
			LCD_write_2xs(6,1,peri2);
			LCD_write_char(8,1,'u');
			LCD_write_string(9,1,"   ");
		}
	}
	
		pha_=pha*100;
		pha1=pha_/100;pha2=(pha_%100);
		if(pha>360)pha1=pha_-360;
		if(pha1<10)		LCD_write_int(12,1,pha1);
		if(pha1<100)	LCD_write_int(11,1,pha1);
		else 			LCD_write_int(10,1,pha1);
		LCD_write_char(13,1,'.');
		LCD_write_2xs(14,1,pha2);
			   
}

main()
{
LCD_init();
LCD_write_string(4,0,"WAIT...");	
delay_ms(1000);
//是对采样值清零			  

while(1)
	{
		LCD_init();
		LCD_write_string(1,0,str);
		delay_ms(200);
		freq_1();
		LCD_init();				
		LCD_write_int(1,0,freq);
		LCD_write_int(1,1,ave);
		delay_ms(400);
		pha_1();

		LCD_init();
		LCD_write_int(1,0,cnt2);
		LCD_write_int(1,1,cnt1);
		delay_ms(2000);
		pha=(360*cnt1)/cnt2;
		if(flag==1) frq=(1000000*per)/cnt2;	 
		else 	    frq=(1000000*per)/256*cnt2; 
		peri=1/frq;	
																					   
		LCD_init();
		LCD_dis();
		delay_ms(1000);							
								
	}
}																	

⌨️ 快捷键说明

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