蓝桥杯基础教程之矩阵按键操作学习蓝桥杯必看基础!

原理

什么叫矩阵键盘呢?

33在这里插入图片描述

在这里插入图片描述
这里要想形成4*4的矩阵键盘就需要将J5跳冒的12脚相连。

矩阵键盘的连接是有一定要求的,仔细看图你可以发现P30连接着第一排按键的右边,同理P31-P33都连接这2.3.4行的按键的右边

这里你也可以发现,P44这里连接的是第一列按键的左边,同理,P42.P35.P34都连接的是2.3.4列的按键的左边。

矩阵键盘的扫描可以用行扫描和列扫描,两种的工作原理一样,效果也是一样的。其实分开,也就是先扫描第一行,再扫描第二行。。。最后到第四行。每次扫描和独立键盘的方式是一样的,这样组合起来也就成了矩阵键盘。

下面简单举个例子,理解一下矩阵键盘是如何工作的。

比如,现在使用行扫描的方法。我们现在要检测3第一行的按键,让P30为低电平,然后根据判断P44.P42.P35以及P34的电平即可检测第一行的按键,然后依次让P31为低电平,扫描第二行的按键,再扫描第三行最后第四行。这样就达到了矩阵键盘的目的。

代码

#include "STC15F2K60S2.h"

#define SEL(x)  P2 = (P2 & 0x1f) | (x << 5); P2 = (P2 & 0x1f)
#define P0FF P0 = 0xff
typedef unsigned char uchar;
typedef unsigned int uint;

enum{
    
    LED = 4, EXT, DIG, CODE};

sbit BP = P0^6; sbit RY = P0^4;
uchar code r[] = {
    
    0xfe, 0xfd, 0xfb, 0xf7};
sbit K1 = P3^7; sbit K2 = P3^6; sbit K3 = P3^5; sbit K4 = P3^4;


enum{
    
    KS_GET, KS_ASSIGN, KS_WAITDEAL}KeyState = KS_GET;
uchar TempKey = 0,Key = 0, KeyCnt = 0; 
uint HoldCnt = 500;
uchar i = 0;

uchar GetKey()
{
    
    
	uchar i = 0;	
	uchar KeyValue = 0;
	for(i=0; i < 4; i++)
	{
    
    
		P3 = r[i]; 
		if(K1 == 0)			{
    
    KeyValue = 4*i+1; break;}
		else if(K2 == 0){
    
    KeyValue = 4*i+2; break;}
		else if(K3 == 0){
    
    KeyValue = 4*i+3; break;}
		else if(K4 == 0){
    
    KeyValue = 4*i+4; break;}
	}
	return KeyValue;
}

void Init()
{
    
    
	P0FF;
	SEL(LED);
	BP = 0;RY = 0;
	SEL(EXT);
}
void Timer1Init(void)		//2毫秒@12.000MHz
{
    
    
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x9A;		//设置定时初值
	TH1 = 0xA9;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	//加上
	ET1 = 1;		//允许定时器1中断
	EA = 1;		   	//全局允许中断开启
}

void Timer1Handle() interrupt 3
{
    
    
	switch(KeyState)
	{
    
    
	 case KS_GET:
		TempKey = GetKey();
		KeyState = KS_ASSIGN;
		KeyCnt = 10;
	 break;
	 
	 case KS_ASSIGN:
		if(KeyCnt != 0)
		{
    
    
		 KeyCnt--;
		}
		else if(TempKey == GetKey())
		{
    
    
		 if(TempKey != Key)
		 {
    
    
		  Key = TempKey;
			KeyState = KS_WAITDEAL;
		 }
		 else if(HoldCnt-- != 0);
		 else
		 {
    
    
		  Key = TempKey;
			KeyState = KS_WAITDEAL;
			HoldCnt = 500;
		 }
		}
		else
		{
    
    
		 KeyState = KS_GET;
		}
	 break;
	}
}

void main()
{
    
    
	Init();		
	Timer1Init();								
	while(1)
	{
    
    														
	 if(KeyState == KS_WAITDEAL)
	 {
    
    
	  switch(Key)
		{
    
    
		 case 1:
			P0 = 0xfe;
			SEL(LED);

		 break;
		 case 2:
			P0 = 0xfd;
			SEL(LED);

		 break;
		 case 7:
			P0 = 0xfb;
			SEL(LED);

		 break;
		 case 11:
			P0 = 0xf7;
			SEL(LED);

		 break;
		}
		KeyState = KS_GET;
	 }
	}
}

重要部分

uchar code r[] = {
    
    0xfe, 0xfd, 0xfb, 0xf7};
uchar GetKey()
{
    
    
	uchar i = 0;	
	uchar KeyValue = 0;
	for(i=0; i < 4; i++)
	{
    
    
		P3 = r[i]; 
		if(K1 == 0)			{
    
    KeyValue = 4*i+1; break;}
		else if(K2 == 0){
    
    KeyValue = 4*i+2; break;}
		else if(K3 == 0){
    
    KeyValue = 4*i+3; break;}
		else if(K4 == 0){
    
    KeyValue = 4*i+4; break;}
	}
	return KeyValue;
}

r数组的含义就是行的意思(row),其余的地方和独立按键都是一样的,只有这里不同。这里遵循的规则就是,每次在一次按键扫描中,分为四次扫,每次扫一行。
比如扫第一行P3 = 0xfe,这个时候P30为0,其余全部为高。然后这个时候去判断K1-K4就是在判断第一行从左到右四个按键的情况。当第一个键返回的时候,返回的值就是4*0+1=1.其余情况以此类推!


注意事项

有个需要注意的就是P34引脚用作NE555检测的时候,这根线是不能用做按键检测的。因此比赛方为了既考矩阵键盘又要考NE555的话,就会让矩阵键盘不是4*4的,比如在这个4*4的键盘上面进行裁剪,让你做2*2或者3*3的矩阵键盘。这个时候只要你掌握了原理,随便它怎么靠,你都能够很快写出来的。

希望读者能自行完成一个3*3的键盘。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37429313/article/details/114289279