- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
最近在笔记本EC中使用到了18*8矩阵键盘,我原本以为这应该是很简单的实现原理:按下某个键时有一根行线与一根列线电平变化。简单地举个例子,比如18根列线为C0~C17,8根行线和R0~R7, 初始时所有的26线全为高电平, 按下按键‘A’时R0和C0为低电平,按下按键‘B’时R0和C1为低电平, 按下按键‘C’时R1和C0为低电平, 按下按键‘D’时R1和C1和低电平…,以此类推。这个实现原理看起来似乎非常准确又设计简便。然而, 仔细想想这样的设计在检测多个按键同时按下时是有BUG存在的,比如当检测到R0、R1、C0、C1这4根线全为低时你根本无法判断‘A’,‘B’,‘C’,‘D’这4个按键到底被同时按了几个, AD、ABD、ACD、BC、ABC、BCD、ABCD这些组合都是可能的。
为了解决这个问题,矩阵键盘采用了另外一种方式,逐行扫描方式,为方便理解,我们采用4*4的矩阵键盘来分析。首先看下原理图:
P10~P13是4根设计成输出口的行线,P14~P17是4根设计成输入口的列线。如此的设计该怎样区别是什么按键被按下了呢?判断方法如下:
1. 扫描P10行:
a) 将P10~P13输出为0 、1、1、1
b) 读P14~P17这4个输入口的电平。如果S0~S3都没被按下,则因为P14~P17都是上拉到VCC,所以都为高;如果有1个被按下比如是S1,则因P10输出为低,所以S1开关导通后P16应为低;如果有2个按下比如是S1,S2,则P16与P17应为低。
c) 根据P14~P17的电平即可得知S0~S3中共有几个按键被按下。
2. 扫描P11行:
a) 将P10~P13输出为1 、0、1、1
b) 读P14~P17这4个输入口的电平。如果S4~S7都没被按下,则因为P14~P17都是上拉到VCC,所以都为高;如果有1个被按下比如是S5,则因P10输出为低,所以S5开关导通后P16应为低;如果有2个按下比如是S5,S6,则P16与P17应为低。
c) 根据P14~P17的电平即可得知S4~S7中共有几个按键被按下。
3. 扫描P12行:将P10~P13输出为1 、1、0、1,其他步骤同上。
4. 扫描P13行:将P10~P13输出为1 、1、1、0,其他步骤同上。
通过这4行的扫描,我们已经能够确定S0~S15这16个按键当前的状态了。
C语言实现如下:
void key_scan() //键盘扫描函数
{
int i;
unsigned char n, row, rowmask ;
row = 1;
for(i=0; i4; i++) //共扫描4条行线
{
rowmask = ~(rowi); //i=0时,rowmask=0xfe, i=1时rowmask=0xfd…
P1=rowmask;
n = P1;
n = 0xf0;
if(n != 0xf0)
{
Delay();//防抖动
P1=rowmask;
n = P1;
n = 0xf0;
if(n != 0xf0)
{
switch(n)
{
case 0xE0://S(3+i*4)按下
break;
case 0xD0://S(2+i*4)按下
break;
case 0xB0://S(1+i*4)按下
break;
case 0x70://S(0+i*4)按下
break;
}
}
}
}
}
void Delay() //延时函数
{
int i,j;
for(i=0; i100; i++)
{
for(j=0; j100; j++);
}
}
本文来自CSDN博客,转载请标明出处:/sunwill_chen/archive/2010/05/22/5616087.aspx
文档评论(0)