单片机原理及应用:独立式键盘控制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灯点亮的过程,之后会介绍按键控制数码管显示的案例。谢谢大家。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Calibre PEX Hspice Netlist提取步骤(数模芯片提取spice netlist流程)

在数模混合芯片中&#xff0c;通常模拟需要数字模块通过calibre工具来提取Hspice netlist用于功耗仿真。注意这里的spice netlist和做Calibre的spice netlist是不太一样的。 另外在做calibre pex时需要确保当前的design LVS已经pass。否则功耗仿真可能会不准。 Calibre LVS常…

rime中州韵小狼毫 inputShow lua Translator 输入字符透传翻译器

在 rime中州韵小狼毫 help lua Translator 中我们分享了如何使用 lua 脚本定义一个 translator&#xff0c;并以 五笔・拼音 为例引用了该 translator&#xff0c;并且达到了预期的效果。 今天&#xff0c;我们继续通过 lua 脚本为 rime中州韵/小狼毫 输入法打造一个 translat…

JRT控制打印机

本次测试打印机控制和纸张方向控制。 打印机状态 选择打印机 控制纸张 定义纸张 旋转纸张 不旋转纸张 A4

BLE Mesh蓝牙组网技术详细解析之Access Layer访问层(六)

目录 一、什么是BLE Mesh Access Layer访问层&#xff1f; 二、Access payload 2.1 Opcode 三、Access layer behavior 3.1 Access layer发送消息的流程 3.2 Access layer接收消息的流程 3.3 Unacknowledged and acknowledged messages 3.3.1 Unacknowledged message …

php安装扩展event 提示 No package ‘openssl‘ found 解决方法

在使用pecl编译安装最新版event模块的时候提示 No package openssl found , 可是本机是安装了openssl的, 编译时找不到, 大概率就是环境配置的问题了, 增加 OPENSSL_CFLAGS OPENSSL_LIBS环境变量即可解决. 异常提示信息: checking for openssl > 1.0.2... no configure: …

在pycharm中jupyter连接上了以后显示无此库,但是确实已经安装好了某个库,使用python可以跑,但是使用ipython就跑不了

今天遇到一个事情&#xff0c;就是用pycharm的jupyter时&#xff0c;连接不上&#xff0c;后来手动连接上了以后&#xff0c;发现环境好像不对。 一般来说&#xff0c;这里会是python3&#xff0c;所以里面的环境也是普通python的环境&#xff0c;并没有我下载的库&#xff0c;…

Python学习笔记之(一)搭建Python 环境

搭建Python 环境 1. 使用工具准备1.1 Python 安装1.1.1 下载Python 安装包1.1.2 安装Python 1.2 VScode 安装1.2.1 下载VScode安装包1.2.2 给VScode安装Python 扩展 2. 第一次编写Python 程序 本篇文章以Windows 系统为例。 1. 使用工具准备 1.1 Python 安装 1.1.1 下载Pytho…

虹科方案|从困境到突破:TigoLeap方案引领数据采集与优化

导读&#xff1a;在数字化工厂和智能制造的时代&#xff0c;数据已经成为优化机器和流程的关键。然而&#xff0c;如何高效地收集和处理这些数据&#xff0c;特别是在开发、部署和生产阶段&#xff0c;仍是企业面临的一大挑战。虹科TigoLeap平台&#xff0c;作为一款引领行业变…

k8s快速搭建

VMware16Pro虚拟机安装教程VMware16.1.2安装及各版本密钥CentOS7.4的安装包:提取码&#xff1a;lp6qVMware搭建Centos7虚拟机教程 搭建完一个镜像 关机 拍摄一个快照,克隆两个作为子节点 0. 环境准备 在开始之前&#xff0c;部署Kubernetes集群机器需要满足以下几个条件&#…

每周一算法:倍增法查找位置

倍增法 倍增法&#xff08;Binary Lifting&#xff09;&#xff0c;顾名思义&#xff0c;就是利用“以翻倍的速度增长”的思想来解决问题的一类算法。 下面介绍如何使用倍增法在有序的序列中查找满足条件的位置。 题目描述 给定一个单调不降的序列&#xff0c;以及 m m m个…

78 Python开发-多线程FuzzWaf异或免杀爆破

这里写目录标题 本课知识点:学习目的:演示案例:Python开发-简单多线程技术实现脚本Python开发-利用FTP模块实现协议爆破脚本Python开发-配合Fuzz实现免杀异或Shell脚本 涉及资源: 本课知识点: 协议模块使用&#xff0c;Request爬虫技术&#xff0c;简易多线程技术&#xff0c;…

基于EPICS modbus模块的单通道电压监测项目

先介绍在本项目中使用到的硬件&#xff1a; 1&#xff09;开发板&#xff1a;为香橙派Zero2&#xff0c;安装系统如下&#xff1a; Distributor ID: Ubuntu Description: Ubuntu 22.04.2 LTS Release: 22.04 Codename: jammy 2&#xff09; USB转485模块&…