用于打印qwerty键的9键键盘的逻辑

时间:2010-10-16 13:46:03

标签: c embedded keyboard

我的设备有9个按键,就像普通的手机一样。 我想使用这9个键来打印像ABCD这样的普通字母,就像手机让你一样。

这是一个嵌入式系统编程项目。我无法弄清楚实现此功能的逻辑。

我通过轮询而非中断来检测密钥。

有人可以帮忙吗?如果你能指出相关资源,我将不胜感激。

4 个答案:

答案 0 :(得分:6)

这是一个小小的键盘解码演示,可以帮助您顺利完成任务。您需要重写硬件的密钥扫描例程。此外,连续两次选择相同的数字需要某种超时。您还应该在确定如何添加对大小写,标点符号和元键的支持时遇到一些麻烦......

#include <stdio.h>

#define NUM_KEYS 10
#define NUM_PHASES 6

char KeyMap[NUM_KEYS][NUM_PHASES] =
    {   { '0',   0,   0,   0,   0,   0 },
        { '1',   0,   0,   0,   0,   0 },
        { '2', 'A', 'B', 'C',   0,   0 },
        { '3', 'D', 'E', 'F',   0,   0 },
        { '4', 'G', 'H', 'I',   0,   0 },
        { '5', 'J', 'K', 'L',   0,   0 },
        { '6', 'M', 'N', 'O',   0,   0 },
        { '7', 'P', 'Q', 'R', 'S',   0 },
        { '8', 'T', 'U', 'V',   0,   0 },
        { '9', 'W', 'X', 'Y', 'Z',   0 }    };

char KeyGet()
{
    char key;

    /* do whatever it takes to scan your
       keyboard and return the _numeric_ digit. */

    /* for this test simulate with console input */
    key = getc(stdin);

    if ((key >= '0') && (key <= '9'))
    {
        key -= 0x30;
    }
    else
    {
        key = 0;
    }

    return key;
}

char DecodeKey(char NewKey, char *pOldKey, int *pPhase)
{
    char ch = 0;

    /* Validate Phase */
    if ((*pPhase < 0) || (*pPhase >= NUM_PHASES))
    {
        *pPhase = 0;
    }

    /* see if a different key was pressed than last time */
    /* if it was then restart the phase counter */
    if (NewKey != *pOldKey)
    {
        *pPhase = 0;
        *pOldKey = NewKey;
    }

    /* Validate Key */
    if ((NewKey >= 0) && (NewKey < NUM_KEYS))
    {
        ch = KeyMap[(int)NewKey][*pPhase];

        /* if the phase position is NULL, just get the numeric digit */
        if (ch == 0)
        {
            *pPhase = 0;
            ch = KeyMap[(int)NewKey][*pPhase];
        }

        /* bump the phase */
        ++(*pPhase);

        if (*pPhase >= NUM_PHASES)
        {
            *pPhase = 0;
        }
    }

    return ch;
}

int main()
{
    char nk;        /* new key */
    char ok = 0;    /* old key */
    char c;         /* resulting character */
    int phase = 0;  /* tracks the key presses */

    while (1)
    {
        /* get a key */
        nk = KeyGet();

        /* convert it to a character */
        c = DecodeKey(nk, &ok, &phase);

        if (c != 0)
        {
            printf("%c", c);
        }
    }

    return 0;
}

答案 1 :(得分:1)

要做一个非常好的设计,你需要一个键盘输入程序,可以判断键何时被保持一段时间,以及它们何时被释放。在按下数字后的短时间内,您应该将光标保持在新键入的字符上;如果再次按下相同的数字,则应更改新键入的字符。如果键入了另一个数字,请将所​​选数字设为“永久”,并将光标显示在新键的字符上。如果没有按键一秒左右,请将光标前进到下一个位置。如果在光标位于新键入的数字上时按下enter键,则只需前进光标。如果它在光标自动前进的大约1/4秒内被推动,则什么也不做。如果在光标不在某个字符上并且不仅仅是自动前进时按下它,请确认输入。

答案 2 :(得分:0)

将控制器的6个引脚用于键盘P0-> P6。将3列P0-> P3和3行连接到P4-> P6。通过代码将所有引脚置为高电平。通过在每列上给出低值来扫描每一行。因此,通过获取特定的行和列,您将能够获得输入的密钥.. 希望你能找到这个......

答案 3 :(得分:0)

改编Amardeep的答案:

char KeyMap[NUM_KEYS][NUM_PHASES] =
{   { '0',   0,   0,   0,   0,   0 },
    { '1',   0,   0,   0,   0,   0 },
    { '2', 'A', 'B', 'C',   0,   0 },
    { '3', 'D', 'E', 'F',   0,   0 },
    { '4', 'G', 'H', 'I',   0,   0 },
    { '5', 'J', 'K', 'L',   0,   0 },
    { '6', 'M', 'N', 'O',   0,   0 },
    { '7', 'P', 'Q', 'R', 'S',   0 },
    { '8', 'T', 'U', 'V',   0,   0 },
    { '9', 'W', 'X', 'Y', 'Z',   0 }    };


//Gets the system time, e.g. as number of timer ticks since power up.  You write this.
sometype GetSystemTime();

//Checks if key has been pressed.  Returns 0-9 if a key was pressed or -1 if no key was pressed.  You write this.
int KeyAvailable();

int main()
{ 
 const sometype PHASE_WAIT = somevalue; //The delay before shifting to the next character.
 char keyBuffer[BUFFER_SIZE]; //The input buffer.
 int  keyIndex = 0; //The index into keyBuffer. 
 int keyPress1 = -1, keyPress2; // keyboard inputs.
 sometype lastKeyPressTime; // The time a key was last pressed.
 int numKeyPresses; // The number of times the same key has been pressed this phase.



 /* keyboard processing loop. */
 while ( 1 )
 {
  if ( ( GetSystemTime() - lastKeyPressTime > PHASE_WAIT ) && ( -1 != keyPress1 ) )
  {
   // Phase timed out.  Commit current character.
   keyBuffer[keyIndex++] = KeyMap[keyPress1][numKeyPresses - 1];
   keyPress1 = -1;
  }
  if ( ( keyPress2 = KeyAvailable() ) > -1 )
  {
   // Key pressed. 
   lastKeyPressTime = GetSystemTime();
   if ( ( keyPress2 != keyPress1 ) && ( -1 != keyPress1 ) )
   {
    // Different than last key.  Commit current character and start a new one.
    keyBuffer[keyIndex++] = KeyMap[keypress1][numKeyPresses - 1];
    numKeyPresses = 1; // Yes, I"m using 1-based indexing.  Deal.

   }else if ( keyPress2 == keyPress1 )
   {
    // Pressed same key multiple times in same phase. 
    numKeyPresses = ((numKeyPresses) % KEYMAPROWSIZE) + 1;
    if ( 0 == KeyMap[keypress2][numKeyPresses - 1] )
    {
     //Loop back to first 'valid' character associated with this key.
     numKeyPresses = 1;
    }
   }else // -1 == keyPress1 
   {
    // Pressed new key. Start new phase. 
    numKeyPresses = 1;
   }
   keyPress1 = keyPress2.
  }
 } 

}