51单片机嵌入式开发:5、按键、矩阵按键操作及protues仿真

按键、矩阵按键操作及protues仿真

  • 1 按键介绍
    • 1.1 按键种类
    • 1.2 按键应用场景
  • 2 按键电路
  • 3 按键软件设计
    • 3.1 按键实现
    • 3.2 按键滤波方法
    • 3.3 矩阵按键软件设计
    • 3.4 按键Protues 仿真
  • 4 按键操作总结


提示

1 按键介绍

1.1 按键种类

按键是一种用于控制电子设备或电路连接和断开的按钮或开关。它们通常具有两个状态:打开和关闭。下面是一些常见的开关按键介绍:

  1. 按下开关(Push Button Switch):这是一种简单的按键,按下按钮可以连接电路,释放按钮则断开电路。它们通常用于控制设备的开关或触发特定功能。
  2. 切换开关(Toggle Switch):切换开关是一种具有固定位置的开关,可以手动切换其状态。它们通常有两个或更多个固定位置(例如打开和关闭),通过切换开关的位置来连接或断开电路。
  3. 滑动开关(Slide Switch):滑动开关是一种通过滑动按钮来改变状态的开关。它们通常具有两个位置,通过将滑块从一个位置滑动到另一个位置来连接或断开电路。
  4. 拨动开关(Toggle Switch):拨动开关是一种通过拨动按钮来改变状态的开关。它们通常具有一个中间位置和两个极端位置,通过将按钮从一个位置拨到另一个位置来连接或断开电路。
  5. 按钮开关(Button Switch):按钮开关类似于按下开关,但通常具有弹簧机制,释放按钮后会自动返回到初始位置。它们常用于需要按住按钮来保持连接状态的应用,而松开按钮则断开电路。
  6. 电子开关(Electronic Switch):电子开关是一种使用电子元件(如晶体管或继电器)来控制电路连接和断开的开关。它们可以通过电信号或其他触发方式来控制开关状态

1.2 按键应用场景

一些机械按键的应用场景:

  1. 电脑键盘:机械键盘在电脑领域广泛应用。由于机械按键提供更好的触感和键程,使得打字和游戏体验更加舒适和精准。
  2. 游戏设备:机械按键在游戏机、游戏手柄和游戏机械键盘中得到广泛应用。机械按键的触感反馈和快速响应时间有助于提高游戏的控制性能。
  3. 工业控制设备:机械按键耐用性强,适用于工业控制设备中需要频繁操作的场景,如机械控制面板、机器人控制台等。
  4. 通信设备:机械按键可以用于手机、电话、对讲机等通信设备中,提供更好的按键触感和可靠性。
  5. 音频设备:机械按键在音频设备中使用广泛,如调音台、音频控制面板、音乐键盘等。
  6. 医疗设备:机械按键在医疗设备中的应用很常见,如医疗仪器、手术台控制面板等,机械按键的稳定性和可靠性对医疗设备的正常运行至关重要。
  7. 汽车和航空设备:机械按键可以用于汽车控制面板、飞机仪表盘等需要高可靠性和耐用性的场景。
    机械按键的耐用性、触感和可靠性使其成为许多领域中首选的选择。无论是为了提高工作效率,还是为了提供更好的用户体验,机械按键都在许多应用场景中得到广泛应用。

2 按键电路

开发板上的按键电路原理图如下所示,J11用于控制0/4/8/按钮处于矩阵键盘中还是独立按键中,16个按键用一组P3X端口控制。

在这里插入图片描述

开发板的按键实物如图所示
在这里插入图片描述

在这里插入图片描述

3 按键软件设计

3.1 按键实现

首先我们实现独立按键,将J11使用跳线帽把2.3两个短接,这样就能实现0/4/8/C按键的独立使用。
1、软件工程,我们新建两个文件,分别为c51_key.c和c51_key.h,在c51_key.c中应用includes.h,在includes.h包含c51_key.h,并将两个共文件添加到工程中如图所示。

在这里插入图片描述

因为要显示按键数值,我们用前面的数码管实现数据显示。
显示函数如下所示。

/********************************************************
函数名称:sys_keynum_ledon
函数功能:显示按键数值
入口参数:按键数值
出口参数:
修    改:
内    容:
********************************************************/
void sys_keynum_ledon(unsigned char num)
{
	//根据原理图,将P0口全部输出高电平,P2选择0号数码管
	P0=EL[num];//取显示数据,段码
	P2=0;  	//取位码
}

在c51_key.c中,实现按键检测

bit key1=0;   //定义按键位置
bit key2=0;
bit key3=0;
bit key4=0;


/********************************************************
函数名称:sys_key_single
函数功能:按键检测
入口参数:
出口参数:按键数值
修    改:
内    容:
********************************************************/
static unsigned char key1_history = 0;//缓存上一次按键的结果
unsigned char sys_key_single(void)
{
	key1=P30;   //定义按键位置
	key2=P31;
	key3=P32;
	key4=P33;

	if(!key1)  //按下相应的按键,数码管显示相应的码值
	{
		key1_history = 1;
		return 1;
	}
	else if(!key2)
	{
		key1_history = 2;
		return 2;
	}
	else if(!key3)
	{
		key1_history = 3;
		return 3;
	}
	else if(!key4)
	{
		key1_history = 4;
		return 4;
	}
	else
	{
		return key1_history;
	}
	
}

主程序main中引用:

#include "includes.h"



/*------------------------------------------------
                    延时子程序
------------------------------------------------*/
void delay(unsigned int cnt) 
{
 while(--cnt);
}

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
	//8个指示灯的操作
	sys_led();
	sys_led_test();
	sys_led_test1();
	
	sys_ledtube_on1();
	sys_ledtube_on2();
	
	//主循环中添加其他需要一直工作的程序
	while (1)
	{
		sys_keynum_ledon(sys_key_single());
	}
}

3.2 按键滤波方法

/********************************************************
函数名称:sys_key_single
函数功能:按键检测,带有消抖策略
入口参数:
出口参数:按键数值
修    改:
内    容:
********************************************************/
static unsigned char key1_history = 0;//缓存上一次按键的结果
unsigned char sys_key_single(void)
{
	key1=P30;   //定义按键位置
	key2=P31;
	key3=P32;
	key4=P33;

	if(!key1)  //按下相应的按键,数码管显示相应的码值
	{
		delay(1000);
		if(!key1)
		{
			key1_history = 1;
			return 1;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key2)
	{
		delay(1000);
		if(!key2)
		{
			key1_history = 2;
			return 2;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key3)
	{
		delay(1000);
		if(!key3)
		{
			key1_history = 3;
			return 3;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key4)
	{
		delay(1000);
		if(!key4)
		{
			key1_history = 4;
			return 4;
		}
		else
		{
			return key1_history;
		}
	}
	else
	{
		return key1_history;
	}
	
}

3.3 矩阵按键软件设计

// 显示段码值01234567,可对应原理图查看显示不同图形对应的引脚高点电平配置状态

unsigned char const EL[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,\
		                  	 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
unsigned char sys_key_board(void)
{
	unsigned char key = 0x00;
	unsigned char num = 0x00;
	key=keyscan();  //调用键盘扫描
	if(key == 0xFF)
	{
		num = key1_history;
	}
	else
	{
		switch(key)
		{
			case 0xee:num = 0x0;break;//0按下相应的键显示相对应的码值
			case 0xde:num = 0x1;break;//1 按下相应的键显示相对应的码值 
			case 0xbe:num = 0x2;break;//2
			case 0x7e:num = 0x3;break;//3
			case 0xed:num = 0x4;break;//4
			case 0xdd:num = 0x5;break;//5
			case 0xbd:num = 0x6;break;//6
			case 0x7d:num = 0x7;break;//7
			case 0xeb:num = 0x8;break;//8
			case 0xdb:num = 0x9;break;//9
			case 0xbb:num = 0xA;break;//a
			case 0x7b:num = 0xB;break;//b
			case 0xe7:num = 0xC;break;//c
			case 0xd7:num = 0xD;break;//d
			case 0xb7:num = 0xE;break;//e
			case 0x77:num = 0xF;break;//f
			default:num = key1_history; break;
		}
		
		key1_history = num;
	}
	return num;
}


/*------------------------------------------------
              键盘扫描程序
------------------------------------------------*/
unsigned char keyscan(void)  //键盘扫描函数,使用行列反转扫描法
{
	unsigned char cord_h,cord_l;//行列值中间变量
	P3=0x0f;            //行线输出全为0
	cord_h=P3&0x0f;     //读入列线值
	if(cord_h!=0x0f)    //先检测有无按键按下
	{
		delay(100);        //去抖
		if(cord_h!=0x0f)
		{
			cord_h=P3&0x0f;  //读入列线值
			P3=cord_h|0xf0;  //输出当前列线值
			cord_l=P3&0xf0;  //读入行线值
			return(cord_h+cord_l);//键盘最后组合码值
		}
	}
	return(0xff);     //返回该值
}

3.4 按键Protues 仿真

独立按键显示结果,拨码开关,将按键一端接地

在这里插入图片描述

矩阵键盘按键仿真:在这里插入图片描述

4 按键操作总结

在单片机应用中,按键检测的可靠性设计对于确保正确的输入和稳定的系统操作至关重要。以下是一些提高按键检测可靠性的设计原则:

  1. 消除按键抖动:按键抖动是指按键在按下或释放时产生的短暂的不稳定信号。为了消除抖动,可以采用硬件或软件的抖动消除方法。硬件方面,可以使用外部电容或RC网络来滤除抖动。软件方面,可以使用软件延时或状态机来稳定按键信号。
  2. 使用外部上拉/下拉电阻:通过使用外部上拉或下拉电阻连接到按键引脚,可以确保按键在未按下时保持稳定状态。这样做可以防止未按下按键时的浮动信号。
  3. 延时和去抖动算法:在软件中实施适当的延时和去抖动算法可以提高按键检测的可靠性。延时可以确保稳定的按键状态,并避免误触发。去抖动算法可以滤除按键抖动,确保只检测到有效的按键操作。
  4. 多重检测和确认:为了提高可靠性,可以使用多重按键检测和确认机制。例如,可以使用软件定时器或中断来周期性地检测按键状态,并通过多次确认来确保按键的有效触发。
  5. 输入缓冲区和状态机:使用输入缓冲区可以存储按键输入,然后使用状态机来处理输入。状态机可以跟踪按键状态和处理按键事件,以确保按键操作的正确性和稳定性。
  6. 电源和地线的干扰隔离:为了防止电源干扰和地线回流对按键信号的影响,可以采取适当的隔离措施。例如,使用独立的电源和地线平面,或者使用滤波器来减少干扰。
  7. 硬件和软件的容错机制:设计容错机制可以在出现错误或异常情况时保护按键输入的可靠性。例如,可以使用冗余检测、校验和检测、错误处理和恢复机制等。
    总的来说,可靠的按键检测设计需要综合考虑硬件和软件方面的各种因素,并根据具体应用场景进行适当的优化和调整。通过合理的设计和实施,可以确保按键的稳定性、准确性和可靠性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLM之RAG实战(四十一)| 使用LLamaIndex和Gemini构建高级搜索引擎

Retriever 是 RAG(Retrieval Augmented Generation)管道中最重要的部分。在本文中,我们将使用 LlamaIndex 实现一个结合关键字和向量搜索检索器的自定义检索器,并且使用 Gemini大模型来进行多个文档聊天。 通过本文,我…

Face_recognition实现人脸识别

这里写自定义目录标题 欢迎使用Markdown编辑器一、安装人脸识别库face_recognition1.1 安装cmake1.2 安装dlib库1.3 安装face_recognition 二、3个常用的人脸识别案例2.1 识别并绘制人脸框2.2 提取并绘制人脸关键点2.3 人脸匹配及标注 欢迎使用Markdown编辑器 本文基于face_re…

Python 安装Numpy 出现异常信息

文章目录 前言一、包源二、安装完成异常 前言 安装Python Numpy包出现异常问题 Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. 一、包源 使用默认的包源出现超时异常,改用清华包源 pip …

娱乐圈幕后揭秘孙俪天选打工人

【娱乐圈幕后揭秘:孙俪“天选打工人”背后的热议风暴】在聚光灯下光鲜亮丽的娱乐圈,每一位明星的日常备受瞩目。近日,实力派演员孙俪在社交媒体上分享了一段片场棚拍的趣事,本是无心之举,意外引爆了网络热议的导火索。…

这几类人,千万不要买纯电车

文 | AUTO芯球 作者 | 响铃 纯电车的冤大头真是太多了, 我之前劝过,有些人不适合买纯电车, 你们看,果然吧,麦卡锡最近的一份报告就披露了 去年啊,22%的人在买了电车后后悔了, 这些人说了&a…

面试常考题---128陷阱(详细)

1.问题引入 分别引入了int和Integer变量,并进行比较 int b 128; int b1 128;Integer d 127; Integer d1 127;Integer e 128; Integer e1 128;System.out.println(bb1); System.out.println(dd1); System.out.println(ee1); System.out.println(e.equals(e1)…

kafka系列之offset超强总结及消费后不提交offset情况的分析总结

概述 每当我们调用Kafka的poll()方法或者使用Spring的KafkaListener(其实底层也是poll()方法)注解消费Kafka消息时,它都会返回之前被写入Kafka的记录,即我们组中的消费者还没有读过的记录。 这意味着我们有一种方法可以跟踪该组消费者读取过的记录。 如前…

【力扣高频题】014.最长公共前缀

经常刷算法题的小伙伴对于 “最长”,“公共” 两个词一定不陌生。与此相关的算法题目实在是太多了 !!! 之前的 「动态规划」 专题系列文章中就曾讲解过两道相关的题目:最长公共子序列 和 最长回文子序列 。 关注公众…

跨境电商代购系统与电商平台API结合的化学反应

随着全球化的不断推进和互联网技术的飞速发展,跨境电商已成为国际贸易的重要组成部分。跨境电商代购系统作为连接国内外消费者与商品的桥梁,不仅为消费者提供了更多元化的购物选择,也为商家开辟了更广阔的市场空间。在这一过程中,…

如何将heic转jpg格式?四种图片格式转换方法【附教程】

如何把heic转jpg格式?heic是用于存储静态图像和图形的压缩格式,旨在以更小的文件大小保持高质量的图像。HEIC格式自iOS 11和macOS High Sierra(10.13)内测开始,被苹果设置为图片存储的默认格式,广泛应用于i…

【VUE基础】VUE3第四节—核心语法之computed、watch、watcheffect

computed 接受一个 getter 函数&#xff0c;返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。 创建一个只读的计算属性 ref&#xff1a; <template><div cl…

【一次成功】清华大学和智谱AI公司的ChatGLM-4-9B-Chat-1M大模型本地化部署教程

【一次成功】清华大学和智谱AI公司的ChatGLM-4-9B-Chat-1M大模型本地化部署教程 一、环境准备二、ChatGLM-4-9B-Chat-1M简介三、模型下载2.1 安装Git LFS2.2 初始化仓库2.3 同步Git文件2.4 拉取文件2.5 下载完毕 四、python和源码安装与下载4.1 安装python4.2 下载源码4.3 安装…

Monaco 中添加 CodeLens

CodeLens 会在指定代码行上添加一行可点击的文字&#xff0c;点击时可以触发定义的命令&#xff0c;效果如下&#xff1a; 通过调用 API 注册 LensProvider&#xff0c;点击时触发 Command&#xff0c;首先要注册命令&#xff0c;通过 editor.addCommand () 方法进行注册。三个…

韦东山嵌入式linux系列-LED驱动程序

之前学习STM32F103C8T6的时候&#xff0c;学习过对应GPIO的输出&#xff1a; 操作STM32的GPIO需要3个步骤&#xff1a; 使用RCC开启GPIO的时钟、使用GPIO_Init函数初始化GPIO、使用输入/输出函数控制GPIO口。 【STM32】GPIO输出-CSDN博客 这里再看看STM32MP157的GPIO引脚使用…

高通开发系列 - 使用QFIL工具单刷某个镜像文件

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 返回:专栏总目录 目录 背景过程记录背景 有时候设备中刷的是user版本,无法使用fastboot刷单个镜像,这个时候该怎么办呢? 要解决在user…

Websocket在Java中的实践——整合Rabbitmq和STOMP

大纲 Rabbitmq开启STOMP支持 服务端依赖参数参数映射类配置类逻辑处理类 测试测试页面Controller测试案例 在《Websocket在Java中的实践——STOMP通信的最小Demo》一文中&#xff0c;我们使用enableSimpleBroker启用一个内置的内存级消息代理。本文我们将使用Rabbitmq作为消息代…

计算机类期刊横纵向对比

备注&#xff1a;综合影响因子更具针对性&#xff0c;将科技类期刊和人文社科期刊的影响力考虑&#xff0c;更加聚焦于某一特定科学领域&#xff1b;复合影响因子是基于期刊、学位论文、以及会议论文等多个类型的文献作为计算基础。 两者都是通过前两年发表的可被引文献在统计年…

pandas数据分析(8)

描述性统计量和数据聚合 描述性统计量 描述性统计量通过量化数据来概括数据集。DataFrame和Series可以通过sum、mean、count等方法来获取各种描述性统计量。在默认情况下会按照axis0返回一个Series&#xff0c;也就是说会得到一个有关列的统计量&#xff1a; 如果要计算行的统…

鼠标宏怎么设置?6款鼠标自动点击器强推,游戏玩家专用!(2024全)

随着电子游戏和日常应用的不断发展&#xff0c;我们经常会遇到一些重复性的任务或操作。而在这种情况下&#xff0c;鼠标宏以其自动化的特点成为了许多玩家和使用者的利器之一。如果你正在寻找如何设置鼠标宏来简化操作并提高效率&#xff0c;那么你来对地方了。在本文中&#…

理解算法复杂度:空间复杂度详解

引言 在计算机科学中&#xff0c;算法复杂度是衡量算法效率的重要指标。时间复杂度和空间复杂度是算法复杂度的两个主要方面。在这篇博客中&#xff0c;我们将深入探讨空间复杂度&#xff0c;了解其定义、常见类型以及如何进行分析。空间复杂度是衡量算法在执行过程中所需内存…