大连林海 发表于 2016-5-1 08:09:58

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

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

首先我参考了下面链接中的按键处理方式:新型的按键扫描程序,仅三行程序
效果不错,于是有了以下的几句:bool Trg = false;
bool Cont = false;
bool Pop = false;
bool ReadData = !digitalRead(7);         // 1,读端口数据即端口字节值,异或运算(或->取反)
Trg = ReadData & (ReadData ^ Cont);   // 2,触发即按下按键
Pop = Cont != ReadData & !Trg;      // 3, 按键弹起检测
delay(20);//每20ms扫描一次
接下来,需要把这几句封装在宏中,看了关于一些对宏的介绍,感觉有一种解释对宏本质解释的最为精辟:宏是一个代码生成器。

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

得到了以下的代码:#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"));
}
其中定义了两个宏:
1.readKey(x,onTrigger,onPop)
2.keyReadInit(x)

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

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

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

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

dsweiliang 发表于 2016-5-4 09:36:59

学习学习

Dgh丶 发表于 2019-12-27 16:40:07

牛逼
页: [1]
查看完整版本: arduino宏的应用实例1--用宏处理按键消息(转)