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

好久没更新了,今天开始继续,争取日更。

今天我们来讲按键。开发板的右下角有4个按键,按下会有明显的“咔嗒”声。如何检测按键是否被按下呢?首先要把按键或直接或间接地连接到单片机上。与之前使用的4个LED不同,4个按键没有全部连接到单片机上——左边2个是连接的,右边2个通过按键上方标有B2、B3的接口引出(从左到右分别为B0、B1、B2和B3)。如果要使用B2、B3,要用杜邦线连接到16个单片机引出针脚上。

开发板库中与按键相关的函数定义在 <ee1/button.h> ,这里是库函数手册。值得一提的是1.1版本的库中,换用枚举类型表示按键等设备,不再使用整数与宏定义(但用整数也是兼容的)。在Atmel Studio 7.0中写代码时,编辑器会提示函数接口,可以根据参数类型知道应该写什么。

对于单片机而言,按键是一种输入设备。程序都有零个或若干个输入,一个或多个输出,而我们学过的唯一一种输出设备就是LED。所以理所当然地,今天我们要用按键来控制LED:按键按下,LED亮起;按键抬起,LED关闭;4个按键分别对应4个LED。

我们先来实现一个简单的版本——只考虑一个按键和一个LED。

程序的流程是:先初始化;然后在主循环中,用 button_down 函数检测按键是否被按下;如果按下,让LED亮;否则让它不亮。再想一想,其实LED的亮暗状态就是 button_down 函数的返回值。

 #include <ee1/led.h>
#include <ee1/button.h> int main(void)
{
led_init();
button_init(PIN_NULL, PIN_NULL);
while ()
led_set(LED_RED, button_down(BUTTON_0));
}

你可能会想到,对于一个已经亮起的LED,再调用 led_set 让它亮会不会有问题?答案是不会。那么,既然已经亮了,可否设置一个变量保存它是否已亮起,若是则无需再让它亮?当然可以,但是维护这样一个变量可能还不如无脑调用 led_set 来得快。对于LED是这样的,但并非所有设备都是,遇到再说。

现在我们来实现4个按键的版本。把以上循环体中的代码复制4遍是可以的,但这是不良代码的表现。我们可以用数组把表示LED和按键的枚举常量存储起来,对数组遍历执行以上循环体,但这也没有必要。在头文件中我们可以看到, LED_RED 、 BUTTON_0 等枚举常量(1.0版本中是宏)就是从0开始的数字,因此用 for 语句中的 i 就能解决问题了。

 #include <ee1/led.h>
#include <ee1/button.h> int main(void)
{
led_init();
button_init(PIN_0, PIN_1);
while ()
{
for (int i = ; i != BUTTON_COUNT; ++i)
led_set(i, button_down(i));
}
}

注意将B2、B3分别连接到端口0和1上。你当然可以改变连接的端口,但也要相应地修改初始化参数。

在上面的代码中,变量 i 的上限是 BUTTON_COUNT - 1 。为什么不是 LED_COUNT 呢?其实是的,它们是相等的。但是我们没法保证它们永远是相等的。设想某一天开发板2.0拥有8个按键,而LED还是4个,led_set 的第一个参数就是不合理的(尽管库函数已经处理好了这个问题)。我们是否有必要在这里写两者中较小的值?没必要。其一,开发者是世界上最聪明的生物,他们(中的部分)能处理好这些问题;其二,相比于软件,硬件是相对稳定的,当硬件更改时,软件往往有必要重写,不是一个上限判断就能解决的;其三,作为初学者,你今天写的代码,一个月后就会觉得很简单,以后这种代码都是信手拈来,这里考虑可复用性没有必要。

现在你已经学会如何读取按键状态了。但有时候我们关心的是按键被按下这一动作,而动作是不能仅由一个状态表示的,下一篇教程将介绍实现方案。

AVR单片机教程——按键状态的更多相关文章

  1. AVR单片机教程——按键动作

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

  2. AVR单片机教程——旋转编码器

    好久没写这个系列了.今天讲讲旋转编码器. 旋转编码器好像不是单片机玩家很常用的器件,但是我们的开发板上有,原因如下: 旋转编码器挺好用的.电位器能旋转的角度有限,旋转编码器可以无限圈旋转:旋转时不连续 ...

  3. AVR单片机教程——数码管

    先解答之前一个思考题:如果不把引脚配置为输出而写高电平,连接LED会怎样? 实验结果是,LED会亮,但相比于输出高电平的情况,亮度很低.这是为什么呢? 通过上一篇教程我们知道,引脚输入输出模式是由寄存 ...

  4. AVR单片机教程——数字输出

    从上一篇教程中我们了解到,按键与开关的输入本质上就是数字信号的读取.这一篇教程要讲的是,控制LED的原理是数字信号的输出.数字IO是单片机编程之有别于桌面编程的各项内容中最简单.最基础的. 在讲数字信 ...

  5. AVR单片机教程——数字输入

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

  6. AVR单片机教程——拨动开关

    在按键的上方有4个拨动开关.开关与按键,在原理和使用方法上都是很类似的,但有不同的用途——按键按下后松开就会弹起,而开关可以保存其状态. <switch.h> 定义了与开关相关的函数.sw ...

  7. AVR单片机教程——ADC

    ADC 计算机的世界是0和1的.单片机可以通过读取0和1来确定按键状态,也可以输出0和1来控制LED.即使是看起来不太0和1的PWM,好像可以输出0到5V之间的电压一样,达到0和1之间的效果,但本质上 ...

  8. AVR单片机教程——定时器中断

    本文隶属于AVR单片机教程系列.   中断,是单片机的精华. 中断基础 当一个事件发生时,CPU会停止当前执行的代码,转而处理这个事件,这就是一个中断.触发中断的事件成为中断源,处理事件的函数称为中断 ...

  9. AVR单片机教程——PWM调光

    本文隶属于AVR单片机教程系列.   PWM 两位数码管的驱动方式是动态扫描,每一位都只有50%的时间是亮的,我们称这个数值为其占空比.让引脚输出高电平点亮LED,占空比就是100%. 在驱动数码管时 ...

随机推荐

  1. 洛谷 P3376 【模板】网络最大流 题解

    今天学了网络最大流,EK 和 Dinic 主要就是运用搜索求增广路,Dinic 相当于 EK 的优化,先用bfs求每个点的层数,再用dfs寻找并更新那条路径上的值. EK 算法 #include< ...

  2. 回归模型的性能评价指标(Regression Model Performance Evaluation Metric)

    回归模型的性能评价指标(Performance Evaluation Metric)通常有: 1. 平均绝对误差(Mean Absolute Error, MAE):真实目标y与估计值y-hat之间差 ...

  3. 第03组 Alpha冲刺(1/4)

    队名:不等式方程组 组长博客 作业博客 团队项目进度 组员一:张逸杰(组长) 过去两天完成的任务: 文字/口头描述: 制定了初步的项目计划,并开始学习一些推荐.搜索类算法 GitHub签入纪录: 暂无 ...

  4. LOJ6609 无意识的石子堆【加强版】【容斥原理,计数】

    题目描述:在一个\(n\times m\)的网格中,放\(2n\)个棋子,使每一行和每一列都不超过两个棋子.求方案数\(\mathrm{mod} \ 943718401\). 数据范围:\(n\le ...

  5. 平安寿险Java面试-社招-四面(2019/08)

    个人情况 2017年毕业,普通本科,计算机科学与技术专业,毕业后在一个二三线小城市从事Java开发,2年Java开发经验.做过分布式开发,没有高并发的处理经验,平时做To G的项目居多.写下面经是希望 ...

  6. 四种CSS样式的引入方式

    准备 1.首先准备一个html文件:test.html,不建议使用记事本创建文件,建议使用Notepad++来创建并编辑文件,注意编码格式为:以UTF-8无BOM格式编码,否则会出现中文乱码,内容如下 ...

  7. Kerberos(一) 安装

    1.服务器基本信息 操作系统:centos7 数量:2 主机名映射关系 IP hostname server 192.168.4.50 manager1 Kerberos server(kdc) 19 ...

  8. last-child为啥不生效

    last-child基本定义 指定属于其父元素的最后一个子元素的 p 元素的背景色 如果你这样写是不会生效的 <div class="limit-border"> &l ...

  9. CFD-Post中截取任意面的数据

    源视频下载链接: https://pan.baidu.com/s/1i4PtgDR 密码: wsn5

  10. vscode前端插件(我的标配)

    前言 今天给我的vscode编辑汉化了一下)我也不知道为什么要汉化一下... 但是汉化后 我的vue文件木有高亮了,2333(只好一顿操作 再安装插件 还要去百度找 自己留存) 汉化后 是所有的插件都 ...