单片机原理及应用:独立式键盘控制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循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

SpringShell命令行之交互式Shell应用开发方式

《SpringShell命令行之交互式Shell应用开发方式》本文将深入探讨SpringShell的核心特性、实现方式及应用场景,帮助开发者掌握这一强大工具,具有很好的参考价值,希望对大家有所帮助,如... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

MySQL 分区与分库分表策略应用小结

《MySQL分区与分库分表策略应用小结》在大数据量、复杂查询和高并发的应用场景下,单一数据库往往难以满足性能和扩展性的要求,本文将详细介绍这两种策略的基本概念、实现方法及优缺点,并通过实际案例展示如... 目录mysql 分区与分库分表策略1. 数据库水平拆分的背景2. MySQL 分区策略2.1 分区概念

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印