矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组,I51开发板上的矩阵键盘,实物图如下图所示:
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P0口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
那么什么是行列扫描法呢?
行扫描法:行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下:
1、先第一行输出0,检查列线是否非全高;
2、否则第二行输出0,检查列线是否非全高;
3、否则第三行输出0,检查列线是否非全高;
4、如果某行输出0时,查到列线非全高,则该行有按键按下;
5、根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。
I51开发板上的4*4矩阵键盘的结构如下图所示:
在本例中,矩阵键盘的四列依次接到单片机的P0.4~P0.7,四行依次接到单片机的P0.0~P0.3;另外,行跟列的每个IO口上都加了一个10K的电阻(实际是用排阻代替的):
按照前面介绍的行列扫描法,我们可以在程序中这样实现:
uchar code T_KeyTable = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//按键K02~K17对应键值:0~15
void Check_Key(void)
{
uchar row,col,tmp1,tmp2;
tmp1 = 0x01; // tmp1用来设置P0口的输出,取反后使P0.0~P0.3中的一位为0
for(row=0;row<4;row++) // 行检测
{
P0 = 0xf0; // 先将P0.4~P0.7置高
P0 =~tmp1; // 使P0.00为0
tmp1<<=1; // tmp1左移一位
if((P0 & 0xf0) != 0xf0)// 检测P0.4~P0.7中是否有一位为0,只要有,则说明此行有键按下,进入列检测
{
tmp2 = 0x10; // tmp2用于检测出哪一列为0,从第一列P0.4开始
for(col =0;col<4;col++) // 列检测
{
if((P0 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列
{
KeyCode =T_KeyTable; // 获取键值,识别按键;T_KeyTable为按键的定义表
return; // 退出循环
}
tmp2<<=1; // tmp2左移一位
}
}
}
}
在本例中,是通过按矩阵按键上的任意一个按键,会产生对于的键值,通过数码管来显示对于的按键按下的键值以判断按键是否争取,最后我们来看下程序的运行效果吧:
这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。至于其他的一些方法就留给读者自行去研究吧,矩阵键盘的部分就简单介绍到这里了!
程序源代码(回复可见):
I51开发板第二十讲 蜂鸣器简介
https://bbs.icxbk.com/community/forum.php?mod=viewthread&tid=66196
(出处: ICKEY BBS)