(51单片机)第四章-键盘检测原理及应用实现-矩阵键盘检测

本文围绕51单片机展开,介绍矩阵键盘检测原理与方法,为节省I/O口采用矩阵键盘,以4×4矩阵键盘为例说明工作原理,还给出检测按键的具体步骤。同时提供了上电后数码管显示0 - F的例程,以及用JX - TX - 1C实验板制作的闹钟示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

4.2 矩阵键盘检测

  书上例程:实验板上电时,数码管不显示,顺序按下矩阵键盘后没再数码管上依此显示0~F,6个数码管同时静态显示即可

         一个用JX-TX-1C实验板制作的24小时以内的时间显示或者倒数计数模式的闹钟(相较以前有所更新)示例

参考资料: 


4.2 矩阵键盘检测

        独立键盘与单片机相连时每一个案件都需要单片机的一个I/O口,若单片机系统需要较多按键则独立按键会占用过多的I/O口资源。为节省I/O口,因纳入矩阵键盘。以4×4矩阵键盘为例讨论起工作原理和检测方法——16个按键排成4行4列,4行4列一共8根线,连接到单片机的8个I/O口上。

   TX-1C上的连接图原理如下:

        矩阵键盘检测是否按下原理同独立键盘——检测该键对应的I/O口是否为低电平,矩阵键盘两端都与I/O口相连,因此检测时需认为通过单片机I/O口送出低电平。检测时,送一列为低电平,其余几列为高电平(确定了列),再检测哪一行为低电平即可确定按下键的行列号,如此轮流检测各列各行,即可检测完所有的按键,反之先检测行线同理可行。 

        其中,TX-1C上的4行S6~S21的8条线分别与单片机的P3口相连——4行分别连P3.0~P3.3,4列分别于单片机的P3.4~P3.7(注意这里与独立按键占用的I/O口重复了,为防止发生51单片机独立键盘和矩阵键盘引脚定义相同IO口导致的问题(串口干扰):在扫描独立按键程序的开头加一句,P3=0xff;)。

        当无按键闭合时,P3.0~P3.3与P3.4~P3.7之间开路。当有键闭合时,与闭合键相连的两条I/O口线之间短路。判断有无按键按下的方法是:

(1)置列线P3.4~P3.7为输入状态,从行线P3.0~P3.3输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。

(2)行线轮流输出低电平,从列线P3.4~P3.7读入数据,若有某一列为低电平,则对应行线上有键按下。综合一二两步的结果,可确定按键编号。但是键闭合一次只能进行一次键功能操作,因此须等到按键释放后,再进行键功能操作,否则按一次键,有可能会连续多次进行同样的键操作。

        检测矩阵键盘语句说明:(以扫描第一行按键为例)

         注:关于位运算可以参考文章:http://t.csdnimg.cn/dAUY9

        为方便编程和查找,在下面的例程中进行了如下的优化:

(1)将矩阵键盘行线存入code数组中便于表示和查找

uchar code matrixkeyboard_row_table[]={	//矩阵键盘行线
	0xfe, //第一行线
	0xfd, //第二行线
	0xfb, //第三行线
	0xf7  //第四行线	
};

(2)将矩阵键盘键位编码存入code数组中便于表示和查找 

uchar code matrixkeyboard_table[]={ //矩阵键盘按钮编号
	0xee,0xde,0xbe,0x7e, //第一行key1~4
	0xed,0xdd,0xbd,0x7d, //第二行key5~8
	0xeb,0xdb,0xbb,0x7b, //第三行key9~12
	0xe7,0xd7,0xb7,0x77  //第四行key13~16
};

(3) 由于(1)无法采用switch case语句(由于case后必须跟的是常数),因此判断temp具体值部分修改为(具体的情况请代入下面的例程):

temp=P3;

if(temp == matrixkeyboard_table[4*i-4]) key_num=4*i-3;
if(temp == matrixkeyboard_table[4*i-3]) key_num=4*i-2;
if(temp == matrixkeyboard_table[4*i-2]) key_num=4*i-1;
if(temp == matrixkeyboard_table[4*i-1]) key_num=4*i;

  书上例程:实验板上电时,数码管不显示,顺序按下矩阵键盘后没再数码管上依此显示0~F,6个数码管同时静态显示即可

        (和原书所附程序有所不同,原理一致,相比之下更便捷更简短)

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char 

sbit dula=P2^6; //声明U1锁存器的锁存端
sbit wela=P2^7;	//声明U2锁存器的锁存端

uchar code dula_table[]={ //段选数码库
	0x3f,0x06,0x5b,0x4f, // 0,1,2,3
	0x66,0x6d,0x7d,0x07, //4,5,6,7
	0x7f,0x6f,0x77,0x7c, //8,9,10,11
	0x39,0x5e,0x79,0x71  //12,13,14,15
};

uchar code matrixkeyboard_row_table[]={	//矩阵键盘行线
	0xfe, //第一行线
	0xfd, //第二行线
	0xfb, //第三行线
	0xf7  //第四行线	
};

uchar code matrixkeyboard_table[]={ //矩阵键盘按钮编号
	0xee,0xde,0xbe,0x7e, //第一行key1~4
	0xed,0xdd,0xbd,0x7d, //第二行key5~8
	0xeb,0xdb,0xbb,0x7b, //第三行key9~12
	0xe7,0xd7,0xb7,0x77  //第四行key13~16
};
 
void main()
{
	void delayxms(uint xms); //延时函数 ms为单位
	void matrixkeyscan(); //矩阵键盘输入函数
	void display(uchar key_num); //数码管显示函数 
	dula=1;
	P0=0; //关闭所有数码管段选
	dula=0;
	wela=1; 
	P0=0xc0; //打开所有数码管的位选
	wela=0;
	
	while(1)
	{
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值