zoukankan      html  css  js  c++  java
  • AVR单片机教程——拨动开关

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

    在按键的上方有4个拨动开关。开关与按键,在原理和使用方法上都是很类似的,但有不同的用途——按键按下后松开就会弹起,而开关可以保存其状态。

    <switch.h> 定义了与开关相关的函数。switch_status 对应 button_down ,switch_changed 对应 button_pressed ,使用与按键是基本相同的。

    这里通过一个异常简单的例子来演示开关函数的使用,并说明开关操作与按键的细微差别:使LED与开关状态保持同步。

    仿照上一篇教程,我们可以简单地把 button_pressed 替换为 switch_changed :

     1 #include <ee1/led.h>
     2 #include <ee1/switch.h>
     3 #include <ee1/delay.h>
     4 
     5 int main()
     6 {
     7     led_init();
     8     switch_init(PIN_NULL, PIN_NULL);
     9     while (1)
    10     {
    11         if (switch_changed(SWITCH_0))
    12             led_flip(LED_GREEN);
    13         delay(40);
    14     }
    15 }

    如果把按键拨到关(即下)再复位单片机,一切安好,但是如果一开始是开的状态,LED的状态会总是与开关相反。为什么呢?因为开关可以保存状态,这是第一个差别。

    所以,我们可以每次得知开关状态改变后读取开关状态,并传给LED:

     1 #include <ee1/led.h>
     2 #include <ee1/switch.h>
     3 #include <ee1/delay.h>
     4 
     5 int main()
     6 {
     7     led_init();
     8     switch_init(PIN_NULL, PIN_NULL);
     9     while (1)
    10     {
    11         if (switch_changed(SWITCH_0))
    12             led_set(LED_GREEN, switch_status(SWITCH_0));
    13         delay(40);
    14     }
    15 }

    这也引出了第二个差别——当 switch_changed 返回 true 时,我们不能直接知晓开关的状态,需要手动调用 switch_status ;而对于相应的按键操作,我们知道此时按键一定处于按下的状态。

    如果复位时开关状态为开,除了第一次拨动按键以前,LED总是与按键同步的。然而我们的要求是保持同步,当然包括一开始的时候。为了获得正确的初始状态,我们可以在进入主循环前添加以下代码:

    1 if (switch_status(SWITCH_0))
    2     led_set(LED_GREEN, true);

    但事实上,这个问题根本没有那么麻烦,甚至不需要 switch_changed 函数——每次循环读取开关状态,再把LED设置成相应状态即可:

     1 #include <ee1/led.h>
     2 #include <ee1/switch.h>
     3 #include <ee1/delay.h>
     4 
     5 int main()
     6 {
     7     led_init();
     8     switch_init(PIN_NULL, PIN_NULL);
     9     while (1)
    10     {
    11         led_set(LED_GREEN, switch_status(SWITCH_0));
    12         delay(40);
    13     }
    14 }

    你一开始有没有想到这个简单的方案?如果有,并且第一反应就是这个,那你得开始逐渐改变思路了。这种方案在这个例子中可用,是因为对 led_set 和 switch_status 的调用的成本是很低的,每次循环都调用也没有问题。然而这并不是放之四海而皆准的,有些函数经不起这样频繁的调用。在那样的情况下,检测状态改变,再读取状态,是一种更好的方案。

    思考:在判定按键动作的函数中,前一次状态通过静态变量存储,其初值为真,保证第一次调用时函数不会返回真;对于开关动作,相应静态变量的初值应该是什么?

    作业:每个开关控制一个LED,一个按键控制开关是否启用;启用时要让LED与当前开关状态对应,禁用时要关闭所有LED。

  • 相关阅读:
    程序设计与算法(一)第3周测验(2020春季)
    程序设计与算法(一)第2周测验(2020春季)
    量化投资_波动和趋势能量比(传统盘整和趋势的量化表示)
    Matlab高级教程_第四篇:白噪声的MATALB生成方式
    数学之美_马尔科夫模型01
    Matlab高级教程_第四篇:Matlab高级函数_关键词:arrayfun
    Matlab高级教程_第四篇:Matlab高级函数_关键词:drawnow,addpoints,animatedline,getpoints
    Matlab高级教程_第二篇:关于MATLAB转C#过程中MWArray到C#数组,C#数组到MWArray相互转换
    Matlab高级教程_第二篇:关于MATLAB转C#过程中遇到输出两组参数的问题
    数学是什么?_基变换(线性代数)
  • 原文地址:https://www.cnblogs.com/jerry-fuyi/p/11553382.html
Copyright © 2011-2022 走看看