首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

嵌入式系統鍵盤處理架構設計:功能鍵狀態機與數字輸入綁定機制

     編輯:關於C語言

前言:鍵盤交互是人機介面的核心

嵌入式裝置無滑鼠、觸控,鍵盤是唯一輸入。功能鍵切換畫面、數字鍵輸入參數,邏輯交織複雜。本文提出結構化處理架構,借鑑 Windows 訊息機制,實現清晰、可擴展的按鍵處理。

一、功能鍵處理:畫面即視窗,按鍵即訊息

問題場景

主畫面按 Enter 進入「設定 XX」子畫面,同一顆鍵在不同畫面觸發完全不同動作。傳統巨大 switch-case 難以維護。

借鑑 Win32 架構

  • 畫面 ⇔ 視窗
  • 畫面元素(選單、按鈕)⇔ 視窗元素
  • 按鍵 ⇔ 訊息
  • 每個畫面擁有訊息處理函數(Callback)
  • 訊息分發 → 焦點元素 → 元素處理函數

資料結構設計


#define ELEMENT_NUM 10

typedef struct {
    BYTE ID;
    void (*OnOk)(void);
    void (*OnCancel)(void);
    // ... 其他事件處理函數指標
} ELEMENT;

typedef struct {
    BYTE currentFocus;           // 當前焦點元素 ID
    ELEMENT element[ELEMENT_NUM]; // 畫面元素陣列
    void (*messageFun)(BYTE keyValue); // 訊息處理函數
} WINDOW;

訊息處理函數範例


void MessageFunction(BYTE keyValue) {
    BYTE i = 0;
    // 尋找焦點元素
    while (i < ELEMENT_NUM && element[i].ID != currentFocus)
        i++;

    if (i < ELEMENT_NUM) { // 找到焦點元素
        switch (keyValue) {
            case KEY_OK:
                if (element[i].OnOk) element[i].OnOk();
                break;
            case KEY_CANCEL:
                if (element[i].OnCancel) element[i].OnCancel();
                break;
            // ... 其他鍵值
        }
    }
}

此即「訊息映射」機制。進階可參考 MFC MESSAGE_MAP 巨集實現編譯期綁定。

二、數字鍵處理:座標與數值綁定

痛點

使用者逐位輸入,每位對應螢幕特定座標,程式需記錄座標與數值,傳統分離變數管理極易出錯。

結構體綁定法


typedef struct {
    BYTE byNum;   // 輸入數值
    BYTE xPos;    // 顯示 X 座標
    BYTE yPos;    // 顯示 Y 座標
} InputNum, *LPInputNum;

InputNum inputElement[NUM_LENGTH]; // 輸入緩衝區
BYTE currentElementInputPlace = 0; // 當前輸入位置

數字鍵處理函數


extern void OnNumKey(BYTE num) {
    if (num == 0 || num == 1) { // 僅接受二進位
        // 1. 顯示輸入
        DrawText(inputElement[currentElementInputPlace].xPos,
                 inputElement[currentElementInputPlace].yPos,
                 "%1d", num);
        // 2. 記錄數值
        inputElement[currentElementInputPlace].byNum = num;
        // 3. 焦點右移
        MoveToRight();
    }
}

座標與數值綁定,處理邏輯緊湊清晰。

三、使用者輸入整理:雙向轉換

位元陣列 → 有效數值


void ConvertToXXX() {
    XXX = 0;
    for (BYTE i = 0; i < NUM_LENGTH; i++)
        XXX += inputElement[i].byNum * POWER(2, NUM_LENGTH - i - 1);
}

有效數值 → 位元陣列(反向顯示)


void ConvertFromXXX() {
    for (BYTE i = 0; i < NUM_LENGTH; i++)
        inputElement[i].byNum = (XXX / POWER(2, NUM_LENGTH - i - 1)) % 2;
}

註:二進位建議用位移 <</>> 取代 POWER,十進位則需冪運算。

四、架構優勢總結

傳統寫法本架構
巨大 switch-case 處理所有畫面按鍵每畫面獨立訊息函數,職責分離
焦點邏輯分散焦點屬於畫面,封裝於 WINDOW
數字輸入座標、數值分離管理InputNum 結構體綁定,原子化操作
新增畫面需修改核心邏輯新增 WINDOW 實例,註冊訊息函數即可

五、程式設計哲學啟示

計算機科學知識具有普遍相通性。Windows 訊息機制、MFC 訊息映射、瀏覽器事件冒泡,本質相同。精通組合語言、C、C++(或 Java)三大核心語言,觸類旁通,新技術不過是舊概念的新包裝。夯實基本功,勝過追逐潮流。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved