[牛人杂谈] 3个IO口扫描16个按键

[复制链接]
1798|16
 楼主| 643757107 发表于 2018-8-26 10:53 | 显示全部楼层 |阅读模式

1353680002_1753.jpg

          1353679073_1935.jpg

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

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

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

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

  16. {
  17. P1=P1&0xfe;   /*I/O1写“0”*/
  18. x=P1&0x07;
  19. x=x/2+7;
  20. if(x= =10)
  21. {
  22. P1=P1|0x07;
  23. P1=P1&0xfd; /*I/O2写“0”*/
  24. x=P1&0x07;
  25. x=(x+1)/2+10; /*屏蔽I/O2并转换K10至K12的键值*/
  26. if(x = =13)
  27. {
  28. P1=P1|0x07;
  29. P1=P1&0xfb; /*I/O3写“0”*/
  30. x=P1&0x07;
  31. x=x+13; /*屏蔽I/O3并转换K13至K15的键值*/
  32. }
  33. }
  34. }
  35. return x;
  36. }



 楼主| 643757107 发表于 2018-8-26 10:53 | 显示全部楼层

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

1353678987_7443.jpg

个人觉得自己写程序的时候有个地方需要注意:当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 | 显示全部楼层
我太笨了,我没看懂。
xuanhuanzi 发表于 2018-8-26 20:42 | 显示全部楼层
这真是个神奇的想法。
 楼主| 643757107 发表于 2018-8-26 21:23 | 显示全部楼层
这种方式有点复杂耗时。
xinpian101 发表于 2018-9-2 15:13 | 显示全部楼层
没有矩阵的好懂
Levin0 发表于 2018-9-10 17:22 | 显示全部楼层
利害!虽然处理比较麻烦,但特殊情况下可以省不小的IO口
734774645 发表于 2018-9-10 22:26 | 显示全部楼层
heisexingqisi 发表于 2018-9-10 23:48 | 显示全部楼层
6到不能行
dongliushui 发表于 2018-9-10 23:56 | 显示全部楼层
方法虽然慢,但是有用。
heisexingqisi 发表于 2018-9-11 22:02 | 显示全部楼层
试了一下,给力
wahahaheihei 发表于 2018-9-11 22:15 | 显示全部楼层
算法小复杂。
yzjyh 发表于 2019-7-8 16:12 | 显示全部楼层
本帖最后由 yzjyh 于 2019-7-9 07:42 编辑

硬件电路有缺陷,程序也弥补不了。 用户也不可能完全按照你的逻辑来操作
wahahaheihei 发表于 2019-7-8 16:28 | 显示全部楼层
方法好,但是我不会用。
wahahaheihei 发表于 2019-7-8 16:28 | 显示全部楼层
如果单按键的形式,那用ADC,可以弄一堆。
windows100 发表于 2019-7-8 16:57 | 显示全部楼层
wahahaheihei 发表于 2019-7-8 16:28
如果单按键的形式,那用ADC,可以弄一堆。

我也觉得ADC比上面的好,且ADC方式还可以检测出来同时按下的情况。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

223

主题

3955

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部