51单片机编程应用(C语言):矩阵键盘

news2024/11/14 14:59:50

16个按键只要8个I/O口,本来16个按键要16个I/O口。

 矩阵键盘可以按行扫描也可以按列扫描,扫描原理很简单,变成之前的独立按键,比如

按行扫描,看原理图如下,我们P17=0,另外三个置1,那么第一行就选中了,另外三行没有选中。

就变成我们熟悉的独立按键了,用独立按键的方式编写即可,检测P13的值是0吗,如果是的,那就s1按下了,检测P12是0吗,如果是的,那s2按下了。

代码如下(按列扫描),而且规定了每个按键的值是多少。


/***键盘扫描函数***/
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}

下面写一个相关的实例吧,比如我们介绍过数码管和矩阵按键了,也讲过数码管了,这两个结合一起使用一下。(51单片机来调试)按了矩阵键盘对应的数,数码管拿两位来显示

代码如下:

#include <REGX52.H>
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//延时子函数
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
	switch(Location)		//位码输出
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];	//段码输出
	Delay(1);				//显示一段时间
	P0=0x00;				//段码清0,消影
}
/***键盘扫描函数***/
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}
void main()
{
	unsigned char keyNumber;
	unsigned char a=0;
	unsigned char b=0;
	while(1)
	{
		keyNumber=MatrixKey();	
		
		if(keyNumber)
		{
            if(keyNumber<10)
			{
				a=0;
				b=keyNumber;
			}
			if(keyNumber>10)
			{
				a=keyNumber/10;
				b=keyNumber%10;
			}
			if(keyNumber==10)
			{
				a=1;
				b=0;
			}
	}
		Nixie(1,a);
		Nixie(2,b);
		Nixie(3,0);
	    Nixie(4,0);
		Nixie(5,0);
		Nixie(6,0);
		Nixie(7,0);
		Nixie(8,0);
	}
}

我是合在一起了的,其实都是我写过的每一个模块,自己可以按之前的博文来分开,

现象如下面视频所示: 

调试结果

 矩阵键盘与动态数码管的结合:

比如,按下哪个键,对应的数字,在数码管上显示。

思路还是蛮简单的,就是把几个模块化合在一起:代码如下

#include <REGX52.H>
//数码管段码表
unsigned char NixieTable[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};

//延时子函数
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
	switch(Location)		//位码输出
	{
		case 1:P0_0=0;P0_1=0;break;//
		case 2:P0_0=0;P0_1=1;break;//选择第1个数码管
		case 3:P0_0=1;P0_1=0;break;//选择第2个数码管
		case 4:P0_0=1;P0_1=1;break;//
	}
	P2=NixieTable[Number];	//段码输出
	Delay(1);				//显示一段时间
	P2=0x00;				//段码清0,消影
}
/***键盘扫描函数***/
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}
void main()
{
	unsigned char keyNumber;
	unsigned char a=0;
	unsigned char b=0;
	while(1)
	{
		keyNumber=MatrixKey();	
		
		if(keyNumber)
		{
            if(keyNumber<10)
			{
				a=0;
				b=keyNumber;
			}
			if(keyNumber>10)
			{
				a=keyNumber/10;
				b=keyNumber%10;
			}
		}
		Nixie(2,a);
		Nixie(3,b);
	    
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1431442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

69.请描述Spring MVC的工作流程?描述一下 DispatcherServlet 的工作流程?

69.请描述Spring MVC的工作流程&#xff1f;描述一下 DispatcherServlet 的工作流程&#xff1f; 核心架构的具体流程步骤如下&#xff1a; 首先用户发送请求——>DispatcherServlet&#xff0c;前端控制器收到请求后自己不进行处理&#xff0c;而是委托给其他的解析器进行…

onnx转换为rknn置信度大于1,图像出现乱框问题解决

前言 环境介绍&#xff1a; 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx&#xff0c;再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn出现置信度大于1&#xff0c;并且图像乱框问题…

速过计算机二级python——第五讲:函数与类库

第五讲&#xff1a;函数与类库 第五讲&#xff1a;函数与类库函数定义实参变量的作用域返回值代码复用 类创建和使用类继承导入类 模块与库概念标准库第三方库 第五讲&#xff1a;函数与类库 函数 定义 函数就是代码块&#xff0c;只不过我们给这个代码块特地进行命名&#…

Fink CDC数据同步(三)Flink集成Hive

1 目的 持久化元数据 Flink利用Hive的MetaStore作为持久化的Catalog&#xff0c;我们可通过HiveCatalog将不同会话中的 Flink元数据存储到Hive Metastore 中。 利用 Flink 来读写 Hive 的表 Flink打通了与Hive的集成&#xff0c;如同使用SparkSQL或者Impala操作Hive中的数据…

python Flask 写一个简易的 web 端程序(附demo)

python Flask 写一个简易的 web 端程序 &#xff08;附demo&#xff09; 介绍简单介绍装饰器 app.route("/") 进阶增加接口设置端口 静态网页核心代码完整代码 介绍 Flask 是一个用于构建 Web 应用程序的轻量级 Python Web 框架。它设计简单、易于学习和使用&#x…

【30秒看懂大数据】数据指标

公众号&#xff1a;知幽科技 PS:本文属专栏第24篇 简单说 数据指标是指对企业经营数据转化为可量化、可衡量、可对比、可预测的一个度量或者维度同称。 举例理解 你在小区门口开了一家馒头店。 开业第一天你算了下一共卖了50个馒头&#xff0c;一共收款100元&#xff0…

今日arXiv最热NLP大模型论文:引入噪声,可提升RAG检索效果超30%??

检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;系统的出现&#xff0c;提高了LLMs回答生成的准确性。它分为两个部分:检索与生成。检索即利用检索器从海量文档中检索出与查询最相关或者最相似的段落&#xff0c;而生成则是LLMs针对混…

幻兽帕鲁客户端存档文件 - 云上备份和恢复教程

本文将详细介绍如何将幻兽帕鲁游戏客户端的存档文件备份至云端&#xff0c;以及如何从云端恢复存档数据至本地。 一、游戏存档备份场景 幻兽帕鲁的游戏进度存储在电脑本地磁盘上&#xff0c;游戏中创建的每个世界都对应一个本地存档文件夹。在玩游戏过程中&#xff0c;客户端…

备战蓝桥杯---搜索(优化1)

显然&#xff0c;我们可以用BFS解决&#xff0c;具体实现与八数码类似&#xff1a; 下面是代码&#xff1a; #include<bits/stdc.h> using namespace std; #define N 3000000 string a,b; int hh,dis[N],cnt; struct node{string u,v; }bian[7]; map<string,int>…

Python flask 表单详解

文章目录 1 概述1.1 request 对象 2 示例2.1 目录结构2.2 student.html2.3 result.html2.4 app.py 1 概述 1.1 request 对象 作用&#xff1a;来自客户端网页的数据作为全局请求对象发送到服务器request 对象的重要属性如下&#xff1a; 属性解释form字典对象&#xff0c;包…

基于微信小程序的旅游景点移动自助导游系统

景点移动自助导游系统用户端要求在系统的安卓手机上可以运行&#xff0c;主要实现了线上查看旅游景点和景点预定等相关信息的查看&#xff0c;并且根据需求进行对管理端&#xff1b;首页、个人中心、用户管理、旅游景点管理、景点类型管理、景点预定管理、旅游路线管理、地图导…

769933-15-5,Biotin aniline,可以合成多种有机化合物和聚合物

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;769933-15-5&#xff0c;Biotin aniline&#xff0c;生物素苯胺&#xff0c;生物素-苯胺 一、基本信息 产品简介&#xff1a;Biotin Aniline&#xff0c;一种具有重要生物学功能的化合物&#xff0c;不仅参与了维生…

使用 Visual Studio Code 在远程计算机上调试 PostgreSQL

使用 Visual Studio Code 在远程计算机上调试 PostgreSQL 1. 概述 PostgreSQL 是一个功能强大的开源关系数据库管理系统&#xff0c;适用于各种应用程序。在开发过程中&#xff0c;调试 PostgreSQL 对于识别和解决问题至关重要。在本博客中&#xff0c;我们将手把手教你使用客…

uniapp 组件封装

1. uniapp 组件封装时间戳格式化为星期 1.1. components/m-week.vue <template><text>{{week}}</text> </template> <script>export default {props: {time: String},mounted(e) {this.week this.getWeek(Number(this.time))},data() {return …

Java设计模式(GOF)-23中设计模式-更新中

推荐&#xff1a;关注 IT技术馆 原文阅读 馆长准备了很多学习资料&#xff0c;其中包含java方面&#xff0c;jvm调优&#xff0c;spring / spring boot /spring cloud &#xff0c;微服务&#xff0c;分布式&#xff0c;前端&#xff0c;js书籍资料&#xff0c;视频资料&#x…

r0下进程保护

简介 SSDT 的全称是 System Services Descriptor Table&#xff0c;系统服务描述符表。这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来。SSDT 并不仅仅只包含一个庞大的地址索引表&#xff0c;它还包含着一些其它有用的信息&#xff0c;诸如地址索引的基地…

数据库管理-第144期 深入使用EMCC-01(20240204)

数据库管理144期 2024-02-04 数据库管理-第144期 深入使用EMCC-01&#xff08;20240204&#xff09;1 用户管理2 配置告警动作3 配置意外事件规则总结 数据库管理-第144期 深入使用EMCC-01&#xff08;20240204&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&am…

打破语言障碍!五个跨境电商必备的实时翻译工具推荐

打破语言障碍&#xff01;随着全球化市场的扩展&#xff0c;语言障碍成为了客户服务领域的一大难题&#xff0c;特别是对于需要出海的企业来说&#xff0c;如何有效地和国外的客户沟通成为了关键。传统的翻译服务往往耗时且成本高昂&#xff0c;无法满足时效性强的客户服务需求…

差分信号:一种提高信号传输质量的神奇方式

在我们的日常生活中&#xff0c;会遇到各种各样的信号传输&#xff0c;比如手机、电视、网络等等。 为什么需要差分信号 在这些信号传输中&#xff0c;我们很多时候使用的是单端信号传输方式。比如使用固定电话打电话时&#xff0c;你有一根信号线和一根地线&#xff0c;电话…

【学习笔记】树上差分总结(点差分/边差分)

一.树上差分的基本概念 1.树上差分的定义 树上差分&#xff0c;顾名思义&#xff0c;意思就是在树上做差分。 至于什么是差分呢&#xff1f;如果不会的同学&#xff0c;可以先看看我的这篇博客:一维,二维差分の详解&#xff08;简单易懂&#xff09;_一维差分-CSDN博客 2.树…