三、键盘检测原理及应用实现

news/2024/11/8 16:37:02/

键盘检测原理及应用实现

视频链接:[3-4] 独立按键控制LED移位_哔哩哔哩_bilibili

对应课程P7-P10

键盘实际上就是一组按键,在单片机的外围电路中,通常用到的按键都是机械弹性开关,当开关闭合时,线路导通,开关断开时,线路断开。单片机系统常见的弹性小按键图示意图如图所示:

image-20221030152126362

弹性小按键被按下时闭合,松开后自动断开;自锁式按键与弹性按键不同,当按下时自锁式按键会闭合且会自动锁柱,只有再次按下时才会弹起断开,自锁式按键示意图如图所示:

image-20221030152535064

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

独立键盘控制LED亮灭

按键的连接方法非常简单,独立按键的原理图如图所示:

image-20221030154114489

当按键被按下时,其触点电压变化过程如下图所示:

image-20221030154438887

由图不难看出,实际波形与理想波形之间是有区别的,实际波形在按键被按下和释放的瞬间都有抖动现象,抖动时间的长短与按键的机械特性有关,一般为5~10ms。通常我们手动按下键然后立即释放,这个动作中稳定闭合的时间超过20ms,这也就是为什么单片机在检测键盘是否按下时都要加上去抖操作了。去抖有专用的去抖电路,也有专用的去抖芯片,但是通常出于成本控制等原因,我们只需要在写程序的时候需延时处理就很容易解决抖动问题。

在编写单片机的键盘检测程序时,通常在检测按下时加入去抖延时,检测松手时就不需要加了。按键检测流程图如图所示:

image-20221030155816371

需要注意的是,在头文件regx52中既包含了寄存器声明也还包含了位声明,如图所示:

image-20221030161243045

关于头文件的不同以代码形式进行简单叙述:

#include <REGX52.H> //#include <REG52.H>则不包含对位寄存器的声明void main
{while(1){//P2=oxFE; 控制P2需要同时操作8位数据从而控制8个LEDP2_0=0;  // 可以单独控制一个LED}
}

为了实现对独立键盘控制LED亮灭,显然需要用判断键盘何时被按下,何时被松开,代码如下:

#include <REGX52.H> //#include <REG52.H>则不包含void main()
{while(1){if(P3_1==0)//通过原理图可知,按键进行这样的连接:S13-RXD-P3.1{           //当检测到P3.1位低电平时(即按键被按下)P2_0=0; //D2亮(最左边的LED亮)}else        //当检测到P3.1位不是低电平时(即按键被释放){P2_0=1;//D2灭}}
}

在上面代码中如P3_1==0,涉及到C51数据运算相关知识,下面给出常用汇总的运算符:

image-20221030165112794

还涉及到if条件语句,基本格式和解释如下图所示:

image-20221030165356594

独立按键控制LED状态

如果想实现独立按键按下之后松开手才亮,再按下按键,灯灭,这该如何实现呢?

上一节已经说了按键抖动现象和去抖的操作,现在结合一张更为具体的图来进行说明:

image-20221030205035557

当按键被检测到按下,此时由于电压存在抖动,在5-10ms,电压会在高电平和低电平反复跳动,如果不进行延时处理,可能会影响按键功能的正常使用,出现误触(实际测试中,程序编译过程中报了警告,上板表现和不加延时看不出差别)。

#include <REGX52.H>void Delay1ms(unsigned int xms)	//延时函数	
{while(xms--){unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);}		
}void main()
{while(1){if(P3_1==0) //检测按键是否按下{Delay1ms(20);//延时20mswhile(P3_1==0)//检测是否松手,松手就跳出循环{}             //另外一种写法,倘若中括号内无内容,可以直接写成:                                       //while(P3_0==0);Delay1ms(20); //延时,松手去抖,书上说检测松手可以不用加延时P2_0=~P2_0; //取反,一开始P2_0默认是高电平,取反之后就是0了}}
}
//现象:按住S1按键,松开后 D2 LED灯亮,再按S1,松开后灯灭。

上述代码使用了while语句,下面简单补充一下while语句的基础知识,在本例中就是使用了while语句实现了检测是否松手:

image-20221030212741665

独立按键控制LED显示二进制

需要注意的是如果主函数代码如下,会出现问题,因为P2默认是高电平:

void main()
{while(1){if(P3_1==0)			//如果s1按键按下{Delay(20);		//延时消抖while(P3_1==0);	//松手检测Delay(20);		//延时消抖P2++;  // P2:1111 1111 一开始默认高电平P2=~P2;// P2:0000 0000 自增}          // P2:1111 1111 取反}              // P2:0000 0000 自增
}                  // P2:1111 1111取反
//现象:上板测试所有LED不发光

实现按键控制LED显示二进制代码如下:

#include <REGX52.H>void Delay1ms(unsigned int xms)		//@12.000MHz
{while(xms--){unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);}	
}void main()
{unsigned char LEDNum=0; //定义无符号字符型变量,其所占的位数为8位while(1){ if(P3_1==0)//检测按键是否被按下{Delay1ms(20);//延时去抖while(P3_1==0);//检测松手LEDNum++; //按一下,值加1,0000 0000->0000 0001->0000 0010...P2=~LEDNum; //按位取反,  1111 1111->1111 1110->1111 1101...}}  
}

独立按键控制LED移位

控制左移的初级版代码如下:

#include <REGX52.H>void Delay1ms(unsigned int xms)		//@12.000MHz
{while(xms--){unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);}
}
unsigned char LEDNUm;//全局声明时,默认声明的变量值为0void main()    	
{P2=~0x01;//对P2口进行初始化,这样一上电,灯就亮了while(1){if(P3_1==0) //检测按键是否被按下{Delay1ms(20);//延时消抖while(P3_1==0);//检测按键是否被松开LEDNUm++;//自增if (LEDNUm>8)       // 0000 0001->0000 0010->0000 0100->0000 1000{               // 0001 0000->0010 0000->0100 0000->1000 0000LEDNUm=0;   //如果LEDNUm大于8就令其为0}P2=0x01<<LEDNUm; //左移n位P2=~P2 ;//取反   0000 0001->0000 0010->1111 1101  000 0100->0000 1000}		}			           
}

同时控制左移和右移的进阶版代码如下:

#include <REGX52.H>void Delay1ms(unsigned int xms)		//@12.000MHz
{while(xms--){unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);}}unsigned char LEDNUm;//全局声明时,默认声明的变量值为0void main()    	
{P2=~0x01;//对P2口进行初始化,这样一上电,灯就亮了while(1){if(P3_1==0) //检测按键s13是否被按下{Delay1ms(20);//延时消抖while(P3_1==0);//检测按键是否被松开LEDNUm++;//自增if (LEDNUm>8)       // 0000 0001->0000 0010->0000 0100->0000 1000{               // 0001 0000->0010 0000->0100 0000->1000 0000LEDNUm=0;   //如果LEDNUm大于8就令其为0}P2=0x01<<LEDNUm; //左移n位P2=~P2 ;//取反   0000 0001->0000 0010->1111 1101  000 0100->0000 1000}if(P3_0==0) //检测按键s14是否被按下{Delay1ms(20);//延时消抖while(P3_0==0);//检测按键是否被松开if(LEDNUm==0) //如果LEDNUm等于0就令其为7{LEDNUm=7;}elseLEDNUm--;P2=0x01<<LEDNUm; //比如按S13 3遍 这时 NUM等于3 此时向左移3位P2=~P2 ;//取反   //此时按S14 1遍 这时 NUM减去1 等于2 此时P2向左移2位 //虽然都是左移,但是位数少了一位,相当于右移了一位。}}}

http://www.ppmy.cn/news/461897.html

相关文章

实验 键盘与LED实验

实验 键盘与LED实验 一、实验要求 P0口接7段LED数码管&#xff0c;P1口接8个独立按钮&#xff0c;分别控制数码管显示数字0-7&#xff0c;画出原理电路图&#xff0c;编写驱动程序。 二、实验目的 1、熟练keil软件的基本操作&#xff1b; 2、掌握80c51单片机p1口的使用方法…

html 游戏键盘,HTML tabindex属性与web网页键盘无障碍访问

本文要介绍的是属性tabindex和下一篇要介绍的accesskey&#xff0c;与web网页无障碍访问息息相关&#xff0c;而且是键盘访问领域的。这些属性不仅可以触发浏览器层面的行为&#xff0c;本身对HTML的元素的交互特性甚至UI表现都会有影响。下面就来看看今天的重点HTML tabindex属…

键盘扫描并控制数码管C语言,CH454 数码管显示驱动和键盘扫描控制芯片

1、概述 CH454 是数码管显示驱动和键盘扫描控制芯片。CH454内置时钟振荡电路&#xff0c;可以动态驱动8 只16段的数码管或者128 只LED&#xff0c;支持11 段、14 段、16 段8 以及17 段7 等;同时还可以进行64 键的键盘扫描;CH454 通过2 线串行接口与单片机等交换数据。 2、特点 …

查询式键盘实验c语言,单片机实验上机--实验十七查询式键盘实验.doc

单片机实验上机--实验十七查询式键盘实验 实验十七 查询式键盘实验 一、实验目的 1、掌握键盘和显示器的接口方法和编程方法 2、掌握键盘和八段码显示器的工作原理 3、静态显示的原理和相关程序的编写 二、实验说明 本实验提供了8个按钮的小键盘,如果有键按下,则相应输出为低…

计算机键盘英语,电脑键盘打字时中英文如何切换?

1、首先&#xff0c;需要安装输入法&#xff0c;安装完毕之后按照输入法默认设置就可以&#xff1b;或者是您可以尝试使用键盘上的【Shift】 【Ctrl】组合键调出输入法&#xff0c;一般会在右下角状态栏上显示当前的输入法&#xff1b; 2、在输入法的状态栏中可以看到当前输入法…

Win11触摸键盘主题如何更换

Win11触摸键盘主题要如何更换&#xff1f;现在有一些使用Windows11平板电脑的朋友&#xff0c;大家会用到触摸键盘&#xff0c;因此也希望显示出来好看一点&#xff0c;所以想要去更换触摸键盘主题颜色&#xff0c;那么应该如何操作呢&#xff1f;下面我给CSDN的朋友讲讲Win11更…

计算机控制键盘,键盘装置及其计算机控制系统的制作方法

技术特征&#xff1a; 1.一种键盘装置&#xff0c;其特征在于&#xff1a;包括一键盘本体&#xff0c;该键盘本体上形成有一操作面&#xff0c;并该操作面的两侧边分别形成有一邻近边及一远离边&#xff0c;且该操作面上设置有复数按键及至少一发光元件&#xff0c;另该键盘本体…

一文教你彻底学会SPI协议

一文教你彻底学会IIC协议 一.概况SPI二.SPI连接2.1 一主一从2.2 一主多从 三.SPI通信过程3.1 CPOL&#xff08;极性&#xff09;和CPHA&#xff08;相位&#xff09;3.2 SPI时序图3.1 SPI起始信号3.2 SPI停止信号3.3 数据的有效性 四.代码实例 一.概况SPI SPI 协议是由摩托罗拉…