无论是矩阵键盘还是独立键盘,单片机检测其是否被按下的方法都是一样的。也就是检测与按键对应的 I/O 口的电平高低。
Ø 独立按键有一端固定为低电平或高电平,单片机写检测程序时比较方便。
Ø 矩阵按键两端都与单片机I/O口相连,因此检测时需要人为地通过单片机 I/O 口送出低电平。先送一列为低电平,其余几列全为高电平(此时确定了列数),然后轮流检测一次各行是否有低电平,若某一行为低电平(此时又确定了行数)。那么我们就可以确定是哪一行哪一列的键被按下。 用同样的方法,依次轮流送各列一次低电平,再轮流检测一次各行中是否有低电平。这样就可检测完 所有的按键,也就能判断出被按下的是哪一个键。 当然我们也可将各行线置低电平,然后扫描检测各列线中是否出现低电平, 这就是矩阵键盘检测的原理和方法。
#include <reg51.h>
#define uchr unsigned char
#define uint unsigned int
uchr code DSY_Table[]= //共阳极数码管编码
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80, //0,1,2,3,4,5,6,7,8
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF, //9,A,B,C,D,E,F,-
}
uchr key //按键序号
void delayms(uchr x)
{
uchr i
while(x--) for(i=0i<120i++)
}
void main()
{
uchr kp
P0=0xff
while(1)
{
P1=0xfd //P1.1置 0
if(P1!=0xfd) //有键按下?
{
delayms(5) //延时消抖动
if(P1!=0xfd) //确认
{
kp=P1 //读取端口键值
while(P1!=0xfd) //等待键松开
switch(kp&0xf0) //屏蔽低4位,判断高4位
{
case 0xe0: //若高4位为e(即1键)
key=1 //赋键值
break
case 0xd0: //若高4位为d(即5键)
key=5 //赋键值
break
case 0xb0: //若高4位为b(即9键)
key=9 //赋键值
break
case 0x70: //若高4位为7(即"9"键:num[9])
key=13 //赋键值
break
}
}
}
P0 = DSY_Table[key] //显示按键值
delayms(5)
}
}
其实方法很多的,这只是简单的一种#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define KEYDOWN 1//按键按下
#define KEYUP 0//按键d开
#define led_date P0 //LED数据口
bit key_first = 1 //按键第一次按下
bit key_state = KEYUP //按键状态
uchar key_value//键值
code uchar LED[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,}
//LED段码 共阳管
void main(void)
void key_scan(void)
void key_scan()
{
uchar key_buff,key_date
key_date = P1 &0xFF
if(key_date != 0xFF)
{
if(key_state != KEYDOWN)
{
if(key_first == 1)
{
key_buff = key_date
key_first = 0
}
else
{
if(key_date == key_buff)
{
key_value = ~key_date
key_state = KEYDOWN
}
}
}
}
else
{
key_first = 1
key_state = KEYUP
}
}
void main()
{
while(1)
{
key_scan()
switch(key_value)
{
case 0x01:
{
led_date = LED[1]
}break
case 0x02:
{
led_date = LED[2]
}break
case 0x04:
{
led_date = LED[3]
}break
case 0x08:
{
led_date = LED[4]
}break
case 0x10:
{
led_date = LED[5]
}break
case 0x20:
{
led_date = LED[6]
}break
case 0x40:
{
led_date = LED[7]
}break
case 0x80:
{
led_date = LED[8]
}break
default: break
}
}
}
下面这个代码会短一些
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define KEYDOWN 1//按键按下
#define KEYUP 0//按键d开
#define led_date P0 //LED数据口
bit key_first = 1 //按键第一次按下
bit key_state = KEYUP //按键状态
uchar key_value//键值
code uchar LED[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,}
//LED段码 共阳管
void main(void)
void key_scan(void)
void key_scan()
{
uchar i,key_buff,key_date
key_date = P1 &0xFF
if(key_date != 0xFF)
{
if(key_state != KEYDOWN)
{
if(key_first == 1)
{
key_buff = key_date
key_first = 0
}
else
{
if(key_date == key_buff)
{
for(i=0i<8i++)
{
if(!((key_date>>i)&0x01))
{
break
}
}
key_value = LED[i+1]
key_state = KEYDOWN
}
}
}
}
else
{
key_first = 1
key_state = KEYUP
}
}
void main()
{
while(1)
{
key_scan()
led_date = key_value
}
}
有独立键盘和距阵键盘的 独立键盘的很简单我就不写了 距阵的我给你写一个//键盘扫描
uchar Keys_Scan()
{
uchar sCode,kCode,i,k
//低4 位置0,放入4 行
P1=0xf0
//若高4 位出现0,则有键按下
if((P1&0xf0)!=0xf0)
{
DelayMS(2)
if((P1&0xf0)!=0xf0)
{
sCode=0xfe//行扫描码初值
for(k=0k<4k++) //对4 行分别进行扫描
{
P1=sCode
if((P1&0xf0)!=0xf0)
{
kCode=~P1
for(i=0i<16i++) //查表得到按键序号并返回
if(kCode==KeyCodeTable[i])
return(i)
}
else
sCode=_crol_(sCode,1)
}
}
}
return(-1)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)