无论是矩阵键盘还是独立键盘,单片机检测其是否被按下的方法都是一样的。也就是检测与按键对应的 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<reg51.h>#include<intrins.h>
#define nop() _nop_()
#define keyport P1
#define ledport P2
unsigned char code seg[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71} //共阴数码管段码
void delayms(unsigned int ms) //12M
{
unsigned int t
for(ms>0ms--)
for(t=123t>0t--)
}
unsigned char keyscan(void)
{
unsigned char temp
keyport=0xFF
nop()nop()
if(keyport!=0xFF)
{
delayms(10)
if(keyport!=0xFF)
{
switch(keyport)
{
case 0xFE:temp=1break
case 0xFD:temp=2break
case 0xFB:temp=3break
case 0xF7:temp=4break
case 0xEF:temp=5break
case 0xDF:temp=6break
case 0xBF:temp=7break
case 0x7F:temp=8break
}
}
}
return temp
}
void display(unsigned char dat)
{
ledport=seg[dat]
}
void main(void)
{
unsigned char num
for()
{
num=keyscan()
display(num)
}
}
//按照你的图,proteus仿真通过,上电后显示0,按下第一个按键就显示1,以此类推。。。
//希望可以帮到你。
//如果你是单片机爱好者,可以加我QQ,我们共同进步!
//当然了,如果你感觉以上的键盘扫描方法效率低的话,可以试试以下的分时采样法,效果是一样的。
#include<reg51.h>
#include<intrins.h>
#define nop() _nop_()
#define keyport P1
#define ledport P2
unsigned char code seg[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}
unsigned char temp
void display(unsigned char dat)
{
ledport=seg[dat]
}
void main(void)
{
TMOD |= 0x01
TH0 = 0xEC
TL0 = 0x78
EA = 1
ET0 = 1
TR0 = 1
for()
{
display(temp)
}
}
void Timer0Interrupt(void) interrupt 1
{
static unsigned char c
TH0 = 0xEC
TL0 = 0x78
if(keyport==0xFF) c=0
if((c<100)&&(++c==10))
{
switch(keyport)
{
case 0xFE:temp=1break
case 0xFD:temp=2break
case 0xFB:temp=3break
case 0xF7:temp=4break
case 0xEF:temp=5break
case 0xDF:temp=6break
case 0xBF:temp=7break
case 0x7F:temp=8break
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)