求51单片机的P1口接行列扫描的16个按键,试编程完成行列扫描的程序。
- 提问者网友:浩歌待明月
- 2021-07-28 07:45
- 五星知识达人网友:由着我着迷
- 2021-07-28 09:12
uchar keyscan()
{
P1=0xfe; //P1赋值,低位送0
temp=P1; //temp读回P1的值,
temp=temp&0xf0; //屏蔽 temp低四位,只看高四位列控是否发声变化
while(temp!=0xf0) //不等,说明第一行有键按下
{ //延时去抖
delay(5); //再检测
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0) //果真有键按下,
{ //把P1给temp,检测按键位置
temp=P1;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
break;
}
while(temp!=0xf0) //一次按键检测,松手跳出循环
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xfd; //检测第二列
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=5;
break;
case 0xdd:num=6;
break;
case 0xbd:num=7;
break;
case 0x7d:num=8;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xfb;
temp=P1; //检测第三列
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=9;
break;
case 0xdb:num=10;
break;
case 0xbb:num=11;
break;
case 0x7b:num=12;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xf7; //检测第四列
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=13;
break;
case 0xd7:num=14;
break;
case 0xb7:num=15;
break;
case 0x77:num=16;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
return num; //返回检测结果,
}
- 1楼网友:刀戟声无边
- 2021-07-28 09:34
给你一个经典的,自己研究研究:
#define Key_Port P1
unsigned char code tab[]={0x7e,0x7d,0x7b,0x77,0xbe,0xbd,0xbb,0xb7,0xde,0xdd,0xdb,0xd7,0xee,0xed,0xeb,0xe7}; unsigned char Key_Scan(void) { unsigned char key_temp=0xff,i=0xff; Key_Port=0xf0; if(Key_Port!=0xf0) { key_temp=Key_Port; Key_Port=0x0f; //线反转 key_temp=(Key_Port&0x0f)|(key_temp&0xf0); //这里已经得到键码 while(Kep_Port!=0x0f); //等待按键释放,可在while里加入显示防止显示中断 for(i=0;i<16;i++) //键码比较,找到则退出循环 if(tab[i]==key_temp)break; } return i; //返回查找到的是第几个键,一般都需要数字键,这样做很有用,如无按键按下则返回0xFF, }
如只需返回键码,则只要如下写即可,比楼主的经典得多也有效得多
unsigned char Key_Scan(void) { unsigned char key_temp=0xff; Key_Port=0xf0; if(Key_Port!=0xf0) { key_temp=Key_Port; Key_Port=0x0f; //线反转 key_temp=(Key_Port&0x0f)|(key_temp&0xf0); //这里已经得到键码 while(Kep_Port!=0x0f); //等待按键释放,可在while里加入显示防止显示中断 } return key_temp; //返回键码,如无按键按下则返回0xFF, }