• AVR单片机教程——数字输入


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

    我们已经学习了如何使用按键和拨动开关,不知你有没有好奇 button_down 和 switch_status 等函数是如何实现的。本篇教程带你一探究竟,让我们从按键的原理开始。

    在原理图中,按键的符号如下图所示:

    符号很简单,就是两个触点上方有一个动片,当按下时与两个触点接触。实际上按键内部的机械结构大体上就是这样,实现的功能是,没有按下时两端断路,按下时两端短路。

    还有一种画法是这样的,即电键:

    就按键内部的机械结构来说,第一种更加真实,但从电路角度来看,两者没什么区别。

    但是我们的开发板上的按键有4个引脚,这是怎么回事呢?其实上面两个和下面两个分别是连通的,相当于只有两个:

    拨动开关,相当于单刀双掷开关:

    从开发板反面可以看到拨动开关有3个引脚。拨到上方时,上面两个导通;拨到下方时,下面两个导通。

    然而,光知道这些原理还不够。任何IC,包括单片机,与外界打交道的唯一途径是引脚。单片机要知道按键状态,必须由我们搭建合适的电路,把按键和开关的信息转换为电平,连接到单片机上。

    先说按键吧。按键按下时,两引脚之间导通,如果一端接在某一极(电源或地)上,另一端的电平就是确定的。然而,如果不连接其他器件,当没有按下时,这一端是浮空的,电压可能高也可能低,是无效的。而我们希望不按下时检测到的是另一种电平,因此我们可以在按键一端和另一极之间接一个电路:

    按键接到地,电阻接到电源,这是一种很常见的接法,其中的电阻称为上拉电阻,取值几千欧到几十千欧都没啥问题。这个电阻可以在单片机内部,也可以是一个独立的元件。在我们的开发板上,4个按键(以及4个开关,后面会提到)是通过排阻上拉的。

    为什么把按键接在地上用上拉,而不是接在正电源上用下拉?这是个很复杂的问题。尽管在布尔代数中0和1是完全对称的,但电子毕竟是电子而空穴是电子的缺失,由于某些很复杂的原因,导致上拉比下拉更加常见(得多)。事实上,AVR单片机的引脚可以配置独立的上拉电阻,但是没有下拉电阻可选(部分新型号中有)。

    如果你没有受过上拉电阻思想的熏陶,对于拨动开关,你可能会想到这种接法:

    这种接法不需要额外的元器件,听起来很妙。然而,虽然可行,这是一种不好的方法。万一两个触点之间短路了怎么办?整块开发板都短路保护了。尽管短路保护听起来安全,但即使保护起来,在解决短路问题之前,开发板还是不能用的。还有一种情况,我真的碰到过,就是单片机上两个相邻的读取开关的引脚因为焊接时的疏忽短路了,导致一旦这两个开关状态不一样就会触发短路保护。总之,这种接法不提倡。

    与按键类似,在开关这边我们也可以用上拉电阻的接法:

    利用这两种电路,我们成功地将按键不按下与按下分别转换成高电平和低电平,把开关位于下方和上方分别转换成低电平和高电平。那么,单片机怎么读取电平呢?库提供了 pin_read 函数,定义在 <ee1/pin.h> 中。我们还是通过一个例子来学习其使用方法:保持黄灯和蓝灯的状态分别与按键2和开关2的电平相同。

     1 #include <ee1/pin.h>
     2 #include <ee1/led.h>
     3 
     4 #define BUTTON2 PIN_0
     5 #define SWITCH2 PIN_1
     6 
     7 int main()
     8 {
     9     led_init();
    10     pin_mode(BUTTON2, INPUT);
    11     pin_mode(SWITCH2, INPUT);
    12     while (1)
    13     {
    14         led_set(LED_YELLOW, pin_read(BUTTON2));
    15         led_set(LED_BLUE  , pin_read(SWITCH2));
    16     }
    17 }

    异常简单的例子,不是吗?用 pin_read 读取引脚电平,再把LED设置为相应值。

    当程序涉及端口操作时,为了能在硬件连接改变时方便地修改程序,建议用宏或常量建立设备与引脚之间的映射关系。这样在修改时就只有这个映射关系需要改动了,总比程序每一处调用都修改要方便得多。

    值得一提的是,尽管今天的教程介绍了更底层的知识,但这仍不是我们能达到的最底层的地方。在几篇教程之后,你就可以抛弃库函数了。

    作业:利用 pin_read 函数,结合之前教程中的知识,实现按键动作的检测并测试之。

  • 相关阅读:
    Linux 头文件详解
    Linux 进程运行状态
    配置uboot指定nfs挂载根文件系统
    (实例)Linux 内核添加exfat驱动
    Linux 内核 编译模块
    简单添加自己的驱动程序到Linux内核树中
    Linux 生成随机mac地址,并固化到本地
    (转)为什么ssh一关闭,程序就不再运行了?
    Ubuntu 安装 QtCreator (version : Qt 5.9.8)
    Ubuntu 固定自己的IP
  • 原文地址:https://www.cnblogs.com/jerry-fuyi/p/11570101.html
Copyright © 2020-2023  润新知