我想要检测按键矩阵中开关的释放。考虑一个4*4键矩阵,微控制器的扫描可以很容易地完成,以检测按键。但是,我想在发生释放时也检测到它们。有没有更有效的方法来做到这一点,而不是仅仅对未按下的每个状态更改中断进行另一次扫描?
发布于 2019-12-25 06:57:07
矩阵键盘扫描不需要任何中断。您应该创建定期调用的扫描函数。最好的方法是将每个键作为位存储在某个变量中-您有4x4键盘,所以uint16_t将完美地适合您。XOR运算符非常适合检测按键变化。另外,不要忘记实现一些关键的去抖动功能。
我建议使用下面的“伪”代码或类似的代码(我希望其中没有bug ):
#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");
}
}https://stackoverflow.com/questions/59472548
复制相似问题