在51单片机中用C51编写矩阵键盘的程序。下面有我编写的,但不知道其中的keyscan()的函数,怎么就错了。

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
uchar keycheck(void);
uchar keyscan(void);
void display(uchar);
void delay(uint);
void main(void)
{
uchar num=16; //按键未按下保持上一次的状态,但上电时不显示
while(1)
{
if(keycheck()!=0)
{
delay(10);
if(keycheck()!=0)num=keyscan();
}
display(num);
}

}
uchar keycheck(void)
{
P1=0xf0;
if(P1==0xf0)return(0); //无键按下就返回0
else return(0xf0); //有键按下就返回oxf0
}
uchar keyscan(void)
{
uchar keycode;
uchar keyvalue;
uchar i,j,k;
keycode=0xfe;
for(i=0;i<4;i++)
{
P1=keycode;
k=0x10;
for(j=0;j<4;j++)
{
if(P1&k==0)
{
keyvalue=i*8+j;
while(keycheck()!=0); //判键松开
return(keyvalue);
}
else k=k<<1;
}
keycode=_crol_(keycode,1);
}
}
void display(uchar i)
{
P2=~a[i];
}
void delay(uint i)
{
while(--i);
}

函数返回值类型为非空的
但是在函数中有一个或者以上的分支没有返回值
例如
int test()
{
if(){....return 0;}
else if{ ......return 0;}
else{.....而这里没有返回值的话就可能会出现这种情况了}
}
uchar keyscan(void)
{
for( ..)
..return ()..//此处需加返回值
}追问

恩恩,记到了,但这个程序我调试过了。问题不在这里。而在于,当有键按下时,程序也不跳进计算键值的语句中 if(P1&k==0)

keyvalue=i*8+j;
while(keycheck()!=0); //判键松开
return(keyvalue);
}。不过你说的我确没有注意到,所以相当感激。但我的这个函数是在有键按下之后才会进入的,所以是一定会有返回值的。肯请阁下再帮我看看,我定当感激不尽。

追答

你用这个方式写吧
int keyscan() //扫描法
{
unsigned char k, k_temp;
P1=0xf0; //低位置0,准备查询按键
k=P1; //取得当前P1口状态
if(k!=0xf0) //如果有变化则表示有按键按下
{
delay(10); //延迟 消抖
k_temp=p1;
if(k==k_temp) //确实有键按下
{
k=0xfe;
do //循环扫描每一行
{
p1=k;
if(k!=p1)
{
switch(P1) //判断按键 并返回键值
{
//第1行
case 0x7e:{return 0; break;}
case 0xbe:{return 1; break;}
case 0xde:{return 2; break;}
case 0xee:{return 3; break;}
//第2行
case 0x7d:{return 4; break;}
case 0xbd:{return 5; break;}
case 0xdd:{return 6; break;}
case 0xed:{return 7; break;}
//第3行
case 0x7b:{return 8; break;}
case 0xbb:{return 9; break;}
case 0xdb:{return 10;break;}
case 0xeb:{return 11;break;}
//第4行
case 0x77:{return 12;break;}
case 0xb7:{return 13;break;}
case 0xd7:{return 14;break;}
case 0xe7:{return 15;break;}
}
}
k=_crol_(k,1);//移位 进入下一行扫描
}
while(k!=0xef); //超过列范围 退出扫描
}
}
}

追问

这个程序要用4个switch吧?其它方式我可以写,但是我就是搞不懂我上面的程序为什么就不可以,要不我把原文件(protues原理图。与C51程序)发给你,你帮我看一下,先感激了,qq512382078

追答

哪里要4个啊 1个就够了 就上面那个 你换上去自己调试下
主函数就
while(1)
{
b=keyscan() ;
}
//不过还是用反转法实用 仅需扫描2次可得按键值
unsigned int keyboar()//线反转法
{
static unsigned int a=0;
unsigned char a1=0,b1=0;
//行线为输入线,列线为输出线
v1=v2=v3=v4=0;
h1=h2=h3=h4=1;
if(P2<0xf0)//检查行是否有按键按下
{
if(key_return==1)
{

keytemp=0;

if(P2<0xf0)
{
//行线为输入线,列线为输出线
v1=v2=v3=v4=0;
h1=h2=h3=h4=1;
a1=P2;
//行线为输出线,列线为输入线
h1=h2=h3=h4=0;
v1=v2=v3=v4=1;
b1=P2;

a=a1|b1;
}
}
}
if (a==0xe7){return 7 ;}//(/)
else if(a==0xeb){return 8 ;}
else if(a==0xed){return 9 ;}
else if(a==0xee){return 13;}

else if(a==0xd7){return 4 ;}//(*)
else if(a==0xdb){return 5 ;}
else if(a==0xdd){return 6 ;}
else if(a==0xde){return 12;}

else if(a==0xb7){return 1 ;}//(-)
else if(a==0xbb){return 2 ;}
else if(a==0xbd){return 3 ;}
else if(a==0xbe){return 11;}

else if(a==0x77){return 0 ;}//(+)
else if(a==0x7b){return 15;}
else if(a==0x7d){return 16;}
else if(a==0x7e){return 10;}

else return 17;//cuo wu

}

温馨提示:答案为网友推荐,仅供参考
相似回答