蓝桥杯-单片机(矩阵键盘)

文章详细介绍了矩阵键盘的工作原理,利用单片机检测按键的下降沿,通过改变列电位确定具体按键,同时提供了简单的C语言代码示例。

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

一、矩阵键盘电路原理图

如果需要使用矩阵键盘的时候,需要将CON3的1和2进行短接。

在上一讲已经讲过按键的原理,在本文就不再赘述了,直接讲解一下矩阵键盘的工作原理:

        前文提到过,如果单片机需要检测到有一个按键是否被按下最好的解决方案是直接检测与该按键直接相连的单片机引脚上的电平变化,如果在除抖操作后检测到一个上升沿或者下降沿,则认为该按键被按下。在矩阵键盘中也采用相同的处理措施。

        15单片机的引脚都是采用的外接上拉电阻处理,所以在没有任何外设的影响下,单片机的引脚是处在高电平状态,所以,我们对于按键而言,只能采用捕获下降沿的方式(5V->0v)来判断按键是否被按下,而不可采用获取上升沿的方式来检验按键。

        通过观察原理图,我们可以发现,矩阵键盘是有四行,四列,共16个节点组成的按键矩阵,我们可以将其用坐标方式给每个按键一个新的表述:

仔细读矩阵键盘的原理图,(1,1)坐标下的按键是由P3^0(P3寄存器的第3位)和P4^4(P4寄存器的第4位)两个引脚控制的,那我们想要制造一个下降沿,可以让P44为低点位或者让P30为低huan电位,然后检测另一个引脚的电位变化,就可以得到我们想要的一个结果。

  如果前面设置都没问题,那么按照理论,按下(1,1)按键,P30的引脚上会出现一个下降沿,由此可以判断,(1,1)按键被按下。

        按照如此理论,我们只要去模仿(1,1)按键的例子,就能完成矩阵键盘的检测工作,仔细观察不难发现,我们其实并不需要去用一个for或者while的循环,循环16次来检测,我们可以从原理图中看出,每一列与4行相交都会有4个交点,我们只需呀将某一列/(某一行)的电位置为0V,其余列/(其余行)的电位置为5V,然后循环检测4行/(4列)上面的电位变化,就可以得到矩阵键盘上第一列中哪一个按键被按下,然后依此改变后面三列上的电位,就可以实现矩阵键盘的键位检测了。

二:代码部分

/*实现功能:根据矩阵键盘对应的数值,led显示其二进制数*/
#include <stc15f2k60s2.h>

sbit HC_A=P2^5;           
sbit HC_B=P2^6;           
sbit HC_C=P2^7;           

char result = 0;

void delay(unsigned int t)
{
	while(t--);
}

/*矩阵键盘部分*/
char button()
{
	P35 = 1;
	P36 = 1;
	P42 = 1;
	P44 = 0;	
	if(P30 == 0 && P44 == 0)
	{
		delay(200);
		while(P30 == 0);
		delay(200);
		return 0x01;
	}
	
	if(P31 == 0 && P44 == 0)
	{
		delay(200);
		while(P31 == 0 );
		delay(200);
		return 0x05;	
	}
	
	if(P32 == 0 && P44 == 0)
	{
		delay(200);
		while(P32 == 0);
		delay(200);
		return 0x09;	
	}
	
	if(P33 == 0 && P44 == 0)
	{
		delay(200);
		while(P33 == 0);
		delay(200);
		return 0x0D;	
	}
	P34 = 1;
	P35 = 1;
	P42 = 0;
	P44 = 1;
	if(P30 == 0 && P42 == 0)
	{
		delay(200);
		while(P30 == 0);
		delay(200);
		return 0x02;
	}
	
	if(P31 == 0 && P42 == 0)
	{
		delay(200);
		while(P31 == 0);
		delay(200);
		return 0x06;	
	}
	
	if(P32 == 0 && P42 == 0)
	{
		delay(200);
		while(P32 == 0);
		delay(200);
		return 0x0A;	
	}
	
	if(P33 == 0 && P42 == 0)
	{
		delay(200);
		while(P33 == 0);
		delay(200);
		return 0x0E;	
	}	

	P34 = 1;
	P35 = 0;
	P42 = 1;
	P44 = 1;
	if(P30 == 0 && P35 == 0)
	{
		delay(200);
		while(P30 == 0);
		delay(200);
		return 0x03;
	}
	
	if(P31 == 0 && P35 == 0)
	{
		delay(200);
		while(P31 == 0);
		delay(200);
		return 0x07;	
	}
	
	if(P32 == 0 && P35 == 0)
	{
		delay(200);
		while(P32 == 0);
		delay(200);
		return 0x0B;	
	}
	
	if(P33 == 0 && P35 == 0)
	{
		delay(200);
		while(P33 == 0);
		delay(200);
		return 0X0F;	
	}	

	P34 = 0;
	P35 = 1;
	P42 = 1;
	P44 = 1;
	if(P30 == 0 && P34 == 0)
	{
		delay(200);
		while(P30 == 0);
		delay(200);
		return 0x04;
	}
	
	if(P31 == 0 && P34 == 0)
	{
		delay(200);
		while(P31 == 0);
		delay(200);
		return 0x08;
	}
	
	if(P32 == 0 && P34 == 0)
	{
		delay(200);
		while(P32 == 0);
		delay(200);
		return 0x0C;		
	}
	
	if(P33 == 0 && P34 == 0)
	{
		delay(200);
		while(P33 == 0);
		delay(200);
		return 0xff;	
	}	
}
/*主函数*/
void main()
{
	HC_A = 0;
    HC_B = 0;
    HC_C = 1;         	
    P0 = 0xff;
	while(1)
	{
		result = button();
		P0 = ~result;
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值