大神带你玩转单片机之机械按键详解

今天,我们来讲解一下板子上的一个模块——机械按键。

机械按键分为两种使用模式:独立按键和矩阵按键。这两个模式是通过板子上的一个硬件部分来切换的,使用方法不相同,但原理都差不多,在大家使用小红板学习的时候这方面都应该也有接触过。没错,它与小红板上的使用方式几乎是相同的。

相信很多人在学习的时候,都觉得按键很简单对吧?但是大家要注意的是,想要写出一个完全没bug(按键能够特别灵敏地判断状态)的按键其实并不简单。而且它总是结合数码管、LED灯等各种模块来配合使用的,按键各种按下状态中实现各种功能,各种逻辑写起来也是有一定难度的。

好的,话不多说了,接下来我会为大家分别讲解一下独立键盘和矩阵键盘基础知识。

机械按键原理图

我们先来看一下按键部分的原理图:

“”

我们看右边蓝色框框起来引脚,可以看到大部分的按键都是通过P3端口来控制的。

为什么说是大部分呢?因为板子上的两个引脚有变化:P3^6 --> P4^2; P3^7 --> P4^4

前边说的键盘两种模式是通过左边橙色框里框起来的硬件(对应板子上的J5)来控制的。当跳线帽接2-3时,模式为独立按键;接1-2时,模式为矩阵按键(千万别抬杠哦)。

独立按键原理

好的,我们现在先开始独立按键的讲解。

这里的独立按键与小红板上的使用方法是完全一样的。

我们看左边红色框里框起来的部分,这四个按键就是独立按键,可以看到它右边分别接了P3^0~P3^3引脚,左边通过跳线帽接到了GND。

然后,我们又知道51单片机在默认状态下,引脚都为高电平,当对应按键按下时,右边的引脚就与左边的GND接在了一起,电平就会被拉低,所以直接判断对应的引脚是否为低电平就可以知道这个按键有没有被按下。

使用按键的时候要注意一点就是机械按键的抖动,我们看下边这张图:

“”

上边蓝色框框起来的是我们理想中的波形图(默认高电平,按下低电平),实际中的波形是下边红色框框起来的。

可以看到绿色框中的电平一直在抖动,这段电平就会对我们判断按键是否触发产生干扰。由于板子上没有消除抖动的硬件设计,我们就需要通过程序延时来跳过这段抖动。

很简单,只需要在判断引脚电平为低以后加10ms左右的延时,如果这时候引脚电平还是低电平,就代表我们的按键确实被按下了。还有,在我们按下没松手的时候,程序会一直循环执行我们这段程序。

为了避免这种问题,还需要在按键程序中加入“松手检测”,看下边一段程序:

if(P30 == 0) //判断按键S7是否按下
{
  Delay_key(10); //10ms延时用来消抖
  if(P30 == 0) //再次判断按键S7是否按下
  {
    /* 按下S7时需要执行的程序放这里 */
    while(P30 == 0); //松手检测
  }
}

这就是独立按键的检测函数,嘻,很简单吧?

矩阵按键原理

好的独立按键讲完了我们来讲解一下矩阵按键。(切换的时候记得要把跳线帽换一下哦)

这时我们再看原理图,每行的四个按键都接在了一起,右端分别接在了P3^0、P3^1、P3^2、P3^3引脚,每列的四个按键也接在了一起,左端分别接在了P3^4、P3^5、P4^2、P4^4引脚。

当按下一个按键的时候,我们只要想办法判断它是哪一行哪一列的就行啦。通过程序先把P3^4、P3^5、P4^2、P4^4全部拉低,再判断P3^0、P3^1、P3^2、P3^3中哪一个引脚变为了低电平就可以判断第几行按键按下了,同样的方法来判断按键是哪一列的就可以啦。

再看下边一段程序:

void key_scan()
{
  P34 = P35 = P42 = P44 = 0;
  P30 = P31 = P32 = P33 = 1;
  if(P30 == 0)
  {
    delayms(10)
    if(P30 == 0) KeyValue = 7;
    while(P30 == 0)
  }
  if(P31 == 0)
  {
    delayms(10)
    if(P31 == 0) KeyValue = 6;
    while(P31 == 0)
  }  
  if(P32 == 0)
  {
    delayms(10)
    if(P32 == 0) KeyValue = 5;
    while(P32 == 0)
  }
  if(P33 == 0)
  {
    delayms(10)
    if(P33 == 0) KeyValue = 4;
    while(P33 == 0)
  }
  P34 = P35 = P42 = P44 = 1;
  P30 = P31 = P32 = P33 = 0;
  if(P34 == 0)
  {
    delayms(10)
    if(P34 == 0) KeyValue = KeyValue + 12;
    while(P34 == 0)
  }
  if(P35 == 0)
  {
    delayms(10)
    if(P35 == 0) KeyValue = KeyValue + 8;
    while(P35 == 0)
  }
  if(P42 == 0)
  {
    delayms(10)
    if(P42 == 0) KeyValue = KeyValue + 4;
    while(P42 == 0)
  }
  if(P44 == 0)
  {
    delayms(10)
    if(P44 == 0) KeyValue = KeyValue;
    while(P44 == 0)
  }
}

这段代码没加注释,是因为我希望大家可以不只依赖于注释。细品一下这段代码,在品的时候多加思考,绝对比只看注释理解得更加透彻。

KeyValue是我们在程序最开始定义的一个全局变量,它主要起标志的作用,这就是传说中的标志位,通过判断给它的赋值就可以判断按下的哪一个按键(KeyValue=6 --> 按键6...),把这个函数在主函数while循环中执行就可扫描矩阵按键。当然,这只是其中一种判断形式,常用的还有逐行判断等等,大家可以自己试一下。

值得注意的是,我们这里的头文件使用的是“stc15f2k60s2.h”,相较于“reg52.h”,它的功能更加强大。而且在“reg52.h”中是没有P4端口的定义的,在使用的时候要在程序开头部分添加一句代码 “sfr P4 = 0xC0;” 来给P4定义地址。“stc15f2k60s2.h”就不需要了,而且可以直接用 “P30”等来表示 “P3^0” 等。

本文转载自:电子产品世界(作者:阿飞)
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理。

点击这里,获取更多关于应用和技术的有关信息
点击这里,获取更多工程师博客的有关信息

推荐阅读