2010-10-16 130 views
2

我有一個設備有9個鍵就像一個普通的手機。 我想打印正常的字母如ABCD使用這9個鍵完全按照手機讓你這樣做。邏輯9鍵鍵盤打印QWERTY鍵

這是一個嵌入式系統編程項目。我無法弄清楚實現這個功能的邏輯。

我通過輪詢而不是中斷來檢測密鑰。

有人可以幫忙嗎?如果您能指出相關資源,我將不勝感激。

回答

6

這是一個小鍵盤解碼演示程序,應該可以幫助您順利完成任務。您需要重新編寫硬件的主要掃描例程。另外,連續兩次選擇相同的數字會有某種超時。你也應該有一點麻煩搞清楚如何添加大寫,標點符號和Meta鍵支持...

#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; 
} 
+0

鍵= GETC(標準輸入);是阻止呼叫? – 2010-10-17 10:13:32

+0

@Akshar:是的,這是一個用於此演示的阻止呼叫。標準C沒有非阻塞控制檯輸入庫例程。實施者需要爲實際目標編寫一個自定義例程。 – 2010-10-17 11:18:09

1

要做到一個很好的設計,你需要一個鍵盤輸入程序,可以告訴你何時按鍵已經被擱置了一段時間,並且當它們被釋放了一段時間。在按下數字後的短時間內,應該將光標保持在新輸入的字符上;如果再次按下相同的數字,則應該更改新輸入的字符。如果輸入另一位數字,則將選定數字設爲「永久」,並將光標顯示在新密鑰的字符上。如果沒有按鍵被按下一秒左右,請將光標移到下一個位置。如果在光標位於新輸入的數字上時按下Enter鍵,只需前進光標即可。如果它在光標自動前進的大約1/4秒內被推入,則不執行任何操作。如果在光標不在字符上並且不僅僅是自動提前時被按下,請確認輸入。

0

把你的控制器的6個引腳用於鍵盤P0-> P6。將你的3列P0-> P3和3行連接到P4-> P6。用代碼將所有引腳拉高。通過在每列上設置低位來掃描每行。因此,通過獲取特定的行和列,你將能夠獲得進入關鍵.. 希望你看這個..

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. 
    } 
} 

}