首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用微控制器检测键盘矩阵中开关的释放?

如何使用微控制器检测键盘矩阵中开关的释放?
EN

Stack Overflow用户
提问于 2019-12-25 02:55:39
回答 1查看 231关注 0票数 0

我想要检测按键矩阵中开关的释放。考虑一个4*4键矩阵,微控制器的扫描可以很容易地完成,以检测按键。但是,我想在发生释放时也检测到它们。有没有更有效的方法来做到这一点,而不是仅仅对未按下的每个状态更改中断进行另一次扫描?

EN

回答 1

Stack Overflow用户

发布于 2019-12-25 06:57:07

矩阵键盘扫描不需要任何中断。您应该创建定期调用的扫描函数。最好的方法是将每个键作为位存储在某个变量中-您有4x4键盘,所以uint16_t将完美地适合您。XOR运算符非常适合检测按键变化。另外,不要忘记实现一些关键的去抖动功能。

我建议使用下面的“伪”代码或类似的代码(我希望其中没有bug ):

代码语言:javascript
复制
#define ROW_COUNT         4
#define COL_COUNT         4
#define DEBOUNCE_TIMEOUT  10   // In milliseconds

typedef uint16_t KeyState;

// This function returns current keyboard state and
// fills upKeys with keys that were pressed and downKeys with keys that were released
// It expects that key down is logic H, up is logic L
KeyState KeyboardState(KeyState* upKeys, KeyState* downKeys)
{
  static KeyState lastState = 0;
  static KeyState lastValidState = 0;
  static Timestamp lastTimestamp = 0;
  KeyState currentState = 0;
  uint8_t x, y;

  // Set defaults
  if (upKeys)
    *upKeys = 0;
  if (downKeys)
    *downKeys = 0;

  for(y = 0; y < ROW_COUNT; y++)
  {
    // Set appropriate row pin to H
    SetRowPinH(y);
    // Just to be sure that any parasitic capacitance gets charged
    SleepMicro(10);
    for(x = 0; x < COL_COUNT; x++)
    {
      // Check key pressed
      if (IsColPinSet(x))
        currentState |= 1 << ((y * COL_COUNT) + x);
    }
    // And don't forget to set row pin back to L
    SetRowPinL(y);
  }

  // Now lets do debouncing - this is important for good functionality
  // Matrix state should not change for some time to accept result
  if (lastState == currentState)
  {
    // Check if time has passed
    if ((TimestampNowMilli() - lastTimestampMilli) >= DEBOUNCE_TIMEOUT)
    {
      // Let's detect up/down changes first - it's easy, just use XOR for change detection
      if (upKeys)
        *upKeys = currentState & (lastValidState ^ currentState);
      if (downKeys)
        *downKeys = (~currentState) & (lastValidState ^ currentState);
      lastValidState = currentState;
    }
  }
  else
  {
    // Current state differs from previous - reset timer
    lastTimestampMilli = TimestampNowMilli();
  }
  lastState = currentState;

  return lastValidState;
}

int main()
{
  KeyState upKeys;
  KeyState downKeys;
  KeyState currentKeys;
  while(1)
  {
    currentKeys = KeyboardState(&upKeys, &downKeys);
    if (upKeys & 0x0001)
      printf("Key 1 pressed\n");
    if (downKeys & 0x0001)
      printf("Key 1 released\n");
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59472548

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档