/**********************************************************************************
程序功能:表决器,模拟三位评委的表决,并做出判断,将结果显示于1602上。
共用到TX-1C学习板上左二列的S6,S7,S10,S11,S14,S15,S18七个按键。
其中S18为清零键,对1602进行清屏和对相关变量清零。
每位评委操控两个按键,分别代表“通过”和“不通过”。
第一位评委控制S6(通过)与S7(不通过);
第二位评委控制S10(通过)与S11(不通过);
第三位评委控制S14(通过)与S15(不通过);
当按“通过”次数多于“不通过”时,1602将显示“yes”,否则显示“no”。
在一个回合中,每位评委只有一次按键的权利,一旦按下,其操控的两个
按键均将被封锁,再按也不会有任何作用。除非按下清零键S18清零后开始下一回合。
************************************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit lcdrs=P3^5;
sbit lcden=P3^4;
sbit beep=P2^3;
uchar table[]="yes";
uchar table1[]="no";
uchar table2[]="agree";
uchar table3[]="disagree";
uchar table4[]=" ";
uchar table5[]="YES!";
uchar table6[]="NO!";
uchar pass,nopass;
bit flag,ok1,ok2,ok3; //flag是显示agree或者disagree的标志位,flag1,flag2,flag3是该按键释放被激活的标志位,因为每一次同一个人的按键只能被按一次
bit clear;
/*延时函数*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--) //即延时约z毫秒
for(y=110;y>0;y--);
}
/*1602液晶显示*/
/*写命令*/
void write_com(uchar com)
{
lcdrs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*写数据*/
void write_date(uchar date)
{
lcdrs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*初始化*/
void init()
{
dula=0;
wela=0;
lcden=0;
write_com(0x38);
delay(100);
write_com(0x0c);
delay(100);
write_com(0x06);
delay(100);
write_com(0x01);
delay(100);
}
void yes()
{
uchar a;
write_com(0x80+0x40+6);
delay(20);
for(a=0;a<4;a++)
{
write_date(table5[a]);
delay(20);
}
}
void no()
{
uchar a;
write_com(0x80+0x40+6);
delay(20);
for(a=0;a<3;a++)
{
write_date(table6[a]);
delay(20);
}
}
/*agree/disagree显示*/
void display(bit flag)
{
uchar i;
write_com(0x01); //显示之前需要将之前显示的清零
write_com(0x80);
if(flag)
{
for(i=0;i<5;i++)
{
write_date(table2[i]);
delay(20);
}
}
else
{
for(i=0;i<8;i++)
{
write_date(table3[i]);
delay(20);
}
}
}
/*键盘扫描程序*/
void keyscan()
{
uchar temp;
if(!ok1)
{
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee: //S6被按下
flag=1;
pass++;
ok1=1;
//agree(); //调用该函数存在错误,最好是在等待按键之后再调用显示函数,所以解决方法是设置标志位,在后面调用display()函数
break;
case 0xde: //S7被按下
flag=0;
nopass++;
ok1=1;
//disagree();
break;
}
while(temp!=0xf0) //等待按键被释放
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
display(flag);
}
}
}
if(!ok2)
{
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed: //S10被按下
flag=1;
pass++;
ok2=1;
break;
case 0xdd: //S11被按下
flag=0;
nopass++;
ok2=1;
break;
}
while(temp!=0xf0) //等待按键被释放
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
display(flag);
}
}
}
if(!ok3)
{
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb: //S14被按下
flag=1;
pass++;
ok3=1;
break;
case 0xdb: //S15被按下
flag=0;
nopass++;
ok3=1;
break;
}
while(temp!=0xf0) //等待按键被释放
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
display(flag);
}
}
}
P3=0xf7;
temp=P3; //S18,清零
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:
clear=1;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
}
/*主函数*/
void main()
{
uchar count;
init();
while(1)
{
keyscan();
count=pass+nopass;
if(count==3)
{
delay(2000);
write_com(0x01);
delay(2000);
if(pass > nopass)
{
yes();
}
if(nopass > pass)
{
no();
}
}
if(clear)
{
ok1=0;
ok2=0;
ok3=0;
count=0;
pass=0;
nopass=0;
clear=0;
write_com(0x01);
}
}
}
个位前辈,刚入行不久,为什么以上的程序出现了问题,我一直没有弄出来,现象就是:agree和disagree正常显示,但是最后显示结果“yes”或“no”的时候,1602就显示1秒,然后就出现乱码了。这是什么原因呢?如果不要keyscan()函数,直接给pass和nopass赋值的话,那么结果“yes”或“no”就正常显示。。
|