6979浏览
查看: 6979|回复: 2

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

[复制链接]
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()函数替换掉。

得到了以下的代码:
  1. #define readKey(x,onTrigger,onPop) do{\
  2.     static bool Trg = false;\
  3.     static bool Cont = false;\
  4.     static bool Pop = false;\
  5.     static unsigned long timdel = millis();\
  6.     if (millis() - timdel >= 20) {\
  7.       bool ReadData = !digitalRead(x);\
  8.       Trg = ReadData & (ReadData ^ Cont); \
  9.       Pop = Cont != ReadData & !Trg; \
  10.       Cont = ReadData; \
  11.       if (Trg) {\
  12.         onTrigger;\
  13.       }\
  14.       if (Pop) {\
  15.         onPop; \
  16.       }\
  17.       timdel = millis(); \
  18.     }\
  19.   } while (0)
  20. #define keyReadInit(x) do{\
  21.     pinMode(x, INPUT_PULLUP);\
  22.   } while (0)
  23. int c = 0;
  24. void setup() {
  25.   // put your setup code here, to run once:
  26.   keyReadInit(7);
  27.   keyReadInit(8);
  28.   Serial.begin(9600);
  29. }
  30. void loop() {
  31.   // put your main code here, to run repeatedly:
  32.   readKey(7, Serial.println("Trigger7"), Serial.println("Pop7"));
  33.   readKey(8, void(), Serial.println("Pop8"));
  34. }
复制代码
其中定义了两个宏:
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){这里是处理长按的代码}

dsweiliang  初级技神

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

学习学习
回复

使用道具 举报

Dgh丶  学徒

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

牛逼
回复

使用道具 举报

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

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail