单片机原理及应用:独立式键盘控制LED与多功能按键识别

本文主要是介绍单片机原理及应用:独立式键盘控制LED与多功能按键识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天来介绍另一个外设——按键与LED的配合工作,与开关不同,按键需要注意消除抖动带来的影响,代码逻辑也会更复杂一写,下面先为大家介绍独立式键盘的相关知识。

单片机的独立式键盘指的是一种不依赖于计算机或其他外部设备的键盘输入方式,由若干按键按照一定的规则组成,每一个按键实质就是一个按钮开关。而独立式键盘的各键相互独立,每个按键各接一条I/O口线,通过检测I/O输入线的电平状态,很容易地判断哪个按键被按下。

当无键按下时,通过上拉电阻,P0的 8 个I/O口引脚被上拉为高电平“ 1 ”;如果有键按下,将使对
应该键接的I/O口引脚,通过该键接地,信息为“0 ” 。
与开关不同,机械式按键在按下或释放时,由于机械弹性作用的影响 常伴随一定时间的触点机械抖 动, 然后才能稳定下来。 若有抖动,按键按下会被错误地认为是多次操作。 所以我们要在代码中执行消抖程序。
消抖程序的原理是 在检测到有按键按下时执行一个10ms左右的延时程序;再确认该键电平是否仍保持闭合状态电平,若仍保持闭合状态电平,则确认该键处于闭合状态,从而消除抖动的影响。我现在以8位独立式键盘控制LED灯点亮作为案例,代码如下:
#include <reg52.h>     
void delay10ms(void)     //延时消抖程序,第三种delay,数量级为5~10k
{ unsigned char i,j; for(i=40;i>0;i--) for(j=250;j>0;j--); 
} 
void main()         
{unsigned char x;P1=0xff;          //led全灭x=0;while(1){while(x==0)     //无键被按下执行死循环,有键被按下才往下走{x=P0;             //第一次进入循环给x赋值,没有异常再取反恢复原值x=~x;}delay10ms();      //消抖x=P0;               //再次读键盘状态x=~x;if(x==0) continue;//如果无键按下则认为是按键抖动,重新扫描键盘 switch(x)           //根据键值点亮对应的发光二极管{case 0x01: P1=0xfe; break;    //点亮第一个发光二极管case 0x02: P1=0xfd; break;    //点亮第二个发光二极管case 0x04: P1=0xfb; break;   //点亮第三个发光二极管case 0x08: P1=0xf7; break;   //点亮第四个发光二极管case 0x10: P1=0xef; break;   //点亮第五个发光二极管case 0x20: P1=0xdf; break;    //点亮第六个发光二极管case 0x40: P1=0xbf; break;   //点亮第七个发光二极管case 0x80: P1=0x7f; break;    //点亮第八个发光二极管default: break;}}
}
#include<reg52.h> sbit S1=P1^0;        		//将S1位定义为P1.0引脚
sbit S2=P1^1;        		//将S2位定义为P1.1引脚
sbit S3=P1^2;        		//将S3位定义为P1.2引脚
sbit S4=P1^3;        		//将S4位定义为P1.3引脚unsigned char keyval;  		//定义键值储存变量单元void led_delay(void);//第一种延时函数,流水灯延时
void delay10ms(void);//按键消抖
void key_scan(void)	;//键盘扫描
void ledstate();	 //switch封装,也可以写在主函数中
//void key(void);		 
//灯的四种变化
void forward(void);	//从上至下
void backward(void);//从下至上
void Alter(void);	//高四位与低四位互闪
void blink (void);	//全闪void main(void)  	
{keyval=0;       //键值初始化为0while(1)
{		//key();key_scan();  			//调用键盘扫描函数ledstate();				//调用灯光执行程序}
}
void key_scan(void)			//函数功能:键盘扫描
{P1=0xff;if((P1&0x0f)!=0x0f)   		//检测到有键按下{delay10ms();  		//延时10ms再去检测if(S1==0) keyval=1;    		//按键k1被按下if(S2==0) keyval=2;     		//按键k2被按下if(S3==0) keyval=3;     		//按键k3被按下if(S4==0) keyval=4;     		//按键k4被按下	}}
void forward(void)	//函数功能:正向流水点亮LED
{P3=0xfe; led_delay();        		//LED0亮P3=0xfd; led_delay();         		//LED1亮P3=0xfb; led_delay();         		//LED2亮P3=0xf7; led_delay();         		//LED3亮P3=0xef; led_delay();         		//LED4亮P3=0xdf; led_delay();         		//LED5亮P3=0xbf; led_delay();         		//LED6亮P3=0x7f; led_delay(); 				//LED7亮} 
void backward(void)		//函数:反向流水点亮LED
{P3=0x7f; led_delay();        		//LED7亮P3=0xbf; led_delay();        		//LED6亮P3=0xdf; led_delay();         		//LED5亮P3=0xef; led_delay();          		//LED4亮P3=0xf7; led_delay();         		//LED3亮P3=0xfb; led_delay();          		//LED2亮P3=0xfd; led_delay();        		//LED1亮P3=0xfe; led_delay();       		//LED0亮
}
void Alter(void)		//函数:交替点亮高4位与低4位LED
{P3=0x0f;led_delay();P3=0xf0;led_delay();
}
void blink (void)		//函数:闪烁点亮LED
{P3=0xff;led_delay();P3=0x00;led_delay();
} 
void led_delay(void)			//函数:延时
{unsigned char i,j;for(i=0;i<220;i++)for(j=0;j<220;j++);
}
void delay10ms(void)	//函数:软件消抖延时10ms
{unsigned char i,j;for(i=0;i<100;i++)for(j=0;j<100;j++);
}
void ledstate()
{switch(keyval){case 1:forward();	//键值为1,调用正向流水点亮函数break;case 2:backward();	//键值为2,调用反向流水点亮函数break;case 3:Alter();	//键值为3,调用高、低4位交替点亮函数break;case 4:blink ();	//键值为4,调用闪烁点亮函数break;}
} 
//键盘扫描和灯光操作可以合并为一个函数,还能省下sbit命名
/*void key(void)
{
P1=0xff;
if((P1&0x0f)!=0x0f)
{delay10ms();
switch(~(P1&0x0f)){case 0xf1:forward();	//键值为1,调用正向流水点亮函数break;case 0xf2:backward();	//键值为2,调用反向流水点亮函数break;case 0xf4:Alter();	//键值为3,调用高、低4位交替点亮函数break;case 0xf8:blink ();	//键值为4,调用闪烁点亮函数break; }}} */

 这里给大家展示了两个程序,第一个实例就是先检测按键的状态,然后用switch语句判断哪个键被按下,之后执行相应的点亮程序。第二个实例是把之前学过的LED点亮状态都封装成函数,然后在主程序里根据键盘的值执行相应的操作。

实例仿真1

实例仿真2

有两点需要注意

  1. delay10ms是到目前为止我们学习的第三个延时函数,作用是消抖,数量级为5~10k。 
  2. 为了节省空间,按键个数一般少于8个,需要用按位与“&”屏蔽不需要的引脚来防止异常电位

按键控制LED点亮

下面是多功能按键控制LED的案例,与前文不同,该案例是通过记录按键按下的次数来改变LED状态的。,在这种情况下,就需要考虑按住按键不松手的情况,以免一直进行灯光切换。

#include <reg52.h>
sbit key=P3^0; 
unsigned char ID; 
void delay10ms(void) 
{ unsigned char i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); 
} 
void keyonoff()
{if(key==0) 		  //检测按键被按下{delay10ms();  //去抖if(key==0) { ID++;while(key==0); 	//防止按住不松手,等待按键释放  if(ID==4) { ID=0; } } }
}
void displayled()
{switch(ID) {case 0: P1=0x0e;break; 	//点亮D1,熄灭其它LEDcase 1: P1=0x0d;break; 	//点亮D2,熄灭其它LEDcase 2: P1=0x0b;break; 	//点亮D3,熄灭其它LEDcase 3: P1=0x07;break; 	//点亮D4,熄灭其它LED}  	//end switch
}
void main(void) 
{ 	P1=0x0f;while(1) { //按键识别程序keyonoff();//根据按键结果,输出程序displayled();}    	
}      		

这个模式在没有按键被按下的情况下点亮第一个LED作为标志,大家也可以自行更改case的值设置双击或全灭等操作,或者把前文封装的函数放在switch里执行更多的功能。

多功能按键控制LED点亮

 以上就是按键控制LED灯点亮的过程,之后会介绍按键控制数码管显示的案例。谢谢大家。

这篇关于单片机原理及应用:独立式键盘控制LED与多功能按键识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/562872

相关文章

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat