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

📄 plj.c

📁 用2051制作的测试1HZ到1M的频率测试C程序
💻 C
字号:
#include <reg52.h> // SFR声明
#include <intrins.h>
#include <math.h>
#define ulong unsigned long
#define	 uchar unsigned char
#define uint unsigned int
#define udouble unsigned double

#define 	SYSCLK 	24000 // 系统时钟频率kHz
#define  	STACK_START 0x60//堆栈底部
#define		STACK_END 0xAF//堆栈顶部
#define		disp_bit_hide	0x60 //显示位消隐

#define 	ts_2ms (0xffff-7962/2)//2ms		 24MHz*2  0xf073
#define 	ts_025s 124//0.25S=2mS*124
#define 	ts_05s 249//0.5S=2mS*249
#define 	ts_1s 501//1S=2mS*500
uint code JN[5]={10000,1000,100,10,1};

uint  time_ref;
uint  time_refs=ts_025s;
uchar	xn=2,xnb=2;	  //xnb=计数时间的倒数
uchar led;
uchar led_bit;    

uint freq_alu_word=0;  //频率计数值 
uint freq_alu_hb;
uint freq_alu_lb;

idata uchar freqh_word=0;		// 频率值
idata ulong flowc_word=0;		// 中间比较值
idata uchar dispbuf_bcd[5];		//显示缓冲区放5个值
idata uchar disp_bcd[5];		//显示缓冲地址

sbit cs245=P3^7;				//位选74HC245,“0”有效
bit  start=0;					//频率计数开始标志
bit  busy=0;					//在一个时基内,频率计数完,频率计算开始标志
uchar code tabchar[64]={

	0xb7,0x12,0x67,0x76,0xd2,0xf4,0xf5,0x16,   //0~7,+00H
	0xf7,0xf6,0xd7,0xf1,0xa5,0x73,0xe5,0xc5,   //8~F,+08H 	
											   //数码显示:CHR 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
	0xbf,0x1a,0x6f,0x7e,0xda,0xfc,0xfd,0x1e,   //0.~7.  +10h
	0xff,0xfe,0xdf,0xf9,0xad,0x7b,0xed,0xcd,   //8.~f.  +18h 	
											   //数码显示带点:CHR 0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,A.,B.,C.,D.,E.,F.
	0x00,0x50,0x12,0x85,0x41,0x71,0xc7,0x97,   // 灭 ,'-',-1 ,'R','r' ,'o','P','N','L'+20h
	0xa1,0x51,0xd3,0x00,0x00,0x00,0x00,0x00,   //L,n,H +28h
											   //字符显示:  灭 ,'-',-1 ,'R','r' ,'o','P','N','L','n','H'
	0x08,0x58,0x1a,0x8d,0x49,0x79,0xcf,0x9f,   // 灭. ,'-.',-1. ,'R.','r.' ,'o.','P.','N.'+30h
	0xa9,0x59,0xdb,0x00,0x00,0x00,0x00,0x00	   //L.,n.H.+38h
											};//字符带点:  灭. ,'-.',-1. ,'R.','r.' ,'o.','P.','N.','L.','n.','H.
void disp_scan()
{	idata uchar buf;
	static uint k=0;
	k++;
	if(k==500)
		{k=0;	P2=~P2;}
	//led=4;		 		//5个数码管
	//led_bit=1;			//LED位控制位,最低位选中,
	cs245=0;
	P3=disp_bit_hide;	//显示位消隐
	_nop_();
	P3=0x7f&led_bit;		//开第一个数码管
	_nop_();
	P1=0x00;
	buf=dispbuf_bcd[led];
	P1=tabchar[buf];
	led--;				 //扫描位计数,更新下一个数码管缓冲区里显示数值
	led_bit=led_bit<<1;	 //数码管位控移位,16进制数为,0x01,0x02,0x04,0x08,0x10,再回到0x01
	//if((led_bit==0x10)|(led==0))
	 //{led_bit=1;led=4;}	////一次五位显示循环完毕,重新赋扫描初值
	 if(led>4|led_bit>0x10 |led_bit==0x00)
		{led=4;led_bit=1;}	//一次五位显示循环完毕,重新赋扫描初值
}
void disp_start()	  	//显示(0.--9.)
{	uchar i;
	for(i=0;i<5;i++)
	{ dispbuf_bcd[i]=i+16;}//显示缓冲数据区里的值从0---4
	//delay(500);
	//for(j=5;j<10;j++)
	//{dispbuf_bcd[j-5]=j+16;}

}
void freq_alu()	//频率计算
{	ulong freq_reg;	// 最终频率计算值 32位数
	freq_reg=freq_alu_hb;	//存高16位
	freq_reg=freq_reg<<16;	//移动16次 到32位的高16值
	freq_reg=freq_reg+freq_alu_lb;	//高16+低16位
	freq_reg=freq_reg<<xnb;//计数值freq_reg/计数时间	(xnb=计数时间的倒数)
	flowc_word=freq_reg;   //计算出来的频率值
	if(xn!=xnb){xnb=xn;}												 
}
void freq_bcd_n(ulong N)
{	ulong M;
	uchar i,j,dot;
	//N=flowc_word;
	dot=3;	//小数点默认在第3位(0000.0)K
	if(N<100000)	
		{ dot=1;	//小数点第一位
			time_refs=ts_1s; //频率低于10,时基改变为1S
			xnb=0;}
	else if (N<1000000)
		{		dot=2; //小数点定位在位2(000.00kHz)
				time_refs=ts_05s;	//默认时基
				xn=1;
				M=N%10;
				N=N/10;
				if(M>4){N++;}	//末位四舍五入
	
		
		 }
	else 	//if(N<10000000)
		{		dot=3;				//小数点定位在位3(0000.0kHz)
				time_refs=ts_025s;	//默认时基
				xn=2;
				M=N%100;
				N=N/100;
				if(M>49){N++;}		//末位四舍五入
		}
	 //BCD码转化成5位十进制数,最高位从disp_bcd[0]开始
	 for(i=0;i<=4;i++)
	 	{disp_bcd[i]=N/JN[i];
			N=N%JN[i];
		}
		disp_bcd[dot]=disp_bcd[dot]+0x10;//小数点位置 加16

	 if(dot=1&(disp_bcd[0]==0))	//如果小数点在第一位并且第一个数码管的值为0
	 	{disp_bcd[0]=0x20;}		//消隐

	 for(j=0;j<5;j++)
		{dispbuf_bcd[j]=disp_bcd[j];}

}
void delay(uint n)
{	uint i;
	uchar j;
	for(i=0;i<n;i++)
		for(j=0;j<255;j++)
		{;;}
}
void freq_start()
{	//cs245=0;
	EX0=0;//外中断0禁止
	ET0=1;
	ET1=1;
	TR1=0;//停止计数
	TF1=0;//清溢出标志
	TH1=0;//清计数初值
	TL1=0;
	TH0=0xf0;		//2毫秒定时初值
	TL0=0x60;
	freq_alu_word=0;
	time_ref=time_refs;
	TR0=1;
	TR1=1;
	PT0=1;
	start=1;

}

void Timer0() interrupt 1 using 1
{	
	TF0=0;				//中断溢出标志清0
	TH0=0xf0;		//2毫秒定时初值	
	TL0=0x60;
	if(start)		//如果频率计数开始
			{if(time_ref--==0)
				{freq_alu_lb=TH1*256+TL1;
				freq_alu_hb=freq_alu_word;}
				busy=1;
				time_ref=time_refs;
				freq_start();
			}
	disp_scan();

}



void Timer1()interrupt 3 using 1
{freq_alu_word++;}	

void timer0_count1_init()
{	TMOD=0x51;		//T0用来定时 T1用来计数
	TH0=0xf0;		//2毫秒定时初值
	TL0=0x60;
	TH1=0;			//计数器1初值
	TL1=0;
	TR0=1;
	TF0=0;
	IT0=0;	//下降沿有效
	PT0=1;	//中断0优先
	EA=0;
} 


void main()
{	led=4;
	led_bit=1;
	TMOD=0x51;		//T0用来定时 T1用来计数
	TH0=0xf0;		//2毫秒定时初值
	TL0=0x60;
	TH1=0;			//计数器1初值
	TL1=0;
	TR0=1;
	ET0=1;
	PT0=1;
	timer0_count1_init(); //定时/计数初始化
	EA=1;
	disp_start();	//开始显示(0.-9.)
	delay(1000);	//延迟1S
	freq_start();	//频率计数开始
	for(;;)
		{if(busy)
			{freq_alu();	 //频率计算
			 freq_bcd_n(flowc_word);//计算的频率值转化成10进制数 }
			 busy=0;	
		 }
		 freq_start();
}

	 







}

⌨️ 快捷键说明

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