极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12160|回复: 1

arduino宏的应用实例1--用宏处理按键消息

[复制链接]
发表于 2016-4-21 22:57:14 | 显示全部楼层 |阅读模式
本帖最后由 wwwymq 于 2016-4-25 22:08 编辑

c++的宏真是一个很有意思的东西,合理的运用宏能让你少写很多的重复代码。
下面说说宏在处理按键消息命令时的应用。

首先我参考了下面链接中的按键处理方式:新型的按键扫描程序,仅三行程序
效果不错,于是有了以下的几句:
  1. bool Trg = false;
  2.   bool Cont = false;
  3.   bool Pop = false;
  4.   bool ReadData = !digitalRead(7);           // 1,读端口数据即端口字节值,异或运算(或->取反)
  5.   Trg = ReadData & (ReadData ^ Cont);   // 2,触发即按下按键
  6.   Pop = Cont != ReadData & !Trg;        // 3, 按键弹起检测
  7.   delay(20);//每20ms扫描一次
复制代码


接下来,需要把这几句封装在宏中,看了关于一些对宏的介绍,感觉有一种解释对宏本质解释的最为精辟:宏是一个代码生成器。

我们用宏是为了生成重复的代码。
首先我们要在使用的变量前加上static,因为这是每一块代码私有的变量。
然后因为要检测多个按键,以及处理其他的函数,因此delay是不能要的,用millis()函数替换掉。

得到了以下的代码:
[pre lang="arduino" line="1" file="keyRead"]#define readKey(x,onTrigger,onPop) do{\
    static bool Trg = false;\
    static bool Cont = false;\
    static bool Pop = false;\
    static unsigned long timdel = millis();\
    if (millis() - timdel >= 20) {\
      bool ReadData = !digitalRead(x);\
      Trg = ReadData & (ReadData ^ Cont); \
      Pop = Cont != ReadData & !Trg; \
      Cont = ReadData; \
      if (Trg) {\
        onTrigger;\
      }\
      if (Pop) {\
        onPop; \
      }\
      timdel = millis(); \
    }\
  } while (0)
#define keyReadInit(x) do{\
    pinMode(x, INPUT_PULLUP);\
  } while (0)
int c = 0;
void setup() {
  // put your setup code here, to run once:
  keyReadInit(7);
  keyReadInit(8);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  readKey(7, Serial.println("Trigger7"), Serial.println("Pop7"));
  readKey(8, void(), Serial.println("Pop8"));
}[/code]

其中定义了两个宏:
1.readKey(x,onTrigger,onPop)
2.keyReadInit(x)

注意宏的外面都加上了do{}while(0)至于为什么要加,大家可以百度。
多行的宏每行结尾处要加"\"。

其中keyReadInit(x)用于在setup中初始化io。
设置模式为输入,启用内置的上拉电阻。

readKey(x,onTrigger,onPop)用于处理按键的事件
onTrigger和onPop分别用于处理按下和弹起时的动作,这里只是做了简单的替换,因此可以是各种表达式。
比如:
  1. readKey(7, Serial.println("Trigger7"), Serial.println("Pop7"));
  2. readKey(8, void(), Serial.println("Pop8"));
复制代码

端口7在按下和弹起时分别打印语句。
端口8只在弹起时打印语句。

宏只要经过简单的改造就能处理长按事件:if(Cont){这里是处理长按的代码}
回复

使用道具 举报

发表于 2016-4-22 13:01:53 | 显示全部楼层
谢谢分享,很好参考价值!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-27 02:29 , Processed in 0.054079 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表