• AVR单片机教程——按键动作


    本文隶属于AVR单片机教程系列。

    上一篇教程中我们学习了如何读取按键状态。而按键的动作,比如单击,至少需要两个状态才能判定,长按、双击的判定更加复杂。今天我们来学习如何使用库函数判断按键单击,以及其实现原理。

    我们要实现的是:当一个按键被单击时,一个LED的状态改变(即亮变暗,暗变亮);4个按键对应4个LED。利用库提供的 button_pressed 函数,很容易就能实现这个功能。

     1 #include <ee1/button.h>
     2 #include <ee1/led.h>
     3 #include <ee1/delay.h>
     4 
     5 int main()
     6 {
     7     led_init();
     8     button_init(PIN_0, PIN_1);
     9     while (1)
    10     {
    11         for (uint8_t i = 0; i != BUTTON_COUNT; ++i)
    12             if (button_pressed(i))
    13                 led_flip(i);
    14         delay(40);
    15     }
    16 }

    在主循环中,程序对每个按键调用 button_pressed ,若返回真,则用 led_flip 将LED状态反转。

    按键动作需要两个状态来判断,而函数在当下是无法从按键读取到以前的信息的,只能在本次调用时保存状态以供下次使用。自动变量保存的内容无法保留到下一次调用,可选的有全局变量与静态变量。由于此状态只被这一个函数使用,可以把它定义成静态变量。

    button_pressed 函数可以判断4个按键的动作,每个按键需要一个 bool 变量,即一个bit的存储空间。为了节省空间,我使用了位操作,这里先不讲,把重心放在按键动作判断逻辑上。以下是判断一个按键动作的函数。

    1 bool pressed()
    2 {
    3     static bool status = true;
    4     bool pre = status;
    5     status = button_down(BUTTON_0);
    6     return !pre && status;
    7 }

    静态变量 status 用于保存按键在上一次调用时的状态。函数体中,先用自动变量 pre 临时保存了 status ,然后将 status 更新为当前的状态。return 语句返回的是 !pre && status ,即仅当 pre 为假且 status 为真时返回 true 。其逻辑为,如果上一次按键没有被按下而这一次被按下,则按键被单击了。

    想一想,为什么 status 的初值要设置成 true ?

    另外,上面的代码开头处的蓝色 bool 特别醒目,因为博客园代码着色是按照C#的规则,bool 是其中一个关键字。但是应当注意,C语言中没有 bool 这个关键字,而是 _Bool ;bool 与 true 和 false 都在 <stdbool.h> 中定义。

    我们还没有解释过第一段代码中的 delay(40) 。如果你把它去掉,你会发现判定经常出错,往往在抬起的时候被多判定了一次,在按得不是很用力时很不稳定。这是按键内部的机械结构决定的,当处于连通和不连通位置的交界处时,单片机检测到的电平会迅速跳变(按键的原理,以及单片机如何检测按键状态,将在几篇后介绍),而一段延时就可以让这些跳变的电平被 button_down 函数忽略。这里的40是根据经验选取的。其实把40换成10到100之间的数,手感基本没有差别。

    然而,即使有这句延时,单击判定还是有出错的时候。如果不能允许这样的错误,就需要“消抖”上场了,我们以后再讲。

    作业:给其中一个按键加上一个功能,让它控制其余按键是否启用。

  • 相关阅读:
    linux设置永久别名
    网站架构
    c#: 判断Firefox是否安装
    似是故人来
    Python: re.sub()第二个参数
    Python: AES加密与解密
    c#: Noto Sans字体如何支持韩文
    Inno Setup安装程序单例运行
    朵朵的二维码
    Python: 浅淡Python中的属性(property)
  • 原文地址:https://www.cnblogs.com/jerry-fuyi/p/11546554.html
Copyright © 2020-2023  润新知