AVR单片机教程——拨动开关
本文隶属于AVR单片机教程系列。
在按键的上方有4个拨动开关。开关与按键,在原理和使用方法上都是很类似的,但有不同的用途——按键按下后松开就会弹起,而开关可以保存其状态。
<switch.h> 定义了与开关相关的函数。switch_status 对应 button_down ,switch_changed 对应 button_pressed ,使用与按键是基本相同的。
这里通过一个异常简单的例子来演示开关函数的使用,并说明开关操作与按键的细微差别:使LED与开关状态保持同步。
仿照上一篇教程,我们可以简单地把 button_pressed 替换为 switch_changed :
#include <ee1/led.h>
#include <ee1/switch.h>
#include <ee1/delay.h> int main()
{
led_init();
switch_init(PIN_NULL, PIN_NULL);
while ()
{
if (switch_changed(SWITCH_0))
led_flip(LED_GREEN);
delay();
}
}
如果把按键拨到关(即下)再复位单片机,一切安好,但是如果一开始是开的状态,LED的状态会总是与开关相反。为什么呢?因为开关可以保存状态,这是第一个差别。
所以,我们可以每次得知开关状态改变后读取开关状态,并传给LED:
#include <ee1/led.h>
#include <ee1/switch.h>
#include <ee1/delay.h> int main()
{
led_init();
switch_init(PIN_NULL, PIN_NULL);
while ()
{
if (switch_changed(SWITCH_0))
led_set(LED_GREEN, switch_status(SWITCH_0));
delay();
}
}
这也引出了第二个差别——当 switch_changed 返回 true 时,我们不能直接知晓开关的状态,需要手动调用 switch_status ;而对于相应的按键操作,我们知道此时按键一定处于按下的状态。
如果复位时开关状态为开,除了第一次拨动按键以前,LED总是与按键同步的。然而我们的要求是保持同步,当然包括一开始的时候。为了获得正确的初始状态,我们可以在进入主循环前添加以下代码:
if (switch_status(SWITCH_0))
led_set(LED_GREEN, true);
但事实上,这个问题根本没有那么麻烦,甚至不需要 switch_changed 函数——每次循环读取开关状态,再把LED设置成相应状态即可:
#include <ee1/led.h>
#include <ee1/switch.h>
#include <ee1/delay.h> int main()
{
led_init();
switch_init(PIN_NULL, PIN_NULL);
while ()
{
led_set(LED_GREEN, switch_status(SWITCH_0));
delay();
}
}
你一开始有没有想到这个简单的方案?如果有,并且第一反应就是这个,那你得开始逐渐改变思路了。这种方案在这个例子中可用,是因为对 led_set 和 switch_status 的调用的成本是很低的,每次循环都调用也没有问题。然而这并不是放之四海而皆准的,有些函数经不起这样频繁的调用。在那样的情况下,检测状态改变,再读取状态,是一种更好的方案。
思考:在判定按键动作的函数中,前一次状态通过静态变量存储,其初值为真,保证第一次调用时函数不会返回真;对于开关动作,相应静态变量的初值应该是什么?
作业:每个开关控制一个LED,一个按键控制开关是否启用;启用时要让LED与当前开关状态对应,禁用时要关闭所有LED。
AVR单片机教程——拨动开关的更多相关文章
- AVR单片机教程——数字输入
我们已经学习了如何使用按键和拨动开关,不知你有没有好奇 button_down 和 switch_status 等函数是如何实现的.本篇教程带你一探究竟,让我们从按键的原理开始. 在原理图中,按键的符 ...
- AVR单片机教程——串口发送
本文隶属于AVR单片机教程系列. 到目前为止,我们的开发板只能处理很小量的数据:读取几个引脚电平,输出几个LED,顶多用数码管显示一个两位数字.至于输入一个指令.输出一条调试信息,甚至用scanf ...
- AVR单片机教程——旋转编码器
好久没写这个系列了.今天讲讲旋转编码器. 旋转编码器好像不是单片机玩家很常用的器件,但是我们的开发板上有,原因如下: 旋转编码器挺好用的.电位器能旋转的角度有限,旋转编码器可以无限圈旋转:旋转时不连续 ...
- AVR单片机教程——数码管
先解答之前一个思考题:如果不把引脚配置为输出而写高电平,连接LED会怎样? 实验结果是,LED会亮,但相比于输出高电平的情况,亮度很低.这是为什么呢? 通过上一篇教程我们知道,引脚输入输出模式是由寄存 ...
- AVR单片机教程——数字输出
从上一篇教程中我们了解到,按键与开关的输入本质上就是数字信号的读取.这一篇教程要讲的是,控制LED的原理是数字信号的输出.数字IO是单片机编程之有别于桌面编程的各项内容中最简单.最基础的. 在讲数字信 ...
- AVR单片机教程——按键动作
上一篇教程中我们学习了如何读取按键状态.而按键的动作,比如单击,至少需要两个状态才能判定,长按.双击的判定更加复杂.今天我们来学习如何使用库函数判断按键单击,以及其实现原理. 我们要实现的是:当一个按 ...
- AVR单片机教程——按键状态
好久没更新了,今天开始继续,争取日更. 今天我们来讲按键.开发板的右下角有4个按键,按下会有明显的“咔嗒”声.如何检测按键是否被按下呢?首先要把按键或直接或间接地连接到单片机上.与之前使用的4个LED ...
- AVR单片机教程——随机点亮LED
之前我们做的闪烁LED和流水灯,灯效都是循环的.这次我们来尝试一些不一样的——每一次随机选择一个LED并点亮. 要实现随机的效果,我们要用C语言标准库中的相关设施: #define RAND_MAX ...
- AVR单片机教程——流水灯
上次我们用 delay 函数与 while 循环实现了一个LED的闪烁.这一次我们把所有LED加入进来,让它们依次闪烁,形成流水灯的效果. 开发板上有4个LED,我们可以用不多的语句把循环体直接描述出 ...
随机推荐
- 2-移远GSM/GPRS M26 模块 Mini板 开发板(M26入门)
https://www.cnblogs.com/yangfengwu/p/11214553.html 资料获取,首先说一下....很多东西需要自己悟,没有QQ群,没有微信群,论坛也寥寥无几!!!! 估 ...
- python 报can't subtract offset-naive and offset-aware datetimes错误
两个时间一个含时区,一个不含时区
- NOIP 2018 普及组 解题报告
目录 标题统计 题目链接 思路 代码 龙虎斗 题目链接: 思路 代码 摆渡车 题目链接: 思路 对称二叉树 题目链接 思路: 先来解释一下为毛现在才来发解题报告: 其实博主是参加过NOIP 2018普 ...
- 群晖采用root用户登录
在控制面板中开启 ssh 登录 通过有 管理员权限的用户登录 通过输入 sudo -i 或者 sudo su - , 然后输入当前用户密码, 进入 root 输入如下命令可以修改root 用户的密码 ...
- mysql max()函数,min()函数,获取最大值以及最小值
mysql> select * from table1; +----------+------------+-----+---------------------+ | name_new | t ...
- HAProxy+Keepalived高可用负载均衡
一 基础准备 1.1 部署环境及说明 系统OS:CentOS 6.8 64位 HAProxy软件:HA-Proxy version 1.5.18 Keepalived软件:keepalived-1.3 ...
- 算法练习题---罗马数字转int
连接:https://leetcode-cn.com/problems/roman-to-integer/submissions/ 题目: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 ...
- 微信小程序之页面导航栏
效果图: 页面有点丑,作为初次学习,页面可以要求不那么美观,先学会再说.毕竟后面可以优化的很漂亮. 代码实例如下: <view class="section btn-area" ...
- 第09组 Alpha冲刺(1/4)
队名:软工9组 组长博客: https://www.cnblogs.com/cmlei/ 作业博客: 组员进度 ● 组员一(组长) 陈明磊 ○过去两天完成了哪些任务 ●文字/口头描述 初步 ...
- 【软工实践】Alpha冲刺(6/6)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 tomcat的学习与实现 服务器后端部署,API接口的beta版实现 后端代码 ...