蓝桥杯单片机-07矩阵键盘的扫描原理

本文详细描述了如何在单片机平台中使用4x4矩阵键盘进行扫描,通过逐行逐列的方式检测按键,并在按键松开时在数码管上显示对应的数字。代码展示了按键扫描过程和数码管显示逻辑。
摘要由CSDN通过智能技术生成

要求

在单片机训练平台上,首先将J5处的跳帽接到1、2引脚,使键盘组成4x4的键盘。

在扫描键盘的过程中,发现有按键触发信号后(不做去抖动),在按键松开后,在数码管的第一位显示相应的数字:从左到右,从上到下,依次显示0~F

电路图:

矩阵键盘的原理

思想:逐行逐行的扫描,逐列逐列的读取 

如图所示,逐行扫描的时候,只能有一个低电平。第一次扫描,让第一行为低电平,得到行0111,在列得到1111;第二次扫描得到行1011,列1101,说明第二行第三列按下了。以此类推。 

代码

要求

按键扫描

/*============按键扫描==============*/
unsigned char key_num;

void ScanKeyMulti()
{
	//第一次
	R1 = 0;
	R2 = R3 = R4 =1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 ==0)
	{
		while(C1 == 0);
		key_num = 0;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
  {
		while(C2 == 0);
    key_num = 1;
    DisplayKey(SMG_duanma[key_num]);
  }
	else if(C3 == 0)
  {
		while(C3 == 0);
    key_num = 2;
    DisplayKey(SMG_duanma[key_num]);
  }
	else if(C4 == 0)
  {
		while(C4 == 0);
    key_num = 3;
    DisplayKey(SMG_duanma[key_num]);
  }
	//第二次
	R2 = 0;
	R1 = R3 = R4 = 1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 == 0)
	{
		while(C1 == 0);
		key_num = 4;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
	{
		while(C2 == 0);
		key_num = 5;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C3 == 0)
	{
		while(C3 == 0);
		key_num = 6;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C4 == 0)
	{
		while(C4 == 0);
		key_num = 7;
		DisplayKey(SMG_duanma[key_num]);
	}
	
	//第三次
	R3 = 0;
	R2 = R1 = R4 = 1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 == 0)
	{
		while(C1 == 0);
		key_num = 8;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
	{
		while(C2 == 0);
		key_num = 9;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C3 == 0)
	{
		while(C3 == 0);
		key_num = 10;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C4 == 0)
	{
		while(C4 == 0);
		key_num = 11;
		DisplayKey(SMG_duanma[key_num]);
	}
	
	//第四次
	R4 = 0;
	R2 = R3 = R1 = 1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 == 0)
	{
		while(C1 == 0);
		key_num = 12;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
	{
		while(C2 == 0);
		key_num = 13;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C3 == 0)
	{
		while(C3 == 0);
		key_num = 14;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C4 == 0)
	{
		while(C4 == 0);
		key_num = 15;
		DisplayKey(SMG_duanma[key_num]);
	}
}

完整代码

#include"reg52.h"
//关于矩阵键盘的定义
sfr P4 = 0xC0;    //定义P4口

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,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};

void SelectHC138(unsigned char channel)     //通过38译码器对P2口写,控制锁存器
{
	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 DisplayKey(unsigned char value)
{
	P0 = 0xff;
	SelectHC138(6);
	P0 = 0x01;          //选择第一个数码管
	SelectHC138(7);
	P0 = value;
}

/*============按键扫描==============*/
unsigned char key_num;

void ScanKeyMulti()
{
	//第一次
	R1 = 0;
	R2 = R3 = R4 =1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 ==0)
	{
		while(C1 == 0);
		key_num = 0;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
  {
		while(C2 == 0);
    key_num = 1;
    DisplayKey(SMG_duanma[key_num]);
  }
	else if(C3 == 0)
  {
		while(C3 == 0);
    key_num = 2;
    DisplayKey(SMG_duanma[key_num]);
  }
	else if(C4 == 0)
  {
		while(C4 == 0);
    key_num = 3;
    DisplayKey(SMG_duanma[key_num]);
  }
	//第二次
	R2 = 0;
	R1 = R3 = R4 = 1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 == 0)
	{
		while(C1 == 0);
		key_num = 4;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
	{
		while(C2 == 0);
		key_num = 5;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C3 == 0)
	{
		while(C3 == 0);
		key_num = 6;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C4 == 0)
	{
		while(C4 == 0);
		key_num = 7;
		DisplayKey(SMG_duanma[key_num]);
	}
	
	//第三次
	R3 = 0;
	R2 = R1 = R4 = 1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 == 0)
	{
		while(C1 == 0);
		key_num = 8;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
	{
		while(C2 == 0);
		key_num = 9;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C3 == 0)
	{
		while(C3 == 0);
		key_num = 10;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C4 == 0)
	{
		while(C4 == 0);
		key_num = 11;
		DisplayKey(SMG_duanma[key_num]);
	}
	
	//第四次
	R4 = 0;
	R2 = R3 = R1 = 1;
	C1 = C2 = C3 = C4 =1;
	
	if(C1 == 0)
	{
		while(C1 == 0);
		key_num = 12;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C2 == 0)
	{
		while(C2 == 0);
		key_num = 13;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C3 == 0)
	{
		while(C3 == 0);
		key_num = 14;
		DisplayKey(SMG_duanma[key_num]);
	}
	else if(C4 == 0)
	{
		while(C4 == 0);
		key_num = 15;
		DisplayKey(SMG_duanma[key_num]);
	}
}


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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值