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){这里是处理长按的代码}
|
|
|
|
|
|