两种方式实现矩阵键盘扫描(含程序) 您所在的位置:网站首页 stm32键盘数字读取程序 两种方式实现矩阵键盘扫描(含程序)

两种方式实现矩阵键盘扫描(含程序)

2023-07-18 22:12| 来源: 网络整理| 查看: 265

1 矩阵键盘的结构

下图是一个4*3的矩阵键盘示意图,三条列线连接P1.4-P1.6引脚。四条行线连接P1.0-P1.3引脚 在这里插入图片描述

2 逐行逐列扫描法

首先使三条列线所连接的I/O引脚P14-P16输出低电平,四条行线所连接的I/O引脚P10-P13输出高电平。当没有按键按下时,四条行线所连接的I/O引脚读取到的将全部是高电平;而当有按键按下时,由于该按键所在的行线与列线接通,行线将被下拉到低电平。此时读取行线所连接的引脚P10-P13,将不再全是高电平,由此可以判断出有按键按下。判断有按键按下后,还要用逐行逐列扫描法来获取按键的键值。

逐行逐列扫描法的原理是:逐列将列线依次置低电平,读取行线,如果某一条行线为低电平,则说明该行线与当前置为低电平的列线交叉点处的按键被按下,从而可以获取按键的键值。

#define keyboard P1 //四条行线三条列线所连接的IO口 unsigned char Check_Keyboard() { unsigned char row_scan_code=0x01; //行扫描码 unsigned char col_scan_code=0xEF;//列扫描码 unsigned char keycode; //按键键值 unsigned char i,x,j; //可以做一个消抖处理 for(i=0;i if(!(x&row_scan_code))//说明对应行的按键按下,使行线被拉低 { keycode+=3*j; //如果按键还未释放,则仍有行线被拉至低电平 while((keyboard&0x0f)!=0x0f);//等待按键释放 P1=0x0F; //恢复原状态,为下次按键做准备 return keycode; //已检测到按键键码,返回 } else row_scan_code=_crol_(row_scan_code,1); } col_scan_code=_crol_(col_scan_code,1);//左移一位,将下一列线拉低 row_scan_code=0x01;//重置行扫描码,为下一行扫描作准备 } keycode=0;//没有按键按下,键值记为0 return keycode; } 3 线反法

上面逐行逐列扫描法较为繁琐,在实际的单片机系统中更常用的是线反法。 在这里插入图片描述 线反法的原理为:首先使P1口的高四位输出高电平,P1口低四位输出低电平,这时键盘的行线被拉高,列线被拉低。如果有按键按下,则某一条行线将被拉低,此时读取P1口高四位,读取到的将不再全为高电平,说明有按键按下。(在判断是否有按键按下这一点上,线反法与逐行逐列扫描法是一致的)根据读取到0值的I/O口所连接的行线,就可以判断出按下的按键位于哪一行。接下来使P1口的高四位输出低电平,P1口低四位输出高电平(即与上次输出的电平相反,因此称为线反法)。如果有按键按下,此时读取P1口低四位,读取到的将不再全为高电平,根据读取到0值的I/O口所连接的列线,就可以判断出按下的按键位于哪一列。综合按键所在的行线与列线,即可唯一确定按键所在位置,进而获取按键的键值。

//@brief:判断4*4矩阵键盘是否有键可靠按下,高4位口接行线,低四位口接列线 //@retval:当有键可靠按下时返回1-16的键值,否则返回0 #define keyboard P1 unsigned char Check_Keydown() { unsigned char KeyValue=0; keyboard=0x0f; if(keyboard!=0x0f)//如果按键按下 { delay_ms(10);//延时10ms消抖 if(keyboard!=0x0f)//按键确实按下 { //判断按键所在列,以所在列的第一行的按键键值赋给KeyValue keyboard=0X0F; switch(keyboard) { case(0X07): KeyValue=1;break; //第一列按下 case(0X0b): KeyValue=2;break; //第二列按下 case(0X0d): KeyValue=3;break; //第三列按下 case(0X0e): KeyValue=4;break; //第四列按下 } //判断按键所在行 keyboard=0XF0; switch(keyboard) { case(0X70): KeyValue=KeyValue;break; //第一行按下 case(0Xb0): KeyValue=KeyValue+4;break; //第二行按下 case(0Xd0): KeyValue=KeyValue+8;break; //第三行按下 case(0Xe0): KeyValue=KeyValue+12;break; //第四行按下 } while(keyboard!=0xf0); //按键松手后退出 return KeyValue; } else //否则认为是信号干扰导致 { return 0; //认为没有按键按下 } } return 0; //如果没有按键按下返回零 }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有