【ct107d】矩阵键盘

矩阵键盘

矩阵键盘的实现和动态数码管有一定的相似之处,动态数码管是循环通过段选来点亮.而矩阵键盘(4*4)是循环检测键值判断是否按下.
在这里插入图片描述
在上面的矩阵键盘中,要识别出黄色按键的按下状态,应该怎么做呢?
对与矩阵键盘,我们只能逐行扫描,然后读取列的状态信号。如果R3行输出低电平,那么黄色按键如果有按下动作的话,那读取C2列信号也应该为低电平,而该行上其他没有按下动作的按键的列信号则为高电平。因此,我们可以得到矩阵键盘的基本扫描步骤:
<1> R1输出点电平,R2、R3、R4输出高电平,逐个读取判断列信号,如果都为高电平则R1行上没有按键按下。
<2> R2输出点电平,R1、R3、R4输出高电平,逐个读取判断列信号。
<3> R3输出点电平,R1、R2、R4输出高电平,发现C2列信号为低电平,那么可以判断得R3行的C2列的按键有按下动作。
<4> R4输出点电平,R1、R3、R4输出高电平,逐个读取判断列信号。
如此循环往复,扫描的按键的状态。
我们知道有按键按下动作,那么又怎么知道是哪一个按键按下呢?这时,我们最好定义一个键值全局变量,给矩阵行列上的每一个的按键编一个唯一的号码。当扫描的某一行某一列的按键动作后,把对应的编号复制给键值变量,这样我们判断这个键值,就知道是那个按键有触发动作了。
在这里插入图片描述
首先让J5端子12 短接.才能实现矩阵键盘功能.
我们试着练习题目
在这里插入图片描述

#include<reg52.h>
#define uchar unsigned char
#define uchar unsigned char
sbit S1=P3^0;
sbit S2=P3^1;
sbit S3=P3^2;
sbit S4=P3^3;
sbit C4=P3^4;
sbit C3=P3^5;
sbit C2=P3^6;
sbit C1=P3^7;

uchar code SMG_NoDot[18] = 
    {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
     0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
     0xbf,0x7f};

void HC138(uchar n)
{
	switch(n)
	{
		case 4:	P2=(P2&0X0F)|0X80; break; 
		case 5:	P2=(P2&0X0F)|0Xa0; break; 
		case 6:	P2=(P2&0X0F)|0Xc0; break; 
		case 7:	P2=(P2&0X0F)|0Xe0; break; 
	}	
}

void displaykey(uchar dat)
{
	 HC138(6);
	 P0=0X01;
	 HC138(7);
	 P0=SMG_NoDot[dat];
}
void scankey()
{
   	S1=0;
	S2=S3=S4=1;
	if(C1==0)
	{
		if(C1==0)
		{
			displaykey(0);
			while(C1==0);	
		}
	}
	else if(C2==0)
	{
		if(C2==0)
		{
			displaykey(1);
			while(C2==0);	
		}	
	}
	else if(C3==0)
	{
		if(C3==0)
		{
			displaykey(2);
			while(C3==0);	
		}	
	}
	else if(C4==0)
	{
		if(C4==0)
		{
			displaykey(3);
			while(C4==0);	
		}	
	}
	S2=0;
	S1=S3=S4=1;
	if(C1==0)
	{
		if(C1==0)
		{
			displaykey(4);
			while(C1==0);	
		}
	}
	else if(C2==0)
	{
		if(C2==0)
		{
			displaykey(5);
			while(C2==0);	
		}	
	}
	else if(C3==0)
	{
		if(C3==0)
		{
			displaykey(6);
			while(C3==0);	
		}	
	}
	else if(C4==0)
	{
		if(C4==0)
		{
			displaykey(7);
			while(C4==0);	
		}	
	}
	S3=0;
	S2=S1=S4=1;
	if(C1==0)
	{
		if(C1==0)
		{
			displaykey(8);
			while(C1==0);	
		}
	}
	else if(C2==0)
	{
		if(C2==0)
		{
			displaykey(9);
			while(C2==0);	
		}	
	}
	else if(C3==0)
	{
		if(C3==0)
		{
			displaykey(10);
			while(C3==0);	
		}	
	}
	else if(C4==0)
	{
		if(C4==0)
		{
			displaykey(11);
			while(C4==0);	
		}	
	}
	S4=0;
	S2=S3=S1=1;
	if(C1==0)
	{
		if(C1==0)
		{
			displaykey(12);
			while(C1==0);	
		}
	}
	else if(C2==0)
	{
		if(C2==0)
		{
			displaykey(13);
			while(C2==0);	
		}	
	}
	else if(C3==0)
	{
		if(C3==0)
		{
			displaykey(14);
			while(C3==0);	
		}	
	}
	else if(C4==0)
	{
		if(C4==0)
		{
			displaykey(15);
			while(C4==0);	
		}	
	}
	
}
void init()
{
	HC138(5);
	P0=0X00;
}

void main()
{
	init();
	while(1)
	{
		scankey();
	}
}

我们发现代码十分的多 虽然好理解 但是十分繁琐 不美观
下篇文章 我们试着对该程序优化一下.

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你我山巅自相逢y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值