完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
单片机系统中,若使用按键较多时如电子密码锁、电话机键盘等一般都至少有12到16个按键,通常采用矩阵键盘。矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4*4个。这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。最常见的键盘布局一般由16个按键组成,在单片机中正好可以用一个P口实现16个按键功能,这也是在单片机系统中最常用的形式,4*4矩阵键盘的内部电路如下图所示。
当无按键闭合时,P3.0~P3.3与P3.4~P3.7之间开路。当有键闭合时,与闭合键相连的两条I/O口线之间短路。 判断有无按键按下的方法是:第一步,置列线P3.4~P3.7为输入状态,从行线P3.0~P3.3输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。第二步,行线轮流输出低电平,从列线P3.4~P3.7读入数据,若有某一列为低电平,则对应行线上有键按下。 综合上述两步的结果,可确定按键编号。但是键闭合一次只能进行一次键功能操作,因此须等到按键释放后,再进行键功能操作,否则按一次键,有可能会连续多次进行同样的键操作。识别按键的方法很多,其中最常见的方法是扫描法。当按键按下时,与此键相连的行线与列线导通,行线在无按键按下时处在高电平。如果所有的列线都处在高电平,则按键按下与否不会引起行线电平的变化,因此必须使所有列线处在低电平。这样,当有按键按下时,该键所在的行电平才会由高变低,才能判断相应的行有键按下。矩阵按键的位置由于行号和列号是唯一确定,因此可以分别对行号和列号进行二进制编码,然后两值合成一个字节,高4位是行号,低4位是列号。 代码如下: #include void delay(int t) { int x, y; for (x = t; x > 0; x--) for (y = 10; y > 0; y--); } void main (void) { while (1) { P3 = 0xfe; //扫描第一行 temp = P3; temp = temp & 0xf0; //保留列上的信息 if (temp != 0xf0) //四列有输入为低电平0的? 有按键? { delay(10); //过10ms,再观察。 if (temp != 0xf0) //还是四列有输入为低的情况?有按键? { temp = P3; //读一下信息。 switch (temp) { case 0xee: //如果是第一行第一列? key = 0; break; case 0xde: key = 1; break; case 0xbe: key = 2; break; case 0x7e: key = 3; break; } while (temp != 0xf0) { temp = P3; temp = temp & 0xf0; } disp(key); } } P3 = 0xfd; temp = P3; temp = temp & 0xf0; if (temp != 0xf0) { delay(10); if (temp != 0xf0) { temp = P3; switch (temp) { case 0xed: key = 4; break; case 0xdd: key = 5; break; case 0xbd: key = 6; break; case 0x7d: key = 7; break; } while (temp != 0xf0) { temp = P3; temp = temp & 0xf0; } disp(key); } } P3 = 0xfb; temp = P3; temp = temp & 0xf0; if (temp != 0xf0) { delay(10); if (temp != 0xf0) { temp = P3; switch (temp) { case 0xeb: key = 8; break; case 0xdb: key = 9; break; case 0xbb: key = 10; break; case 0x7b: key = 11; break; } while (temp != 0xf0) { temp = P3; temp = temp & 0xf0; } disp(key); } } P3 = 0xf7; temp = P3; temp = temp & 0xf0; if (temp != 0xf0) { delay(10); if (temp != 0xf0) { temp = P3; switch (temp) { case 0xe7: key = 12; break; case 0xd7: key = 13; break; case 0xb7: key = 14; break; case 0x77: key = 15; break; } while (temp != 0xf0) { temp = P3; temp = temp & 0xf0; } disp(key); } } } } |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1180浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 20:06 , Processed in 1.155057 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号