bit keyscan()//扫描按键函数
{
bit yes=0;
unsigned char temp;
P2=0xfe;//扫描第1行
temp=P2;//读取端口值,检测是否有按键按下
if(temp!=0xfe)
{
delay(15);//按下去抖
temp=P2;
if(temp!=0xfe)//再一次判断,确实有键按下再执行
{
yes=1;
while(P2!=0xfe);
delay(15);
while(P2!=0xfe);
switch(temp)//获取键值
{
case 0x7e:NUM=14;break;
case 0xbe:NUM=0;break;
case 0xde:NUM=12;break;
case 0xee:NUM=11;break;
}
}
}
P2=0xfd;//扫描第2行
temp=P2;
if(temp!=0xfd)
{
delay(15);//按下去抖
temp=P2;
if(temp!=0xfd)
{
yes=1;
while(P2!=0xfd);
delay(15);
while(P2!=0xfd);
switch(temp)
{
case 0x7d:NUM=7;break;
case 0xbd:NUM=8;break;
case 0xdd:NUM=9;break;
case 0xed:NUM=15;break;
}
}
}
P2=0xfb;//扫描第3行
temp=P2;
if(temp!=0xfb)
{
delay(15);//按下去抖
temp=P2;
if(temp!=0xfb)
{
yes=1;
while(P2!=0xfb);
delay(15);
while(P2!=0xfb);
switch(temp)
{
case 0x7b:NUM=4;break;
case 0xbb:NUM=5;break;
case 0xdb:NUM=6;break;
case 0xeb:NUM=10;break;
}
}
}
P2=0xf7;//扫描第4行
temp=P2;
if(temp!=0xf7)
{
delay(15);//按下去抖
temp=P2;
if(temp!=0xf7)
{
yes=1;
while(P2!=0xf7);
delay(15);
while(P2!=0xf7);
switch(temp)
{
case 0x77:NUM=1;break;
case 0xb7:NUM=2;break;
case 0xd7:NUM=3;break;
case 0xe7:NUM=13;break;
}
}
}
return yes;
}
其中NUM为全局变量,每次检测到有按键按下时会返回‘1’,通过读取NUM来获得键值,四个switch语句中的NUM值完全取决于你要把该按键设定为何值而定的。
本程序的键盘扫描的原理就是进行行扫描,每一行先对端口写行扫描字,然后再读取端口值,若该行有按键按下,则按键对应列线被拉为低电平。扫描完四行就可以检测一遍16个键了。
你放到中断里可能会出现这样的情况,程序运行到键盘检查段时候,你没有设置跳出中断,这样说吧!程序在扫描键盘时候需要有键盘返回的值,当你键盘没有任何反应(没去按它)它就一直在检查检查,就没有跳出中断,所以你的机械手死在了这个无限循环的检查中。这样设置,中断计时,到点了中断一下检查一下键盘值,检查完后马上跳出来让MCU去执行其他程序段。
首先单片机引脚默认输出高电瓶的。令控制某一行(假设第n行)键盘的引脚为0,然后按下该行的某一键,然后一列一列的检查低电平(假设检测出为第m列),由此判断出按下的为第nm键。思路就是令行为低电平,检查列(当然反之也可以)
p3=fe就是扫描第一行,然后&上f0就是屏蔽低位高位不等于f0则有建按下,后面你那个12345678……就是第几个建,如你的例子,=ed的时候是发生在p3=fd的程序,fd是第二行手机打字欢迎追问
#include <reg51h>
#include <intrinsh>
#define uchar unsigned char
#define uint unsigned int
unsigned char code Led_Show[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00};
void delayms(void);
uchar kbscan(void);
void main()
{
uchar key;
while(1)
{
key=kbscan();
if(key!=0)
{
switch(key)
{
case 0x18:P0 = Led_Show[0];
break;
case 0x14:P0 = Led_Show[1];
break;
case 0x12:P0 = Led_Show[2];
break;
case 0x11:P0 = Led_Show[3];
break;
case 0x28:P0 = Led_Show[4];
break;
case 0x24:P0 = Led_Show[5];
break;
case 0x22:P0 = Led_Show[6];
break;
case 0x21:P0 = Led_Show[7];
break;
case 0x48:P0 = Led_Show[8];
break;
case 0x44:P0 = Led_Show[9];
break;
case 0x42:P0 = Led_Show[14];
break;
case 0x41:P0 = Led_Show[15];
break;
default:break;
}
}
}
}
uchar kbscan(void)
{
unsigned char sccode,recode;
P2=0x0f; //发0扫描,列线输入
if ((P2 & 0x0f) != 0x0f) //有键按下
{
delayms(); //延时去抖动
if ((P2&0x0f)!= 0x0f)
{
sccode = 0xef; //逐行扫描初值
while((sccode&0x01)!=0)
{
P2=sccode;
if((P2&0x0f)!=0x0f)
{
recode=(P2&0x0f)|0xf0;
return((~sccode)+(~recode));
}
else
sccode=(sccode<<1)|0x01;
}
}
}
return 0; //无键按下,返回0
}
void delayms(void)
{
unsigned char k,y;
for (k=200; k>0; k--)
for (y=50;y>0;y--);
}
以上就是关于51单片机 矩阵键盘扫描全部的内容,包括:51单片机 矩阵键盘扫描、用亚龙单片机实训装置,通过51单片机控制机械手,我把矩阵键盘的键盘扫描程序放在定时器中断里,、51单片机。4*4矩阵键盘扫描程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)