打印
[牛人杂谈]

3个IO口扫描16个按键

[复制链接]
1455|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主


         

该电路在程序处理时,由处理器首先向I/O1~I/O3写高电平,然后读入。如果非全“1”,说明,K0~K6中有键按下,此时可根据读入的端口状态判断键的状态,如果读入的结果为全“1”,则I/O1~I/O3轮流输出低电平,再读入,这样就可根据另外两根I/O线的状态来判别是K7~K15中的哪一个键被按下。重复调用键盘处理子程序可将读取的键值与上次的值进行比较,甚至两次读数相同为止,这样即可消除按键抖动所造成的误读。该电路选用的单片机为

AT89C2051
,用C51语言编写的按键电路处理程序如下:

#include<c:eg51.h>
#define uchar unsigned char
uchar getkey(void);
uchar keyvol;
void main(void)
{
keyvol=getkey(); /*调用键处理函数,返回的数据等于16表示同有键按下,0至15对应k0至K15*/
}
以下为键盘处理子程序:
uchar getkey(void)
{
uchar x
P1=P1|0x07; /*I/O1至I/O3写“1”*/
x=P1&0x07; /*读入I/O1至I/O3并屏蔽其它位*/

if(x==0x07)   /*判断K0至K6是否按下并转换键值*/

{
P1=P1&0xfe;   /*I/O1写“0”*/
x=P1&0x07;
x=x/2+7;
if(x= =10)
{
P1=P1|0x07;
P1=P1&0xfd; /*I/O2写“0”*/
x=P1&0x07;
x=(x+1)/2+10; /*屏蔽I/O2并转换K10至K12的键值*/
if(x = =13)
{
P1=P1|0x07;
P1=P1&0xfb; /*I/O3写“0”*/
x=P1&0x07;
x=x+13; /*屏蔽I/O3并转换K13至K15的键值*/
}
}
}
return x;
}



沙发
643757107|  楼主 | 2018-8-26 10:53 | 只看该作者

利用该键盘电路并根据逻辑组合原理可推断开n条I/O线可组合的按键数N为:
N=(2n-1)+(2 n-1 -1)n


个人觉得自己写程序的时候有个地方需要注意:当IO口赋值011,按k0之后IO读数为000,按k13读数也为000,所以如果检测到到k0到k6,这几个都没按才可以继续检测k7到k15.


使用特权

评论回复
板凳
pmw_56| | 2018-8-26 12:10 | 只看该作者
643757107 发表于 2018-8-26 10:53
利用该键盘电路并根据逻辑组合原理可推断开n条I/O线可组合的按键数N为:
N=(2n-1)+(2 n-1 -1)n

好方法,先MARK下

使用特权

评论回复
地板
小明的同学| | 2018-8-26 18:12 | 只看该作者
我太笨了,我没看懂。

使用特权

评论回复
5
xuanhuanzi| | 2018-8-26 20:42 | 只看该作者
这真是个神奇的想法。

使用特权

评论回复
6
643757107|  楼主 | 2018-8-26 21:23 | 只看该作者
这种方式有点复杂耗时。

使用特权

评论回复
7
xinpian101| | 2018-9-2 15:13 | 只看该作者
没有矩阵的好懂

使用特权

评论回复
8
Levin0| | 2018-9-10 17:22 | 只看该作者
利害!虽然处理比较麻烦,但特殊情况下可以省不小的IO口

使用特权

评论回复
9
734774645| | 2018-9-10 22:26 | 只看该作者
真牛X

使用特权

评论回复
10
heisexingqisi| | 2018-9-10 23:48 | 只看该作者
6到不能行

使用特权

评论回复
11
dongliushui| | 2018-9-10 23:56 | 只看该作者
方法虽然慢,但是有用。

使用特权

评论回复
12
heisexingqisi| | 2018-9-11 22:02 | 只看该作者
试了一下,给力

使用特权

评论回复
13
wahahaheihei| | 2018-9-11 22:15 | 只看该作者
算法小复杂。

使用特权

评论回复
14
yzjyh| | 2019-7-8 16:12 | 只看该作者
本帖最后由 yzjyh 于 2019-7-9 07:42 编辑

硬件电路有缺陷,程序也弥补不了。 用户也不可能完全按照你的逻辑来操作

使用特权

评论回复
15
wahahaheihei| | 2019-7-8 16:28 | 只看该作者
方法好,但是我不会用。

使用特权

评论回复
16
wahahaheihei| | 2019-7-8 16:28 | 只看该作者
如果单按键的形式,那用ADC,可以弄一堆。

使用特权

评论回复
17
windows100| | 2019-7-8 16:57 | 只看该作者
wahahaheihei 发表于 2019-7-8 16:28
如果单按键的形式,那用ADC,可以弄一堆。

我也觉得ADC比上面的好,且ADC方式还可以检测出来同时按下的情况。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

213

主题

3783

帖子

11

粉丝