新聞中心

        EEPW首頁 > 消費電子 > C語言嵌入式系統編程修煉之鍵盤操作篇

        C語言嵌入式系統編程修煉之鍵盤操作篇

        ——
        作者: 時間:2006-12-19 來源: 收藏

        功能鍵的問題在于,用戶界面并非固定的,用戶功能鍵的選擇將使屏幕畫面處于不同的顯示狀態下。

        處理功能鍵

          功能鍵的問題在于,用戶界面并非固定的,用戶功能鍵的選擇將使屏幕畫面處于不同的顯示狀態下。例如,主畫面如圖1:





        圖1 主畫面

          當用戶在設置XX上按下Enter鍵之后,畫面就切換到了設置XX的界面,如圖2:






        圖2 切換到設置XX畫面

          程序如何判斷用戶處于哪一畫面,并在該畫面的程序狀態下調用對應的功能鍵處理函數,而且保證良好的結構,是一個值得思考的問題。

          讓我們來看看WIN32中用到的"窗口"概念,當消息(message)被發送給不同窗口的時候,該窗口的消息處理函數(是一個callback函數)最終被調用,而在該窗口的消息處理函數中,又根據消息的類型調用了該窗口中的對應處理函數。通過這種方式,WIN32有效的組織了不同的窗口,并處理不同窗口情況下的消息。

          我們從中學習到的就是:

          (1)將不同的畫面類比為WIN32中不同的窗口,將窗口中的各種元素(菜單、按鈕等)包含在窗口之中;

          (2)給各個畫面提供一個功能鍵"消息"處理函數,該函數接收按鍵信息為參數;

          (3)在各畫面的功能鍵"消息"處理函數中,判斷按鍵類型和當前焦點元素,并調用對應元素的按鍵處理函數。

        /* 將窗口元素、消息處理函數封裝在窗口中 */
        struct windows
        {
         BYTE currentFocus;
         ELEMENT element[ELEMENT_NUM];
         void (*messageFun) (BYTE keyValue);
         …
        };
        /* 消息處理函數 */
        void messageFunction(BYTE keyValue)
        {
         BYTE i = 0;
         /* 獲得焦點元素 */
         while ( (element [i].ID!= currentFocus)&& (i < ELEMENT_NUM) )
         
         /* "消息映射" */
         if(i < ELEMENT_NUM)
         {
          switch(keyValue)
          {
           case OK:
            element[i].OnOk();
            break;
           …
          }
         }
        }

          在窗口的消息處理函數中調用相應元素按鍵函數的過程類似于"消息映射",這是我們從WIN32中學習到的。到了一個境界,很多東西都是相通的了。其它地方的思想可以拿過來為我所用,是為編程中的"拿來主"。

          在這個例子中,如果我們還想玩得更大一點,我們可以借鑒MFC中處理MESSAGE_MAP的方法,我們也可以學習MFC定義幾個精妙的宏來實現"消息映射"。

        處理數字鍵

          用戶輸入數字時是一位一位輸入的,每一位的輸入都對應著屏幕上的一個顯示位置(x坐標,y坐標)。此外,程序還需要記錄該位置輸入的值,所以有效組織用戶數字輸入的最佳方式是定義一個結構體,將坐標和數值捆綁在一起:

        /* 用戶數字輸入結構體 */
        typedef struct tagInputNum
        {
         BYTE byNum; /* 接收用戶輸入賦值 */
         BYTE xPos; /* 數字輸入在屏幕上的顯示位置x坐標 */
         BYTE yPos; /* 數字輸入在屏幕上的顯示位置y坐標 */
        }InputNum, *LPInputNum;

          那么接收用戶輸入就可以定義一個結構體數組,用數組中的各位組成一個完整的數字:

        InputNum inputElement[NUM_LENGTH]; /* 接收用戶數字輸入的數組 */
        /* 數字按鍵處理函數 */
        extern void onNumKey(BYTE num)
        {
        if(num==0|| num==1) /* 只接收二進制輸入 */
        {
         /* 在屏幕上顯示用戶輸入 */
         DrawText(inputElement[currentElementInputPlace].xPos, inputElement[currentElementInputPlace].yPos, "%1d", num);
         /* 將輸入賦值給數組元素 */
         inputElement[currentElementInputPlace].byNum = num;
         /* 焦點及光標右移 */
         moveToRight();
        }
        }  

          將數字每一位輸入的坐標和輸入值捆綁后,在數字鍵處理函數中就可以較有結構的組織程序,使程序顯得很緊湊。

        整理用戶輸入

          繼續第2節的例子,在第2節的onNumKey函數中,只是獲取了數字的每一位,因而我們需要將其轉為有效數據,譬如要轉為有效的XXX數據,其方法是:

        /* 從2進制數據位轉為有效數據:XXX */
        void convertToXXX()
        {
         BYTE i;
         XXX = 0;
         for (i = 0; i < NUM_LENGTH; i++)
         {
          XXX += inputElement[i].byNum*power(2, NUM_LENGTH - i - 1);
         }
        }

          反之,我們也可能需要在屏幕上顯示那些有效的數據位,因為我們也需要能夠反向轉:

        /* 從有效數據轉為2進制數據位:XXX */
        void convertFromXXX()
        {
         BYTE i;
         XXX = 0;
         for (i = 0; i < NUM_LENGTH; i++)
         {
          inputElement[i].byNum = XXX / power(2, NUM_LENGTH - i - 1) % 2;
         }
        }

          當然在上面的例子中,因為數據是2進制的,用power函數不是很好的選擇,直接用"<< >>"移位操作效率更高,我們僅是為了說明問題的方便。試想,如果用戶輸入是十進制的,power函數或許是唯一的選擇了。

        總結

          本篇給出了鍵盤操作所涉及的各個方面:功能鍵處理、數字鍵處理及用戶輸入整理,基本上提供了一個全套的按鍵處理方案。對于功能鍵處理方法,將LCD屏幕與Windows窗口進行類比,提出了較新穎地解決屏幕、鍵盤繁雜交互問題的方案。

          計算機學的許多知識都具有相通性,因而,不斷追趕時髦技術而忽略基本功的做法是徒勞無意的。我們最多需要"精通"三種語言(精通,一個在如今的求職簡歷里泛濫成災的詞語),最佳拍檔是匯編、C、C++(或JAVA),很顯然,如果你"精通"了這三種語言,其它語言你應該是可以很快"熟悉"的,否則你就沒有"精通"它們。

        linux操作系統文章專題:linux操作系統詳解(linux不再難懂)


        關鍵詞: C語言 編程 嵌入式

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 剑川县| 从化市| 西林县| 伊金霍洛旗| 建宁县| 民乐县| 盱眙县| 天峻县| 南通市| 梅州市| 叙永县| 平山县| 石林| 紫云| 密云县| 西乌珠穆沁旗| 古田县| 德清县| 通化县| 额尔古纳市| 威信县| 舞阳县| 朔州市| 阿勒泰市| 墨竹工卡县| 卢龙县| 绵竹市| 宁晋县| 精河县| 连江县| 武功县| 穆棱市| 夹江县| 潼关县| 馆陶县| 绥化市| 滁州市| 横峰县| 双牌县| 江永县| 美姑县|