按键实验

按键实验,第1张

无论是矩阵键盘还是独立键盘,单片机检测其是否被按下的方法都是一样的。也就是检测与按键对应的 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)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8154253.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存