第十五届蓝桥杯单片机组备赛——独立键盘&矩阵键盘

文章目录

  • 一、按键原理
  • 二、独立键盘&矩阵键盘
    • [2.1 独立按键](#2.1 独立按键)
    • [2.2 矩阵键盘](#2.2 矩阵键盘)
      • [2.2.1 列扫描](#2.2.1 列扫描)
      • [2.2.2 行扫描](#2.2.2 行扫描)
      • [2.2.3 代码实现(行扫描实现)](#2.2.3 代码实现(行扫描实现))
  • 三、矩阵键盘注意事项
    • [3.1 为什么要设置C1=C2=C3=C4=1](#3.1 为什么要设置C1=C2=C3=C4=1)
    • [3.2 按键消抖](#3.2 按键消抖)

一、按键原理

原理很简单,当我们没有按下SW2时,由于上拉电阻得作用,使得输入引脚得信号为高电平,当按下按键后,引脚直接接地,输入单片机引脚的信号就为低电平。

二、独立键盘&矩阵键盘

在比赛的板子上,独立键盘和矩阵键盘是合在一起的,通过跳线帽来选择是独立按键还是矩阵键盘(图中已经框起)。上图所示的是矩阵键盘,将跳线帽拔了换到另一边就是独立按键了。

2.1 独立按键

独立按键一段接着GND,说明只要按下按键引脚就输入低电平。这时候我们只需要读取按键所连接的IO口状态就可以判断按键是否被按下

2.2 矩阵键盘

矩阵键盘中每个按键两端都接着单片机IO口,如果我们要使用某个按键就先设置按键一段IO为低电平 ,然后读取另一端IO口电平状态 。矩阵键盘的原理就是键盘扫描,按照扫描的方式可以分为列扫描行扫描

2.2.1 列扫描

以下图为例,设置第二列的按键的一端为低电平(P42=0;),然后读取另一端的按键电平状态,如果读取到低电平就说明哪个按键被按下。例如读取P30口,如果P30==0,那么S11被按下。

2.2.2 行扫描

类似的,设置第一行的按键的一端为低电平(P30=0;),然后读取另一端的按键电平状态,如果读取到低电平就说明哪个按键被按下。例如读取P42口,如果P42==0,那么S11被按下。

2.2.3 代码实现(行扫描实现)

c 复制代码
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;

void delayForKeyboard()		//@12.000MHz
{
	unsigned char i, j;

	i = 234;
	j = 115;
	do
	{
		while (--j);
	} while (--i);
}

void keyBoard(){
	R1=0;R2=R3=R4=1;			// 设置第一行按键一段为低电平,其他行(hang)为高电平
	C1=C2=C3=C4=1;				// 将按键另一端设置为高电平(上拉)
	if(C1==0){					// 读取按键状态
		delayForKeyboard();		// 延时20ms,按键消抖
		if(C1==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C2==0){
		delayForKeyboard();
		if(C2==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C3==0){
		delayForKeyboard();
		if(C3==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C4==0){
		delayForKeyboard();
		if(C4==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	
	R2=0;R1=R3=R4=1;			// 设置第二行按键一段为低电平,其他行(hang)为高电平
	C1=C2=C3=C4=1;
	if(C1==0){
		delayForKeyboard();
		if(C1==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C2==0){
		delayForKeyboard();
		if(C2==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C3==0){
		delayForKeyboard();
		if(C3==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C4==0){
		delayForKeyboard();
		if(C4==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	
	R3=0;R1=R2=R4=1;			// 设置第三行按键一段为低电平,其他行(hang)为高电平
	C1=C2=C3=C4=1;
	if(C1==0){
		delayForKeyboard();
		if(C1==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C2==0){
		delayForKeyboard();
		if(C2==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C3==0){
		delayForKeyboard();
		if(C3==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C4==0){
		delayForKeyboard();
		if(C4==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	
	R4=0;R1=R3=R3=1;			// 设置第四行按键一段为低电平,其他行(hang)为高电平
	C1=C2=C3=C4=1;
	if(C1==0){
		delayForKeyboard();
		if(C1==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C2==0){
		delayForKeyboard();
		if(C2==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C3==0){
		delayForKeyboard();
		if(C3==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
	else if(C4==0){
		delayForKeyboard();
		if(C4==0){
			//......			// 在这里编写按下按键你想要完成的任务
		}
	}
}

三、矩阵键盘注意事项

3.1 为什么要设置C1=C2=C3=C4=1

为什么要设置C1=C2=C3=C4=1,原因在于51系列单片机的I/O端口设计为双向的,当没有指明IO的状态时,我们不知道IO口是处于高电平还是低电平,处于一种不稳定的状态 ,举个例子,如果不指定IO为高电平,那么这个时候由于之前的程序设置IO的状态不确定 导致按键还没被按下IO就为低电平,这时候我们读取到的按键状态就是不正确的,所以需要我们指定它默认为高电平,然后才能通过读取IO判断按键是否按下。

3.2 按键消抖

按键抖动是由于按键的机械特性引起的,解决办法可以分为硬件消抖和软件消抖。
这个问题有很多人已经总结了,我就不再赘述。

【单片机】按键消抖及原理(硬件和软件方法详解)

相关推荐
学习路上_write3 分钟前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
非概念8 分钟前
stm32学习笔记----51单片机和stm32单片机的区别
笔记·stm32·单片机·学习·51单片机
jjjxxxhhh1232 小时前
FPGA,使用场景,相比于单片机的优势
单片机·嵌入式硬件·fpga开发
无敌最俊朗@2 小时前
stm32学习之路——八种GPIO口工作模式
c语言·stm32·单片机·学习
EterNity_TiMe_2 小时前
【论文复现】STM32设计的物联网智能鱼缸
stm32·单片机·嵌入式硬件·物联网·学习·性能优化
changingshow3 小时前
Arduino IDE Windows 系统 离线安装 esp32 开发板 亲测好用。
单片机·嵌入式硬件
编码小袁9 小时前
蓝桥杯:编程爱好者的试炼场
职场和发展·蓝桥杯
Chervin12 小时前
Windows,虚拟机Ubuntu和开发板三者之间的NFS服务器搭建
linux·单片机·ubuntu·arm
白-胖-子15 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-奇数序列排序
c++·算法·蓝桥杯·等考·13级
电子工程师UP学堂15 小时前
用单片机MSP430设计一个太阳能实战项目,能够详细的设计出它的硬件和软件系统
单片机