我想检测按键矩阵中开关的释放。考虑 4*4 键矩阵,微 Controller 的扫描可以轻松完成以检测按键 PRESS。但是,我还想在释放发生时检测它们。 有没有比仅对未按下的状态更改中断进行另一次扫描更有效的方法?
最佳答案
矩阵键盘扫描不需要任何中断。您应该创建将定期调用的扫描函数。最好的方法是将每个键存储为某个变量中的一个位 - 您有 4x4 键盘,因此 uint16_t 将完全适合。 XOR 运算符非常适合 key 更改检测。另外不要忘记实现一些关键的去抖功能。
我建议遵循“伪”代码或类似的代码(我希望其中没有错误):
#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");
}
}
关于c - 如何使用微 Controller 检测键盘矩阵中开关的释放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59472548/