我要做一个由按键和数码管构成的人机交互界面。下面是该界面的按键说明:1、进入参数设定菜单
a、长按“设定”键,直至显示“PASS”,表示要输入密码;
b、用“◄”键移动闪烁数字,用“▲”键修改闪烁数字,即可输入密码;
c、确认密码输入正确后,按“设定”键确认,即可进入参数设定菜单;
d、进入参数设定菜单后,用“▲”键可以选择菜单;
e、选择好菜单后,按“设定”键可进入该项参数的设置;
f、进入参数的设置后,用“▲”键可以选择参数值;
g、参数值修改完成后,按“设定”键确认修改,按“取消”键取消修改;
h、当各项参数修改完成后,按“取消”键退出参数设定菜单,即完成设置。
下面的程序是基于状态机的。我仅仅做到了把该显示的按照要求显示出来,但是如上面的说明,有些是给各个通道设置系数,有些是开启或者关闭某个通道。但是我不知道怎样告诉单片机,在我按下这个键时,就表明我开启了这个通道,设置了某个系数等等?总的来说我没有完成人机交互,这该怎么做?
问题2:这里面密码设置时需要按键来设置密码,我仅仅是一次显示出要设置的密码,做不到按一下,数字加1,设置完一位,在设置下一位,直到5位密码设置完成,这该怎么做?整个程序凡是需要按键动态设置的,我都没有做到。
问题3:下面的程序结构实在是太机械了,有没有更好的结构来实现?
#include<reg51.h>
#include<intrins.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar num_key;
static uchar state=1;
sbit scl=P1^6;
sbit sda=P1^7;
/**********************按键检测******************************/
void KeyScan()
{
uchar temp=0;
static uchar temp_code=0;
static uchar num_check=0;
static bit key_flag=0;
temp=P1&0x3f;
if(temp!=0x3f)
{
num_check++;
if(num_check==10)
{
key_flag=1;
temp_code=temp;
}
}
else
{
num_check=0;
if(key_flag==1)
{
key_flag=0;
switch(temp_code)
{
case 0x3e:num_key=1;break;
case 0x3d:num_key=2;break;
case 0x3b:num_key=3;break;
case 0x37:num_key=4;break;
case 0x2f:num_key=5;break;
case 0x1f:num_key=6;break;
default:break;
}
}
}
}
/********************按键检测******************************/
/*******************cs5817的驱动***************************/
void start()
{
sda=1;
_nop_();
scl=1;
_nop_();
sda=0;
_nop_();
}
void stop(void)
{
sda=0;
_nop_();
scl=1;
_nop_();
sda=1;
_nop_();
}
void ack(void)
{
uchar i;
scl=1;
_nop_();
while((sda==0)&&(i<250))
i++;
scl=0;
_nop_();
}
void write_onebyte(uchar date)
{
uchar i,temp;
temp=date;
scl=0;
_nop_();
for(i=0;i<8;i++)
{
temp<<=1;
sda=CY;
_nop_();
scl=1;
_nop_();
scl=0;
_nop_();
}
sda=1;
_nop_();
}
/*void load_date(uchar ad,uchar dat)
{
start();
write_onebyte(ad);
ack();
write_onebyte(dat);
ack();
stop();
}*/
void start_disp()
{
start();
write_onebyte(0x48) ;
ack();
write_onebyte(0x01) ;
ack();
stop();
}
void disp(uchar num_1,uchar num_2,uchar num_3,uchar num_4,uchar num_5,
uchar num_6,uchar num_7,uchar num_8,uchar num_9,uchar num_10)
{
start();
write_onebyte(0x60);
ack();
write_onebyte(num_1);
ack();
write_onebyte(num_2);
ack();
write_onebyte(num_3);
ack();
write_onebyte(num_4);
ack();
write_onebyte(num_5);
ack();
stop();
start();
write_onebyte(0x76);
ack();
write_onebyte(num_6);
ack();
write_onebyte(num_7);
ack();
write_onebyte(num_8);
ack();
write_onebyte(num_9);
ack();
write_onebyte(num_10);
ack();
stop();
start_disp();
}
/************************cs5817的驱动**********************/
/***********************按键处理***************************/
void KeyProc()
{
switch(state)
{
case 1://显示总重和限重
{
if(1==num_key)
state=2;
else if(6==num_key)
state=8;
}break;
case 2: { //显示通道1的重量
if(1==num_key)
state=1;
else if(5==num_key)
state=3;
else if(2==num_key)
state=7;
}break;
case 3: //显示通道2的重量
{
if(1==num_key)
state=1;
else if(5==num_key)
state=4;
else if(2==num_key)
state=2;
}break;
case 4: //显示通道3的重量
{
if(1==num_key)
state=5;
else if(5==num_key)
state=5;
else if(2==num_key)
state=3;
}break;
case 5://显示通道4的重量
{
if(1==num_key)
state=6;
else if(5==num_key)
state=6;
else if(2==num_key)
state=4;
}break;
case 6://显示通道5的重量
{
if(1==num_key)
state=7;
else if(5==num_key)
state=7;
else if(2==num_key)
state=5;
}break;
case 7://显示通道6的重量
{
if(1==num_key)
state=2;
else if(5==num_key)
state=2;
else if(2==num_key)
state=6;
} break;
case 8: //要显示密码
{
if(6==num_key)
state=9;
}break;
case 9: //要显示F0菜单
{
if(6==num_key)
state=10;
else if(5==num_key)
state=16; //F1菜单
else if(2==num_key)
state=30;//最后一个菜单项这里的30是不对的。
}break;
case 10:
{
if(6==num_key)
state=9;
else if(5==num_key)
state=11;
else if(2==num_key)
state=15;
}break;
case 11:
{
if(6==num_key)
state=9;
else if(5==num_key)
state=12;
else if(2==num_key)
state=10;
}break;
case 12:
{
if(6==num_key)
state=9;
else if(5==num_key)
state=13;
else if(2==num_key)
state=11;
}break;
case 13:
{
if(6==num_key)
state=9;
else if(5==num_key)
state=14;
else if(2==num_key)
state=12;
}break;
case 14:
{
if(6==num_key)
state=9;
else if(5==num_key)
state=15;
else if(2==num_key)
state=13;
}break;
case 15:
{
if(6==num_key)
state=9;
else if(5==num_key)
state=10;
else if(2==num_key)
state=14;
}break;
case 16: //要显示F1菜单
{
if(6==num_key)
state=17;
else if(5==num_key)
state=22;//F2菜单
else if(2==num_key)
state=9;//F0菜单
}break;
case 17:
{
if(6==num_key)
state=16;
else if(5==num_key)
state=18;
}break;
case 18:
{
if(6==num_key)
state=16;
else if(5==num_key)
state=19;
}break;
case 19:
{
if(6==num_key)
state=16;
else if(5==num_key)
state=20;
}break;
case 20:
{
if(6==num_key)
state=16;
else if(5==num_key)
state=21;
}break;
case 21:
{
if(6==num_key)
state=16;
else if(5==num_key)
state=17;
}break;
case 22: //要显示F2菜单
{
if(6==num_key)
state=23;
else if(5==num_key)
state=29;//F3菜单;
else if(2==num_key)
state=16;//F1菜单
}break;
case 23: //d=1
{
if(6==num_key)
state=22;
else if(5==num_key)
state=24;
}break;
case 24: //d=2
{
if(6==num_key)
state=22;
else if(5==num_key)
state=25;
} break;
case 25: //d=5
{
if(6==num_key)
state=22;
else if(5==num_key)
state=26;
}break;
case 26: //d=10
{
if(6==num_key)
state=22;
else if(5==num_key)
state=27;
}break;
case 27: //d=20
{
if(6==num_key)
state=22;
else if(5==num_key)
state=28;
} break;
case 28: //d=50
{
if(6==num_key)
state=22;
else if(5==num_key)
state=23;
}break;
case 29: //要显示F3
{
if(6==num_key)
state=30;
else if(5==num_key)
state=37;//F4菜单
else if(2==num_key)
state=22;//F2菜单
}break;
case 30://0.5d
{
if(6==num_key)
state=29;
else if(5==num_key)
state=31;
}break;
case 31://1d
{
if(6==num_key)
state=29;
else if(5==num_key)
state=32;
}break;
case 32: //2d
{
if(6==num_key)
state=29;
else if(5==num_key)
state=33;
}break;
case 33: //5d
{
if(6==num_key)
state=29;
else if(5==num_key)
state=34;
}break;
case 34: //10d
{
if(6==num_key)
state=29;
else if(5==num_key)
state=35;
}break;
case 35: //20d
{
if(6==num_key)
state=29;
else if(5==num_key)
state=36;
}break;
case 36: //50d
{
if(6==num_key)
state=29;
else if(5==num_key)
state=30;
}break;
case 37: //要显示F4菜单
{
if(6==num_key)
state=38;
else if(5==num_key)
state=40; //F5菜单
else if(2==num_key)
state=29; //F3菜单
}break;
case 38://on
{
if(6==num_key)
state=37;
else if(5==num_key)
state=39;
}break;
case 39://off
{
if(6==num_key)
state=37;
else if(5==num_key)
state=38;
}break;
case 40: //F5菜单,设置总重限重。
{
if(6==num_key)
state=41;
else if(5==num_key)
state=42;//F6菜单;
else if(2==num_key)
state=37;//F4菜单
} break;
case 41://直接给出限重。
{
if(6==num_key)
state=40;
}break;
case 42: //F6菜单,要显示单通道的关闭或开启。
{
if(6==num_key)
state=43;
else if(5==num_key)
state=55;//F7菜单设置各个通道系数。
else if(2==num_key)
state=40; //F5菜单
}break;
case 43: //通道1,开
{
if(6==num_key)
state=42;
else if(5==num_key)
state=44;//通道2,开
else if(2==num_key)
state=45;//通道1,关
}break;
case 44: //通道2,开
{
if(6==num_key)
state=42;
else if(5==num_key)
state=46;//通道3,开
else if(2==num_key)
state=47;//通道2,关
}break;
case 45: //通道1,关
{
if(6==num_key)
state=42;
else if(5==num_key)
state=47; //通道2,关
else if(2==num_key)
state=43; //通道1,开
}break;
case 46://通道3,开
{
if(6==num_key)
state=42;
else if(5==num_key)
state=48;//通道4,开
else if(2==num_key)
state=49;//通道3,关
}break;
case 47://通道2,关
{
if(6==num_key)
state=42;
else if(5==num_key)
state=49;//通道3,关
else if(2==num_key)
state=44;//通道2,开
}break;
case 48://通道4,开
{
if(6==num_key)
state=42;
else if(5==num_key)
state=50;//通道5,开
else if(2==num_key)
state=51;//通道4,关
}break;
case 49://通道3,关
{
if(6==num_key)
state=42;
else if(5==num_key)
state=51;//通道4,关
else if(2==num_key)
state=46;//通道3,开
}break;
case 50://通道5,开
{
if(6==num_key)
state=42;
else if(5==num_key)
state=52;//通道6,开
else if(2==num_key)
state=53;//通道5,关
}break;
case 51://通道4,关
{
if(6==num_key)
state=42;
else if(5==num_key)
state=53; //通道5,关
else if(2==num_key)
state=48;//通道4,开
} break;
case 52://通道6,开
{
if(6==num_key)
state=42;
else if(5==num_key)
state=43;//通道1,开
else if(2==num_key)
state=54;//通道6,关
}break;
case 53://通道5,关
{
if(6==num_key)
state=42;
else if(5==num_key)
state=54;//通道6,关
else if(2==num_key)
state=50;//通道5,开
} break;
case 54://通道6,关
{
if(6==num_key)
state=42;
else if(5==num_key)
state=45;//通道1,关
else if(2==num_key)
state=52;//通道6,开
}break;
case 55://要显示F7菜单,设置各个通道的系数。
{
if(6==num_key)
state=56;
else if(5==num_key)
state=68;//F8菜单
else if(2==num_key)
state=42;//F6菜单
}break;
case 56:// 通道1,闪
{
if(6==num_key)
state=57;//设置通道1的系数
else if(5==num_key)
state=58;//通道2,闪
}break;
case 57://通道1设置
{
if(6==num_key)
state=55;
}break;
case 58://通道2,闪
{
if(6==num_key)
state=59;//设置通道2的系数
else if(5==num_key)
state=60;//通道3闪
}break;
case 59://通道2设置
{
if(6==num_key)
state=55;
}break;
case 60://通道3,闪
{
if(6==num_key)
state=61;//设置通道3
else if(5==num_key)
state=62;//通道4,闪
}break;
case 61://通道3设置
{
if(6==num_key)
state=55;
}break;
case 62://通道4,闪
{
if(6==num_key)
state=63;//设置通道4
else if(5==num_key)
state=64;//通道5,闪
}break;
case 63://通道4设置
{
if(6==num_key)
state=55;
}break;
case 64://通道5,闪
{
if(6==num_key)
state=65;//设置通道5
else if(5==num_key)
state=66;//通道6,闪
}break;
case 65://通道5设置
{
if(6==num_key)
state=55;
}break;
case 66://通道6,闪
{
if(6==num_key)
state=67;//设置通道6
else if(5==num_key)
state=56;//通道1,闪
}break;
case 67://通道6,设置
{
if(6==num_key)
state=55;
}break;
case 68://要显示F8菜单
{
if(6==num_key)
state=69;
else if(5==num_key)
state=9;//F0菜单;
else if(2==num_key)
state=55;//F7菜单;
}break;
case 69://no
{
if(6==num_key)
state=68;
else if(5==num_key)
state=70;
}break;
case 70://yes
{
if(6==num_key)
state=68;
else if(5==num_key)
state=69;
}break;
default:break;
}
}
/*****************************按键处理***************************/
void main()
{
while(1)
{
KeyScan();
if(state==1)
disp(0x82,0xee,0xee,0xee,0xee,0,0,0,0x82,0xee);//总重
else if(state==2)
disp(0,0x6c,0xba,0x50,0x82,0,0,0x86,0xee,0xd6); //通道1
else if(state==3)
disp(0,0x6c,0xba,0x50,0x76,0,0,0,0x9a,0xdc); //通道2
else if(state==4)
disp(0,0x6c,0xba,0x50,0xd6,0,0xfc,0x86,0xfe,0x82); //通道3
else if(state==5)
disp(0,0x6c,0xba,0x50,0x9a,0,0,0x76,0xee,0x9a); //通道4
else if(state==6)
disp(0,0x6c,0xba,0x50,0xdc,0,0,0xfc,0xdc,0x82); //通道5
else if(state==7)
disp(0,0x6c,0xba,0x50,0xfc,0,0,0x9e,0xd6,0x86); //通道6
else if(state==8)
disp(0x82,0x76,0xd6,0x9a,0xdc,0,0x3e,0xbe,0xdc,0xdc); //显示密码
else if(state==9)
disp(0,0x70,0xf0,0xf2,0x7c,0x10,0x3c,0xee,0x10,0); //F0菜单
else if(state==10)
disp(0,0,0x10,0xdc,0x82,0,0x6c,0xba,0x50,0x82);//通道1内码
else if(state==11)
disp(0,0,0x10,0xfe,0x76,0,0x6c,0xba,0x50,0x76);//通道2内码
else if(state==12)
disp(0,0x10,0x82,0x82,0xd6,0,0x6c,0xba,0x50,0xd6); //通道3内码
else if(state==13)
disp(0,0,0x10,0xdc,0xee,0,0x6c,0xba,0x50,0x9a);//通道4内码
else if(state==14)
disp(0,0,0x10,0xdc,0xfc,0,0x6c,0xba,0x50,0xdc); //通道5内码
else if(state==15)
disp(0,0,0x10,0xdc,0xd6,0,0x6c,0xba,0x50,0xfc); //通道6内码
else if(state==16)
disp(0,0,0,0xf2,0x3e,0x10,0x3c,0x82,0x10,0);//F1菜单设置小数点位数
else if(state==17)
disp(0,0,0,0,0xef,0x10,0x3c,0x82,0x10,0); //0.
else if(state==18)
disp(0,0,0,0xef,0xee,0x10,0x3c,0x82,0x10,0); //0.0
else if(state==19)
disp(0,0,0xef,0xee,0xee,0x10,0x3c,0x82,0x10,0);//0.00
else if(state==20)
disp(0,0xef,0xee,0xee,0xee,0x10,0x3c,0x82,0x10,0);//0.000
else if(state==21)
disp(0xef,0xee,0xee,0xee,0xee,0x10,0x3c,0x82,0x10,0);//0.0000
else if(state==22)
disp(0,0,0x82,0xb0,0x70,0x10,0x3c,0x76,0x10,0);//F2菜单
else if(state==23)
disp(0,0,0xf2,0x50,0x82,0x10,0x3c,0x76,0x10,0);//d=1
else if(state==24)
disp(0,0,0xf2,0x50,0x76,0x10,0x3c,0x76,0x10,0);//d=2
else if(state==25)
disp(0,0,0xf2,0x50,0xdc,0x10,0x3c,0x76,0x10,0);//d=5
else if(state==26)
disp(0,0xf2,0x50,0x82,0xee,0x10,0x3c,0x76,0x10,0);//d=10
else if(state==27)
disp(0,0xf2,0x50,0x76,0xee,0x10,0x3c,0x76,0x10,0);//d=20
else if(state==28)
disp(0,0xf2,0x50,0xdc,0xee,0x10,0x3c,0x76,0x10,0); //d=50
else if(state==29)
disp(0,0,0xbe,0xdc,0x78,0x10,0x3c,0xd6,0x10,0);//F3
else if(state==30)
disp(0,0,0xef,0xdc,0xf2,0x10,0x3c,0xd6,0x10,0); //0.5d
else if(state==31)
disp(0,0,0,0x82,0xf2,0x10,0x3c,0xd6,0x10,0);//1d
else if(state==32)
disp(0,0,0,0x76,0xf2,0x10,0x3c,0xd6,0x10,0);//2d
else if(state==33)
disp(0,0,0,0xdc,0xf2,0x10,0x3c,0xd6,0x10,0);//5d
else if(state==34)
disp(0,0,0x82,0xee,0xf2,0x10,0x3c,0xd6,0x10,0);//10d
else if(state==35)
disp(0,0,0x76,0xee,0xf2,0x10,0x3c,0xd6,0x10,0);//20d
else if(state==36)
disp(0,0,0xdc,0xee,0xf2,0x10,0x3c,0xd6,0x10,0);//50d
else if(state==37)
disp(0,0x78,0xbe,0x30,0x7c,0x10,0x3c,0x9a,0x10,0);//F4
else if(state==38)
disp(0,0,0,0xf0,0xb0,0x10,0x3c,0x9a,0x10,0);//on
else if(state==39)
disp(0,0,0xf0,0x3c,0x3c,0x10,0x3c,0x9a,0x10,0);//oFF
else if(state==40)
disp(0x80,0xb1,0x6c,0xbe,0x3e,0x10,0x3c,0xdc,0x10,0);//F5;
else if(state==41)
disp(0x82,0xee,0xee,0xee,0xee,0x10,0x3c,0xdc,0x10,0);//总重;
else if(state==42)
disp(0,0,0xbe,0xf2,0xf2,0x10,0x3c,0xfc,0x10,0);//F6
else if(state==43)
disp(0,0,0,0xf0,0xb0,0,0x6c,0xba,0x50,0x82);//通道1,开
else if(state==44)
disp(0,0,0,0xf0,0xb0,0,0x6c,0xba,0x50,0x76);//通道2,开
else if(state==45)
disp(0,0,0xf0,0x3c,0x3c,0,0x6c,0xba,0x50,0x82);//通道1,关
else if(state==46)
disp(0,0,0,0xf0,0xb0,0,0x6c,0xba,0x50,0xd6);//通道3,开
else if(state==47)
disp(0,0,0xf0,0x3c,0x3c,0,0x6c,0xba,0x50,0x76);//通道2,关
else if(state==48)
disp(0,0,0,0xf0,0xb0,0,0x6c,0xba,0x50,0x9a);//通道4,开
else if(state==49)
disp(0,0,0xf0,0x3c,0x3c,0,0x6c,0xba,0x50,0xd6);//通道3,关
else if(state==50)
disp(0,0,0,0xf0,0xb0,0,0x6c,0xba,0x50,0xdc);//通道5,开
else if(state==51)
disp(0,0,0xf0,0x3c,0x3c,0,0x6c,0xba,0x50,0x9a);//通道4,关
else if(state==52)
disp(0,0,0,0xf0,0xb0,0,0x6c,0xba,0x50,0xfc);//通道6,开
else if(state==53)
disp(0,0,0xf0,0x3c,0x3c,0,0x6c,0xba,0x50,0xdc);//通道5,关
else if(state==54)
disp(0,0,0xf0,0x3c,0x3c,0,0x6c,0xba,0x50,0xfc);//通道6,关
else if(state==55)
disp(0x6c,0xf0,0x7c,0x3c,0x3c,0x10,0x3c,0x86,0x10,0);//F7;
else if(state==56)
disp(0,0x6c,0xba,0x50,0x82,0x10,0x3c,0x86,0x10,0);//通道1,闪
else if(state==57)
disp(0xef,0xee,0xee,0x82,0x76,0x10,0x3c,0x86,0x10,0);//通道1设置
else if(state==58)
disp(0,0x6c,0xba,0x50,0x76,0x10,0x3c,0x86,0x10,0); //通道2,闪
else if(state==59)
disp(0xef,0x82,0xee,0xee,0xd6,0x10,0x3c,0x86,0x10,0);//通道2设置
else if(state==60)
disp(0,0x6c,0xba,0x50,0xd6,0x10,0x3c,0x86,0x10,0);//通道3,闪
else if(state==61)
disp(0xef,0xee,0xee,0x9e,0xee,0x10,0x3c,0x86,0x10,0);//通道3设置
else if(state==62)
disp(0,0x6c,0xba,0x50,0x9a,0x10,0x3c,0x86,0x10,0);//通道4,闪
else if(state==63)
disp(0xef,0xee,0xee,0x9e,0xee,0x10,0x3c,0x86,0x10,0); //通道4设置
else if(state==64)
disp(0,0x6c,0xba,0x50,0xdc,0x10,0x3c,0x86,0x10,0); //通道5,闪
else if(state==65)
disp(0xef,0x82,0xee,0xee,0xd6,0x10,0x3c,0x86,0x10,0);//通道5设置
else if(state==66)
disp(0,0x6c,0xba,0x50,0xfc,0x10,0x3c,0x86,0x10,0);//通道6,闪
else if(state==67)
disp(0xef,0xee,0xee,0x9e,0xee,0x10,0x3c,0x86,0x10,0);//通道6,设置
else if(state==68)
disp(0,0x30,0x7c,0xdc,0x78,0x10,0x3c,0xfe,0x10,0);//F8
else if(state==69)
disp(0,0,0,0xb0,0xf0,0x10,0x3c,0xfe,0x10,0);
else if(state==70)
disp(0,0,0xda,0x7c,0xdc,0x10,0x3c,0xfe,0x10,0);
if(num_key!=0)
{
KeyProc();
num_key=0;
}
}
} |