矩阵键盘的原理及应用 - MARS的博客 - CSDN博客 https://blog.csdn.net/qq_40642465/article/details/80334530
矩阵键盘原理图:
第一行的行控制线接到p17,第二行的行控制线接到p16,第三行的行控制线接到p15,第4行的行控制线接到p14
第一列的列控制线接到p13,第二列的列控制线接到p12,第三列的列控制线接到p11,第四列的列控制线接到p10
矩阵键盘的原理和独立按键类似,另外我们可以把矩阵键盘的任意一行或一列作为一个独立键盘使用,假如我们把第一行作为独立键盘,那么我们只需要让P17输出高电平,其余7个io口输出低电平即可,假如我们按下了s1,那么p13的电平就会被拉低,变为低电平,所以我们可以通过查找低4位里哪一位为低电平就可以知道哪个按键按下了。
下面来说说矩阵按键扫描原理(即当我们按下一个矩阵键盘的按键时,如何获取按键的位置)
方法有2种,一种是逐行扫描,一种是行列扫描.接下来就主要讲讲行列扫描.
行列扫描的话,就是一开始让p1口高4位输出高电平,低4位输出低电平,若这4行按键里,有按键按下了,那么那一行按键对应的io的电平就会被拉低,我们就可以知道按键的行坐标.获取按键列坐标的方法也是类似的,就是一开始让p1口高4位输出低电平,低4位输出高电平,若这4列按键里,有按键按下了,那么那一列按键对应的io的电平就会被拉低,我们就可以知道按键的列坐标,获得了行坐标x,列坐标y后,4*(x-1)+y就是按键的编号.
接下来贴份应用的代码,目的就是赋予16个按键键值,分别对应的键值是从0~F。按下一个键,第一个数码管就显示对应的键值
原文:https://blog.csdn.net/zxnsirius/article/details/51088946
根据原理图
键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。现在我们以第二行的S5键为例,若按下S5后我们应该怎么得到这个键值呢?当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。首先,单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有键按下;其次,单片机将P11输出低电平,其它P10、P12、P13仍为高电平,此时再来读取列线数据,发现列线读到的数据有低电平,数值为1011(0x0B),如果我们的键盘布局已经确定,那么0x0B就代表S5的值了。转到S5键功能处理子程序就可以达到目的。
/*
功能:矩阵键盘扫面,按键显示键值程序
作者:siriuszxn
*/
#include "reg51.h"
#define KEYPORT = P1
unsigned char i;
unsigned char Keynum;
unsigned char Line; //行
unsigned char Mask;
unsigned char Col; //列
unsigned char ScanCode;
unsigned char code psegs_table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共阳极数码管0-F
void delay_ms(unsigned int t) //ms延时程序
{
unsigned char i;
unsigned int x;
x=t;
while(x--)
{
for(i=0;i<113;i++);
}
}
/* 键盘扫描程序 */
void keyscan()
{
while (1) //循环扫描键盘
{
P1 = 0xff; //开始
Line = 1;
Mask = 0x01;
for(i = 0; i < 4; i++)
{
P1 = ~Mask;
ScanCode = P1 & 0xf0;
if (ScanCode != 0xf0)
{
delay_ms(5);
}
ScanCode = P1 & 0xf0;
switch(ScanCode)
{
case 0xe0:Col=1;break;
case 0xd0:Col=2;break;
case 0xb0:Col=3;break;
case 0x70:Col=4;break;
default :Col=0;break;
}
if (Col > 0)
{
//根据行列计算键值
Keynum = (Line - 1) * 4 + Col;
//通过P0口接数码管显示
P0 = psegs_table[Keynum-1];
while(1)
{
ScanCode = P1 & 0xf0;
if(ScanCode == 0xf0)
{
break;
}
}
Mask <<= 1;
Line++;
}
}
}
}
原文:https://blog.csdn.net/weixin_40973138/article/details/86607562
key.h
有关输入输出管脚的选择可以多试验几组,有的管脚即使你配置成上拉输入,当你松开按键之后依然不会返回高电平,我在此就因为这个问题被卡了一阵子
关于我的矩阵键盘检测的原理简明阐述如下:
首先设置为行输出低电平,列上拉输入(即无外部干扰时保持高电平);
检测到按键按下,此时通过检测列的电平情况从而得知哪一列有按键被按下;
然后确定有按键被按下后,设置为列输出低电平,行上拉输入;
通过检测行的电平情况从而得知哪一行有按键被按下;
最后通过“不平行的两条直线相交于一点”原理,推知具体被按下的按键。
key.c