📄 fpj5.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 + -