蓝桥杯06-矩阵键盘

1、矩阵键盘的扫描思想
    与独立按键不同的是,按键的两个引脚都分别连接的单片机的I/O端口,一个作为行信号,另外一个作为列信号。我们以4X4的矩阵键盘为例,试着探讨其工作方式和扫描思路。


    在上面的矩阵键盘中,要识别出黄色按键的按下状态,应该怎么做呢?
    对与矩阵键盘,我们只能逐行扫描,然后读取列的状态信号。如果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输出高电平,逐个读取判断列信号。
    如此循环往复,扫描的按键的状态。
    我们知道有按键按下动作,那么又怎么知道是哪一个按键按下呢?这时,我们最好定义一个键值全局变量,给矩阵行列上的每一个的按键编一个唯一的号码。当扫描的某一行某一列的按键动作后,把对应的编号复制给键值变量,这样我们判断这个键值,就知道是那个按键有触发动作了。

#include "reg52.h"

sfr P4 = 0xc0;  //若使用15芯片的头文件,可正常命名

sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;

sbit C4 = P3^4;
sbit C3 = P3^5;
sbit C2 = P4^2;
sbit C1 = P4^4; 

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

														

void ScanKeysMulti();														
void DisPlayKeyNum();
void SelectHC573();														

void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 4: P2 = (P2 & 0x1f) | 0x80; break;
		case 5: P2 = (P2 & 0x1f) | 0xa0; break;
		case 6: P2 = (P2 & 0x1f) | 0xc0; break;
		case 7: P2 = (P2 & 0x1f) | 0xe0; break;
		
	}
}

void DisPlayKeyNum(unsigned char value)
{
	SelectHC573(6);
	P0 = 0x01;
	SelectHC573(7);
	P0 = value;
}

unsigned char key_num ;
void ScanKeysMulti()   //键盘扫描函数
{
	R1 = 0;                      //第一次扫描
	R2 = R3 = R4 = 1;
	C1 = C2 = C3 = C4 = 1;
	if(C1==0)
	{
		while(C1==0);
		key_num = 0;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C2==0)
	{
		while(C2==0);
		key_num = 1;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C3==0)
	{
		while(C3==0);
		key_num = 2;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C4==0)
	{
		while(C4==0);
		key_num = 3;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	
	R2 = 0;                      //第二次扫描
	R1 = R3 = R4 = 1;
	C1 = C2 = C3 = C4 = 1;
	if(C1==0)
	{
		while(C1==0);
		key_num = 4;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C2==0)
	{
		while(C2==0);
		key_num = 5;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C3==0)
	{
		while(C3==0);
		key_num = 6;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C4==0)
	{
		while(C4==0);
		key_num = 7;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	
	R3 = 0;                      //第三次扫描
	R2 = R1 = R4 = 1;
	C1 = C2 = C3 = C4 = 1;
	if(C1==0)
	{
		while(C1==0);
		key_num = 8;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C2==0)
	{
		while(C2==0);
		key_num = 9;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C3==0)
	{
		while(C3==0);
		key_num = 10;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C4==0)
	{
		while(C4==0);
		key_num = 11;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	
	R4 = 0;                      //第四次扫描
	R2 = R3 = R1 = 1;
	C1 = C2 = C3 = C4 = 1;
	if(C1==0)
	{
		while(C1==0);
		key_num = 12;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C2==0)
	{
		while(C2==0);
		key_num = 13;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C3==0)
	{
		while(C3==0);
		key_num = 14;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	else if(C4==0)
	{
		while(C4==0);
		key_num = 15;
		DisPlayKeyNum(SMG_duanma[key_num]);
	}
	
}





void main()
{
	while(1)
	{
		ScanKeysMulti();
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值