郭天祥51单片机 矩阵键盘的程序问题,求解
要求如下:在没有键摁下的情况下,数码管没有显示。但是每摁下一个键后,会在六个数码上同时显示相同的数字,释放是数码管灭掉。下面是我写的一个程序,运行的结果不对,没键摁下是数码管也有显示,键被摁下之后被释放,数码管依然有显示,这个问题要怎么解决呀?进主函数我就把数码管的位选全部关掉了,结果数码管是乱码,怎么回事???求高手解决
#include<reg52.h>
#define uchar unsigned char
#define uintunsigned int
sbit wela=P2^7;
sbit dula=P2^6;
uchar code table[]=
{0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar temp,num;
uchar keyscan();
void display(uchar aa);
void delay(uint z);
//主函数
void main()
{
wela=1;
P0=0xc0; //开所有位选
wela=0;
dula=1;
P0=0x00;
dula=0;
while(1)
{
display(keyscan());
}
}
//延时函数
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//键盘扫描函数
uchar keyscan()
{
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(8); //去抖
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:num=0;break;
case 0xde:num=1;break;
case 0xbe:num=2;break;
case 0x7e:num=3;break;
}
}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(8); //去抖
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=4;break;
case 0xdd:num=5;break;
case 0xbd:num=6;break;
case 0x7d:num=7;break;
}
}
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(8); //去抖
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=8;break;
case 0xdb:num=9;break;
case 0xbb:num=10;break;
case 0x7b:num=11;break;
}
}
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(8); //去抖
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num=12;break;
case 0xd7:num=13;break;
case 0xb7:num=14;break;
case 0x77:num=15;break;
}
}
}
return num;
}
//数码管显示函数
void display(uchar aa)
{
dula=1;
P0=table;
dula=0;
} uchar code table[]={。。。。。。0x00};第十七个数设为0x00,num默认为设置为16,主程序如下 while(1)
{
display(keyscan());
display(num);
num=16;
} {:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:} 本帖最后由 yao1 于 2012-6-6 21:35 编辑
看的头大 给你个看看
//////////////////////////////////////////////////////////////////////////////////
//扫描法:逐行扫描查询 一般用在按键比较少的场合
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); //超过列范围 退出扫描
}
}
}
////////////////////////////////////////////////////////////////////////////////
//线反转法 :只需2步便可获得按键位置,最常用
unsigned intkeyboar()/*线反转法 */
{
static unsigned int a=0;
unsigned char a1=0,b1=0;
/*行线为输入线,列线为输出线 */
v1=v2=v3=v4=0;
h1=h2=h3=h4=1;
if(P2<0xf0)/*检查行是否有按键按下 */
{
delayms(10);
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 1;}
else if(a==0xeb) { return 2;}
else if(a==0xed) { return 3;}
else if(a==0xee) { return 4;}
else if(a==0xd7) {return 5; }
else if(a==0xdb) {return 6; }
else if(a==0xdd) {return 7; }
else if(a==0xde) {return 8; }
else if(a==0xb7) {return 9;}
else if(a==0xbb) {return 10;}
else if(a==0xbd) {return 11;}
else if(a==0xbe) {return 12;}
else if(a==0x77) {return 13;}
else if(a==0x7b) {return 14;}
else if(a==0x7d) {return 15;}
else if(a==0x7e) {return 16;}
else return 17;
} 楼主这程序本来就是一直显示的,因为天详的板子的位选是会被锁存住的,你在进入大循环前,就已经P0=0xc0; //开所有位选了,并且被573锁存住,当初始上电时,num被初始化为0,所以应该显示0,当有键按下,和释放按键之后,num都维持被按下的那个数,所以都会一直显示~~~建议你在keyscan()里,当有键按下时,返回被按下值,没键按下里,返回一个无键按下标志,在display(uchar aa)里,判断aa,如果aa是无键按下标志,则关闭位选,不显示,如果是有键按下,则显示相应值。
uchar num; 51单片机中变量不赋初值,初始化时将是什么值?如果初始化为0,则一开始显示应该是0,如果不是0,是任意一个数,那初始上电,就有可能像你说的那样显示乱码~~~好久没用51了,没有板子测试一下~~希望楼主测试一下~~
矩阵键盘超级难理解。。。楼主现在懂了吗?求教啊! 先扫描行,再扫描列
页:
[1]