普中51-独立按键实验

news2024/12/24 10:34:10

独立按键实验

通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号

如下图所示:
在这里插入图片描述
由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时 也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间 的长短由按键的机械特性决定的,一般为 5ms 到 10ms。按键稳定闭合时间的长 短则由操作人员的按键动作决定的,一般为零点几秒至数秒。按键抖动会引起按 键被误读多次。为了确保 CPU 对按键的一次闭合仅作一次处理,必须进行消抖。

按键消抖有两种方式,一种是硬件消抖,另一种是软件消抖。为了使电路更 加简单,通常采用软件消抖。我们开发板也是采用软件消抖,一般来说一个简单 的按键消抖就是先读取按键的状态,如果得到按键按下之后,延时 10ms,再次 读取按键的状态,如果按键还是按下状态,那么说明按键已经按下。其中延时 10ms 就是软件消抖处理,至于硬件消抖,大家可以百度了解下,网上都有非常 详细的介绍。

这里给大家列出单片机常用的软件去抖动方法:

  1. 先设置 IO 口为高电平(由于开发板 IO 都有上拉电阻,所以默认 IO 为高 电平)。

  2. 读取 IO 口电平确认是否有按键按下。

  3. 如有 IO 电平为低电平后,延时几个毫秒。

  4. 再读取该 IO 电平,如果仍然为低电平,说明按键按下。

  5. 执行按键控制程序。

独立按键电路构成是由各个按键的一个管脚连接在一起接地,按键其他引脚 分别接到单片机 IO 口。

我们知道单片机的 IO 口既可作为输出也可作为输入使用,当检测按键时用 的是它的输入功能,独立按键的一端接地, 另一端与单片机的 I/O 口相连,开 始时先给该 IO 口赋一高电平,然后让单片机不断地检测该 I/O 口是否变为低 电平,当按键闭合时,即相当于该 I/O 口通过按键与地相连,变成低电平,程 序一旦检测到 I/O 口变为低电平则说明按键被按下,然后执行相应的指令。

原理图如下:
在这里插入图片描述

/*
*独立按键实验
*效果:通过按键1控制LED1,进行暗亮操作
*/
#include "reg52.h"

typedef unsigned int u16;//对系统的默认数据类型重新命名
typedef unsigned char u8;

//对独立按键管脚进行定义
sbit KEY_PRESS1 = P3^1;
sbit KEY_PRESS2 = P3^0;
sbit KEY_PRESS3 = P3^2;
sbit KEY_PRESS4 = P3^3;

//对LED1进行定义
sbit LED1 = P2^0;

//使用宏定义独立按键按下的键值
#define KEY_PRESS1_value 1
#define KEY_PRESS2_value 2
#define KEY_PRESS3_value 3
#define KEY_PRESS4_value 4
#define UN_PRESS_value 0


/*
*延时函数:当ten_us=1时延时10us	
*作用:进行消抖
*/
void delay_10us(u16 ten_us){
	
	while(ten_us--);

}

/*
*键位检查函数: model = 0 时单次扫描 model= 1时连续扫描
*
*作用:检查键位是否已经按下
*/
u8 Key_Scan(u8 model){
		static u8 key = 1;
		if(model){
			//连续扫描模式
			key = 1;
		}
		if (key==1&&(KEY_PRESS1==0||KEY_PRESS2==0||KEY_PRESS3==0||KEY_PRESS4==0)){
			delay_10us(1000);//消抖操作,防止误读
			key = 0;
			if(KEY_PRESS1 == 0){
				//按键1 按下
				return KEY_PRESS1_value;
			}else if (KEY_PRESS2 == 0){
				//按键2 按下
				return KEY_PRESS2_value;
			}else if (KEY_PRESS3 == 0){
				//按键3 按下
				return KEY_PRESS3_value;
			}else if (KEY_PRESS4 == 0){
				//按键4 按下
				return KEY_PRESS4_value;
			}
		}else if(KEY_PRESS1==1&&KEY_PRESS2==1&&KEY_PRESS3==1&&KEY_PRESS4==1){
			key = 1;
		}
		return UN_PRESS_value;
}
/*
*主函数
*/
void main(){
	u8 key = 0;
	while(1){
		key = Key_Scan(0);//调用键位检查函数,单次扫描
		if(key == KEY_PRESS1_value){//判断按键是否为按键1
			LED1 = !LED1;//led灯状态翻转
		}
	}
	
}

key_scan 函数带一个形参 mode,该参数用来设定是否连续扫描按键,如果 mode 为 0,只能操作一次按键,只有当按键松开后才能触发下次的扫描,这样 做的好处是可以防止按下一次出现多次触发的情况。如果 mode 为 1,函数是支 持连续扫描的,即使按键未松开,在函数内部有 if(mode==1)这条判断语句,因 此 key 始终是等于 1 的,所以可以连续扫描按键,当按下某个按键,会一直返 回这 个按键的键值,这样做的好处是可以很方便实现连按操作。函数内的 delay_10us(1000)即为软件消抖处理,通常延时 10ms 即可。

key_scan 函数还带有一个返回值,如果未有按键按下,返回值即为 KEY_UNPRESS,否则返回值即为对应按键的键值,如 KEY1_PRESS、KEY2_PRESS、 KEY3_PRESS、 KEY4_PRESS,这都是程序开头定义好的宏,方便大家理解和使用。 函数内定义了一个 static 变量 key,相当于全局变量,所以该函数不是一个可 重入函数。还有一点要注意的就是该函数按键的扫描是有优先级的,因为函数内 用了 if…else if…else 格式,所以最先扫描处理的按键是 KEY1,其次是 KEY2,然后是 KEY3,最后是 KEY4。如果需要将其优先级设置一样,那么可以全 部用 if 语句。

main 函数中主要就是调用 key_scan 函数用于检测按键,此时传入的 mode 值为 0,表示单次扫描按键,然后将扫描按键的值保存在变量 key 中,最后通过if 判断语句控制 LED1 状态

结束!!!

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

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

相关文章

Windows11系统C盘用户文件夹下用户文件夹为中文,解决方案

说明: 1. 博主电脑为Windows11操作系统,亲测有效,修改后无任何影响,软件都可以正常运行! 2. Windows10系统还不知道可不可行,因为Windows11的计算机管理中没有本地用户和组,博主在csdn上看到很…

华为云云耀云服务器L实例评测|redis漏洞回顾 MySQL数据安全解决 搭建主从集群MySQL 相关设置

前言 最近华为云云耀云服务器L实例上新,也搞了一台来玩,期间遇到过MySQL数据库被攻击的情况,数据丢失,还好我有几份备份,没有造成太大的损失;后来有发现Redis数据库被攻击的情况,加入了redis密…

R语言绘制热图

1、初步绘图 rm(listls())#clear Global Environment setwd(D:/Desktop/0000/code-main/热图)#设置工作路径#加载R包 library (pheatmap) #读取数据 df <- read.table(file"data.txt",sep"\t",row.names 1, headerT,check.namesFALSE) #查看前3行 hea…

STM32WB55开发(5)----调整射频功率

STM32WB55开发----5.调整射频功率 概述硬件准备视频教学样品申请选择芯片型号配置时钟源配置时钟树RTC时钟配置查看开启STM32_WPAN条件配置HSEM配置IPCC配置RTC启动RF开启蓝牙开启串口调试配置蓝牙参数设置工程信息工程文件设置Keil工程配置代码配置射频功率ACI_HAL_SET_TX_POW…

【微信小程序】外卖点餐效果展示

概述 外卖点餐效果展示&#xff0c;左右布局&#xff0c;快速点餐&#xff0c;商家信息展示等...程序是模仿人家的&#xff0c;所以界面没做什么调整&#xff0c;功能是没啥问题&#xff0c;可以正常使用... 详细 直接看效果图&#xff1a; 可以把这个点餐这个功能分为5部分…

docker总结

Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…

SkyWalking9.5.0安装与SpringBoot性能链路监控

文章目录 1、下载安装1.1、安装Elasticsearch存储1.2、安装SkyWalking服务器端 2、监控微服务2.1、监控Spring Boot微服务2.1、监控Spring Cloud Gateway网关 Skywalking是分布式系统的应用程序性能监视工具&#xff0c;专为微服务&#xff0c;云原生架构和基于容器&#xff08…

Windows系统版本下载

1. msdn itellyou&#xff1a;MSDN, 我告诉你 - 做一个安静的工具站 (itellyou.cn) 2. MSDN系统库&#xff0d;致力于原版windows生态服务 (xitongku.com)

苹果电脑Mac系统运行若依框架 RuoYi前后端分离版

苹果电脑Mac系统运行若依框架 RuoYi前后端分离版 若依官网 若依官网 http://doc.ruoyi.vip/ruoyi-vue/ 若依的代码和文档都在里面 demo下载下来后还要下载安装redis,启动redis 一、下载安装redis 在终端输入&#xff1a; brew install redis安装过程将自动为我们安装最新版本…

Promise的链式调用

catch方法 .catch(onRejected) .then(null, onRejected) 链式调用 then方法必定会返回一个新的Promise 可理解为后续处理也是一个任务 新任务的状态取决于后续处理&#xff1a; 若没有相关的后续处理&#xff0c;新任务的状态和前任务一致&#xff0c;数据为前任务的数据 …

K8s的ingress-nginx配置https

文章目录 一、自签证书&&创建ingress规则test-ingress-https.yaml 二、测试https访问 一、自签证书&&创建ingress规则 ## ingress配置https访问&#xff0c;这里使用自签证书实现https访问openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyo…

自动化测试岗位之百度测开面试题分享

1、java常用的异常处理机制&#xff1f; Java常用的异常处理机制有以下几种&#xff1a; 1&#xff09;try-catch-finally 语句&#xff1a;用于捕获和处理异常。将可能抛出异常的代码放在try块中&#xff0c;然后在catch块中处理异常。无论是否发生异常&#xff0c;finally块…

千巡翼X1 让航测无人机更小更轻更高效

利用无人机进行航空摄影测量&#xff0c;已成为测绘外业生产的主要方式&#xff0c;不仅方便快捷&#xff0c;更能全面准确获得成果。近年来&#xff0c;凭借快速高效、机动灵活、安全可靠、低成本等诸多优势&#xff0c;小型多旋翼无人机逐渐成为一些航测项目作业的新利器。 千…

SpringBoot启动方式

SpringBoot启动方式 springboot的启动经过了一些一系列的处理&#xff0c;我们先看看整体过程的流程图 SpringBoot的启动方式 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><…

一文读懂最新的A股交易手续费,建议收藏

为了活跃资本市场&#xff0c;最近政策密集出台&#xff0c;印花税下降50%&#xff0c;交易经手费下降30%。 财政部、税务总局&#xff1a;为活跃资本市场、提振投资者信心&#xff0c;自2023年8月28日起&#xff0c;证券交易印花税实施减半征收 上交所发布《关于调整股票交易…

【C++初阶】C++STL详解(四)—— vector的模拟实现

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C初阶 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 【C初阶】CSTL详解&#xff08;三…

day22集合01

1.Collection集合 1.1数组和集合的区别【理解】 相同点 都是容器,可以存储多个数据 不同点 数组的长度是不可变的,集合的长度是可变的 数组可以存基本数据类型和引用数据类型 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类 1.2集合类体系结构【理解】…

详谈操作系统中的内核态和用户态

不知道大家有没有思考过这样一个问题:什么是处理器&#xff08;CPU&#xff09;的状态&#xff1f;&#x1f914; 其实CPU和人一样,没有执行程序的时候,是没有什么状态的,当它执行的程序是用户程序的时候就叫用户态&#xff0c;当执行的程序是操作系统的代码时就叫系统态或者内…

C++---继承

继承 前言继承的概念及定义继承的概念继承定义继承关系和访问限定符 基类和派生类对象赋值转换继承中的作用域派生类的默认成员函数继承与友元继承与静态成员**多重继承**多继承下的类作用域菱形继承虚继承使用虚基类 支持向基类的常规类型转换 前言 在需要写Father类和Mother…

嵌入式Linux驱动开发(I2C专题)(五)

I2C系统驱动程序模型 参考资料&#xff1a; Linux内核文档: Documentation\i2c\instantiating-devices.rstDocumentation\i2c\writing-clients.rst Linux内核驱动程序示例: drivers/eeprom/at24.c 1. I2C驱动程序的层次 I2C Core就是I2C核心层&#xff0c;它的作用&#xf…