矩阵键盘(蓝桥杯练习06)

矩阵键盘扫描原理

独立按键:接上拉电阻,按键未按下时稳定输出高电平。按下按键,引脚接地,读到低电平。
在这里插入图片描述
矩阵键盘:两别都接在了IO口上。若左边IO口为0,按键按下右边读出低电平,未被按下则读出高电平。
在这里插入图片描述
扫描思路:先选中一行,使IO口为低电平,依次扫描列,若读出的IO口为低电平,则按键被按下,依次重复上述操作。

在这里插入图片描述

练习内容

在这里插入图片描述

代码部分

注意:新板子没有P4口,使用前要定义
这里定义的第一行第一列为右上角的那个按键
16个按键,这里只用一位数码管显示按键值,对应0~F的段码值

#include "reg52.h"
#include "delay.h"

sfr P4=0xC0;//新板子没有P4口,要定义

sbit r1=P3^0;//行
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;

sbit c1=P3^4;//列
sbit c2=P3^5;
sbit c3=P4^2;
sbit c4=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};//0~F,“-”,“.”对应段码
//声明为“code”,节约ram区资源

unsigned char keynum=0;

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 display(unsigned char value)
{
	selecthc573(6);//位选
	P0=0x01;
	selecthc573(7);//段选
	P0=value;
}

void scanmulti()
{
	r1=0;//选中第一行
	r2=r3=r4=1;
	c1=c2=c3=c4=1;
	if(c1==0)
	{
		delayxms(20);//去抖动
		while(c1==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=0;
		display(SMG_duanma[keynum]);
	}
	else if(c2==0)
	{
		delayxms(20);//去抖动
		while(c2==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=1;
		display(SMG_duanma[keynum]);
	}
	else if(c3==0)
	{
		delayxms(20);//去抖动
		while(c3==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=2;
		display(SMG_duanma[keynum]);
	}
	else if(c4==0)
	{
		delayxms(20);//去抖动
		while(c4==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=3;
		display(SMG_duanma[keynum]);
	}
	r2=0;//选中第二行
	r1=r3=r4=1;
	c1=c2=c3=c4=1;
	if(c1==0)
	{
		delayxms(20);//去抖动
		while(c1==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=4;
		display(SMG_duanma[keynum]);
	}
	else if(c2==0)
	{
		delayxms(20);//去抖动
		while(c2==0);//等待按键松开
		delayxms(6);//去抖动
		keynum=5;
		display(SMG_duanma[keynum]);
	}
	else if(c3==0)
	{
		delayxms(20);//去抖动
		while(c3==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=6;
		display(SMG_duanma[keynum]);
	}
	else if(c4==0)
	{
		delayxms(20);//去抖动
		while(c4==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=7;
		display(SMG_duanma[keynum]);
	}
	r3=0;//选中第三行
	r2=r1=r4=1;
	c1=c2=c3=c4=1;
	if(c1==0)
	{
		delayxms(20);//去抖动
		while(c1==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=8;
		display(SMG_duanma[keynum]);
	}
	else if(c2==0)
	{
		delayxms(20);//去抖动
		while(c2==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=9;
		display(SMG_duanma[keynum]);
	}
	else if(c3==0)
	{
		delayxms(20);//去抖动
		while(c3==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=10;
		display(SMG_duanma[keynum]);
	}
	else if(c4==0)
	{
		delayxms(20);//去抖动
		while(c4==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=11;
		display(SMG_duanma[keynum]);
	}
	r4=0;//选中第四行
	r2=r3=r1=1;
	c1=c2=c3=c4=1;
	if(c1==0)
	{
		delayxms(20);//去抖动
		while(c1==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=12;
		display(SMG_duanma[keynum]);
	}
	else if(c2==0)
	{
		delayxms(20);//去抖动
		while(c2==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=13;
		display(SMG_duanma[keynum]);
	}
	else if(c3==0)
	{
		delayxms(20);//去抖动
		while(c3==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=14;
		display(SMG_duanma[keynum]);
	}
	else if(c4==0)
	{
		delayxms(20);//去抖动
		while(c4==0);//等待按键松开
		delayxms(20);//去抖动
		keynum=15;
		display(SMG_duanma[keynum]);
	}
}

void main()
{
	while(1)
	{
		 scanmulti();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值