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

📄 fpj5.c

📁 一个用到ZLG7289的实际项目
💻 C
字号:
//程序做了较大改动
//完成初始化:读取所有参数ABCDEF数据,并判断有效,无效修改。最终显示参数A2500.0
//ok
//除数据输入外ok
//除脉冲输出外OK
//除看门狗OK
#include "ZLG7289.h"  
#include "X5045.h"
#include	<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
	
#define FH 		10
#define DP 		11
#define CLR 	12
#define ENT 	13
#define STOP	14
#define RUN 	15
#define OFF		15
#define LOFF	1
#define LON		0
#define CON_DAT1	60.0
#define CON_DAT2	1E9

//端口定义
sbit TOUT=P1^0;/*脉冲输出*/
sbit LA=P3^7;
sbit LB=P3^6;
sbit LC=P3^5;
sbit LD=P3^4;
sbit LE=P3^3;
sbit LF=P2^3;
sbit LG=P2^2;
sbit LRUN=P2^1;
sbit LSTOP=P2^0;
//*******************************************
uchar 	k; 
uchar 	k_new,k_old;
bit			dpend_b;
bit			f_key;  
uchar		k_cnt;//=0表示第一位按键值
uchar		dp_cnt;
uchar		dat[6]={0,0,0,0,0,0};
bit			dp_b;	//表示有小数点
bit 		fh_b;//表示有负号
bit			out_b;
bit			f_10ms;
bit			f_20ms;
uchar		cnt_20ms;
bit			f_100ms;
uchar		cnt_100ms;
uchar		ent_state;//回车状态
uchar		xstate;//总状态
float 	dat_a;
float 	dat_b;
float 	dat_c;
float 	dat_d;
float 	dat_e;
float 	dat_f;
float		result;
ulong 	tout_cnt;//输出时间计数器(0.1S减1,减到0脉冲输完)
//*******************************************
void	init_dat(void);//读取所有参数ABCDEF数据,并判断有效,无效修改。
float calc(void);
void	set_off(void);
void	stor_dat(uchar 	addr);
void	stor1_dat(uchar addr,float temp1);//计算存储
float	read_dat(uchar	addr);
void	disp_out(void);	//根据dat[0-5]内容显示
void	dispg_out(void);//根据dat[0-5]内容显示 正数 没有符号位 
void	calcg(void);
void 	main_init(void);//主程序初始化
void	time_mainloop(void);//时间处理
void	keypd_mainloop(void);//按键判断20ms一次
void	keycl_mainloop(void);//有键值处理
void	tout_mainloop(void);//脉冲输出处理
//*******************************************
void main() 
{  	
	main_init();
	init_dat();
	disp_out();	//输出A参数显示
	ent_state=0;LA=0;//在输入A参数状态	
	k_cnt=0;//无键
	fh_b=0;dp_b=0;//无负号,无小数点
	k_old=ENT;//上次是回车
	xstate=0;
	TR1=1;EA=1;
	while(1)
	{ 
		time_mainloop();
		keypd_mainloop();
		keycl_mainloop();
		tout_mainloop();
	}
} 

//**************************
void	keycl_mainloop(void)//有键值处理
{
//xstate=0 检验态
//xstate=1 输入态
//xstate=2 运行态
//xstate=3 停止态	
	float	temp;
	uchar	datok_b;
	if(!f_key)return;
	f_key=0;
	switch(xstate)
	{
			case 0://验证态, 只响应ENT RUN CLR
				switch(k_new)
				{
					case ENT://状态不变,读取下一个参数,并更新显示
							switch(ent_state)
							{
								case 0:dat_b=read_dat(0x10);disp_out();	LA=1;LB=0;ent_state=1;break;
								case 1:dat_c=read_dat(0x20);disp_out();	LB=1;LC=0;ent_state=2;break;
								case 2:dat_d=read_dat(0x30);disp_out();	LC=1;LD=0;ent_state=3;break;														
								case 3:dat_e=read_dat(0x40);disp_out();	LD=1;LE=0;ent_state=4;break;
								case 4:dat_f=read_dat(0x50);disp_out();	LE=1;LF=0;ent_state=5;break;
								case 5:dat_a=read_dat(0x00);disp_out();	LF=1;LA=0;ent_state=0;break;
							}
							break;
					case CLR://清除显示,并准备输入数据,更改参数
							set_off();k_cnt=0;fh_b=0;dp_b=0;dat[0]=0;dat[1]=0;dat[2]=0;dat[3]=0;dat[4]=0;dat[5]=0;
							xstate=1;
							break;
					case RUN://根据ABCDEF参数进行计算,开始运行
							calcg();dispg_out();//正数 一位小数 无符号位 最大(18760.0)							
							LA=1;LB=1;LC=1;LD=1;LE=1;LF=1;LSTOP=1;
							LG=0;LRUN=0;
							xstate=2;
							tout_cnt=result*10;TOUT=0;out_b=1;cnt_20ms=2;cnt_100ms=5;
							break;						
					default://其它键不响应,直接退出
							break;
				}	
				break;
			case 1://输入态 只响应0-9 负号 dp ENT CLR
				switch(k_new)//改为只能有一位小数
				{
					case 0:
						
						if(dp_b)//只能有一位小数
						{	
							if(dpend_b==0) break;
							dpend_b=0;
						}
						if((k_cnt==1)&&(dat[k_cnt-1]==0)&&(dp_b==0))break; 
						if(k_cnt==6)break;//123456
						if((fh_b)&&(k_cnt==5))break;//-12345
						//0.00000和-0.0000格式不对!
						if((k_cnt==5)&&(dat[0]==0)&&(dat[1]==0)&&(dat[2]==0)&&(dat[3]==0)&&(dat[4]==0))break;
						if(((fh_b)&&(k_cnt==4))&&(dat[0]==0)&&(dat[1]==0)&&(dat[2]==0)&&(dat[3]==0))break;
						//0.0 0.00应该正确输入!
						//01--1	!
						dat[k_cnt]=k_new;ZLG7289_SHL(); ZLG7289_Download(0,5,0,k_new);
						k_cnt++;
						break;
					case 1:
					case 2:
					case 3:
					case 4:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						if(dp_b)//只能有一位小数
						{	
							if(dpend_b==0) break;
							dpend_b=0;
						}
						if(k_cnt==6)break;//123456
						if((fh_b)&&(k_cnt==5))break;//-12345
						if((k_cnt==1)&&(dat[0]==0)&&(dp_b==0))
						{
							dat[k_cnt-1]=k_new;ZLG7289_Download(0,5,0,k_new);
						}
						else
						{
							dat[k_cnt]=k_new;ZLG7289_SHL(); ZLG7289_Download(0,5,0,k_new);
							k_cnt++;
						}					
						break;
					case FH:
						if(k_cnt>0)break;//负号只能是第一位 k_cnt=0
						fh_b=!fh_b;
						if(fh_b){ZLG7289_Download(0,5,0,FH);}
						else{ZLG7289_Download(0,5,0,OFF);}					
						break;
					case DP:
						if(k_cnt==0)break;// . 和 -. 不存在
						if((dp_b==1)&&(dp_cnt!=k_cnt))break;//dp唯一
						dp_b=!dp_b;
						if(dp_b){ZLG7289_Download(0,5,1,dat[k_cnt-1]);dp_cnt=k_cnt;dpend_b=1;}
						else{ZLG7289_Download(0,5,0,dat[k_cnt-1]);}						
						break;
					case CLR:
						set_off();k_cnt=0;fh_b=0;dp_b=0;dat[0]=0;dat[0]=0;dat[1]=0;dat[2]=0;dat[3]=0;dat[4]=0;
						break;	
					case ENT://对输入数据进行验证,并进入下一个数据验证状态
						temp=calc();
						switch(ent_state)
						{
							case 0:
								if((temp<=2500)&&(temp>=0.1))		
								{dat_a=temp;stor1_dat(0x00,dat_a);datok_b=1;}
								break;
							case 1:
								if((temp<=2500)&&(temp>=0.1))		
								{dat_b=temp;stor1_dat(0x10,dat_b);datok_b=1;}
								break;
							case 2:
								if((temp<=50)&&(temp>=0.1))			
								{dat_c=temp;stor1_dat(0x20,dat_c);datok_b=1;}
								break;
							case 3:
								if((temp<=100)&&(temp>=0.1))			
								{dat_d=temp;stor1_dat(0x30,dat_d);datok_b=1;}
								break;
							case 4:
								if((temp<=50)&&(temp>=0.1))		 	
								{dat_e=temp;stor1_dat(0x40,dat_e);datok_b=1;}
								break;
							case 5:
								if((temp>=(-10))&&(temp<=10))
								{dat_f=temp;stor1_dat(0x50,dat_f);datok_b=1;}
								break;
							default:break;
						}
						if(datok_b)
						{
							f_key=1;k_new=ENT;f_20ms=0;xstate=0;datok_b=0;
						}
						else
						{
							set_off();k_cnt=0;fh_b=0;dp_b=0;dat[5]=0;dat[0]=0;dat[1]=0;dat[2]=0;dat[3]=0;dat[4]=0;
						}
						break;
					default:
						break;
				}
				break;
			case 2://运行态---只响应	STOP
				switch(k_new)
				{
						case STOP:TOUT=1;out_b=0;xstate=3;LRUN=LOFF;LG=LON;LSTOP=LON;//停止后,显示不变
									break;
						default:
									break;	
				}
				break;
			case 3://停止态--只响应 RUN ENT
				switch(k_new)
				{
						case RUN:xstate=2;LRUN=LON;LG=LON;LSTOP=LOFF;tout_cnt=result*10;TOUT=0;out_b=1;cnt_20ms=2;cnt_100ms=5;
								break;
						case ENT:xstate=0;ent_state=5;f_key=1;k_new=ENT;f_20ms=0;//重新执行下验证A
									LRUN=LOFF;LG=LOFF;LSTOP=LOFF;
									break;									
						default:
									break;	
				}				
				break;
			default:
				break;		
	}
}
//**************************根据参数进行计算,并转换到dat[0--5]
void	calcg(void)
{
ulong	temp;
			result=dat_a*dat_b*dat_c*dat_d*CON_DAT1/(dat_e*CON_DAT2)+dat_f;
			//结果最大18760
			if(result>18760) result=18760;
			if(result<0)		result=0;
			temp=result*10;//将小数位变为整数
			dat[0]=temp/100000;	temp=temp%100000;
			dat[1]=temp/10000;	temp=temp%10000;
			dat[2]=temp/1000;		temp=temp%1000;
			dat[3]=temp/100;		temp=temp%100;
			dat[4]=temp/10;			temp=temp%10;
			dat[5]=temp;
	
}
//**************************
void	keypd_mainloop(void)//按键判断20ms一次
{
	if(!f_20ms) return;
	f_20ms=0;
	if ( ZLG7289_pinINT == 0 )    //有键按下 
	{  
		//读  
		k = ZLG7289_Key(); 
		while (!ZLG7289_pinINT ); 	//等待按键抬起 	
		switch(k)
		{
			case  1:	k_new=0;break;//0
			case 11:	k_new=1;break;//1
			case 10:	k_new=2;break;//2
			case  9:	k_new=3;break;//3
			case  8:	k_new=4;break;//4
			case 15:	k_new=5;break;//5
			case 14:	k_new=6;break;//6
			case 13:	k_new=7;break;//7
			case 12:	k_new=8;break;//8
			case  2:	k_new=9;break;//9
			case  0:	k_new=10;break;//+-							
			case  3:	k_new=11;break;//dp
			case  7:	k_new=12;break;//CLR
			case  4:	k_new=13;break;//ENT				
			case  5:	k_new=14;break;//STOP
			case  6:	k_new=15;break;//RUN				
			default:	break;
		}	
		f_key=1;
	}
}
//**************************
void	tout_mainloop(void)//脉冲输出处理
{
	if((f_100ms)&&(out_b))
	{
		f_100ms=0;
		if(--tout_cnt==0)
		{
			TOUT=1;out_b=0;	
		}	
	}
}
//**************************
void	set_off(void)
{
	ZLG7289_Download(0,0,0,15);
	ZLG7289_Download(0,1,0,15);
	ZLG7289_Download(0,2,0,15);
	ZLG7289_Download(0,3,0,15);
	ZLG7289_Download(0,4,0,15);
	ZLG7289_Download(0,5,0,15);
}

//******************************************		
void	disp_out(void)	//根据dat[0-5]内容显示
{
	uchar	i;
	//显示修正
	//正数		如果有非0数据,退出for循环
	//正数  15 0 0,0 0 1(0.1)	-->15 15 15 15 0 1
	//      15 0 1 0 0 1(100.1)-->15 15 1  0  0 1
		
	//负数	如果有非0数据,将前一个数据置符号位,退出for循环	
	//负数  10 0 0,0 0 1(-0.1)	-->15 15 15 10 0 1
	//      10 0 1 0 0 1(-100.1)-->15 10 1  0  0 1
	for(i=1;i<5;i++)
	{
		if(dat[i]!=0) 
		{
			if(dat[0]==10){dat[0]=15;dat[i-1]=10;}//负数				
			break;
		}
		if(dat[i]==0){dat[i]=15;}
	}	
	if(dat[4]==15)dat[4]=0;
	if(dat[0]==10){dat[0]=15;dat[3]=10;}//补丁---仅在"-0.x时有效"
	//输出显示
	for(i=0;i<6;i++)
	{
		if(i==4){ZLG7289_Download(0,i,1,dat[i]);}	
		else{ZLG7289_Download(0,i,0,dat[i]);}
	}	
}		
//************************************************
void	dispg_out(void)	//根据dat[0-5]内容显示 正数 没有符号位 
{
	uchar	i;
	for(i=0;i<4;i++)
	{
		if(dat[i]!=0) {break;}
		if(dat[i]==0){dat[i]=15;}
	}	
	//输出显示
	for(i=0;i<6;i++)
	{
		if(i==4){ZLG7289_Download(0,i,1,dat[i]);}	
		else{ZLG7289_Download(0,i,0,dat[i]);}
	}	
}		
//******************************************
//******************************************
//存储时,只按数据存储,第一位是符号位,可能值10,15,其它全是0-9数据
void	stor_dat(uchar 	addr)
{
	X5045WriteByte(addr++,dat[0]);X5045WriteByte(addr++,dat[1]);X5045WriteByte(addr++,dat[2]);
	X5045WriteByte(addr++,dat[3]);X5045WriteByte(addr++,dat[4]);X5045WriteByte(addr++,dat[5]);	
}

void	stor1_dat(uchar addr,float temp1)
{
	ulong temp2;
	uchar	temp[6];
	//根据数据进行计算并存储
	if(fh_b==1)
	{
		temp[0]=10;temp1=temp1*(-1.0);//转为正数
	}
	else 
	{
		temp[0]=15;
	}
	X5045WriteByte(addr++,temp[0]);//存储符号位
	temp2=temp1*10;
	temp[1]=temp2/10000;temp2=temp2%10000;  //12345
	temp[2]=temp2/1000;temp2=temp2%1000;  //2345
	temp[3]=temp2/100;temp2=temp2%100;  //345
	temp[4]=temp2/10;temp2=temp2%10;  //45
	temp[5]=temp2;											//5
	X5045WriteByte(addr++,temp[1]);X5045WriteByte(addr++,temp[2]);
	X5045WriteByte(addr++,temp[3]);X5045WriteByte(addr++,temp[4]);X5045WriteByte(addr++,temp[5]);		
}
//******************************************
//功能:完成读取数据,并转化为浮点数
//dat0分别代表符号位 dat1234代表数据位整数 dat5代表小数位
//可能值 -2500.0---> 10 2 5 0 0 0
//可能值 2500---> 15 2 5 0 0 0
float	read_dat(uchar	addr)
{	
	float temp1;
	ulong temp2;
	dat[0]=X5045ReadByte(addr);
	if((dat[0]!=15)&&(dat[0]!=10)){dat[0]=15;X5045WriteByte(addr,dat[0]);}//符号位不正确,则取正数并写入
	addr++;
	dat[1]=X5045ReadByte(addr++);	dat[2]=X5045ReadByte(addr++);dat[3]=X5045ReadByte(addr++);	dat[4]=X5045ReadByte(addr++);	dat[5]=X5045ReadByte(addr++);

	temp2=dat[1]*1000+dat[2]*100+dat[3]*10+dat[4];
	temp1=temp2+dat[5]*0.1;
	if(dat[0]==10){temp1=temp1*(-1);}
	return temp1;
}
//******************************************
void main_init(void)
{
	TOUT=1;//默认
	TMOD = 0x01;   
	Delay(30);    //延时300ms,等待ZLG7289复位完毕 
	X5045Init();	
	//led on
	P2&=0xf0;//B1111_0000;
	P3&=0x07;//B0000_0111;
	ZLG7289_Init(4);  //调用ZLG7289的初始化函数 
	Delay(100); 	
	ZLG7289_Reset(); 
	//led off
	P2|=0x0f;//B1111_0000;
	P3|=0xf8;//B0000_0111;	
	TMOD=0x11;
	TH1=0xD8;
	TL1=0xF0;//10mS时间初值
	ET1=1;
	cnt_20ms=2;
	cnt_100ms=5;
	
}
//*******************************************
void	init_dat(void)//读取所有参数ABCDEF数据,并判断有效,无效修改。
{
	dat_b=read_dat(0x10);//读取参数B在X5045中的值
	if((dat_b>2500)||(dat_b<=0))//B正数,MAX=2500
	{
		dat_b=2500;
		dat[0]=15;dat[1]=2;dat[2]=5;dat[3]=0;dat[4]=0;dat[5]=0;//2500
		stor_dat(0x10);
	}
	dat_c=read_dat(0x20);//读取参数C在X5045中的值
	if((dat_c>50)||(dat_c<=0))//C正数,MAX=50
	{
		dat_c=50;
		dat[0]=15;dat[1]=0;dat[2]=0;dat[3]=5;dat[4]=0;dat[5]=0;//50
		stor_dat(0x20);
	}	
	dat_d=read_dat(0x30);//读取参数D在X5045中的值
	if((dat_d>100)||(dat_d<=0))//D正数,MAX=100
	{
		dat_d=100;
		dat[0]=15;dat[1]=0;dat[2]=1;dat[3]=0;dat[4]=0;dat[5]=0;//100
		stor_dat(0x30);
	}	
	dat_e=read_dat(0x40);//读取参数E在X5045中的值
	if((dat_e>50)||(dat_e<=0))//E正数,MAX=50
	{
		dat_e=50;
		dat[0]=15;dat[1]=0;dat[2]=0;dat[3]=5;dat[4]=0;dat[5]=0;//50
		stor_dat(0x40);
	}	
	dat_f=read_dat(0x50);//读取参数F在X5045中的值
	if((dat_f>=10)||(dat_f<=-10))//-10<F<10
	{
		dat_f=0;
		dat[0]=15;dat[1]=0;dat[2]=0;dat[3]=0;dat[4]=0;dat[5]=0;//0
		stor_dat(0x50);
	}	
			dat_a=read_dat(0x00);//读取参数A在X5045中的值
	if((dat_a>2500)||(dat_a<=0))//a正数,MAX=2500
	{
		dat_a=2500;
		dat[0]=15;dat[1]=2;dat[2]=5;dat[3]=0;dat[4]=0;dat[5]=0;//2500
		stor_dat(0x00);
	}
}
void 	pit1(void) interrupt 3 
{
	TH1=0xD8;
	TL1=0xF0;//10mS时间初值
	f_10ms=1;
}
void	time_mainloop(void)//时间处理
{
	if(!f_10ms)return;
	f_10ms=0;
	if(--cnt_20ms==0)
	{
		cnt_20ms=2;f_20ms=1;
		if(--cnt_100ms==0)
		{
			cnt_100ms=5;f_100ms=1;	
		}			
	}
}
//*********************************************
//根据按键结果进行处理得到数据
float calc(void)
{
	uchar i;
	ulong temp1;
	float temp2;
	temp1=dat[0];
	for(i=1;i<k_cnt;i++)
	{
		temp1=temp1*10+dat[i];	
	}
	temp2=temp1;
	if(dp_b)
	{
		for(i=0;i<(k_cnt-dp_cnt);i++)
		{temp2=temp2/10;}	
	}
	if(fh_b){temp2=temp2*(-1.0);}
	return (temp2);	
}

⌨️ 快捷键说明

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