從零開始構建計算機系統——二維圖形庫(字串輸出、鍵盤輸入)

weixin_33860722發表於2018-01-02

四、輸出字串

對於字串的輸出,我們需要思考兩個問題,一個是輸出的位置,一個是輸出的大小。

首先,我們假設螢幕的畫素柵格總共有256行、512列,那麼螢幕的畫素就是:256×512。聽起來很耳熟吧,對這就是我們經常說的螢幕的畫素。

一般對於字元,我們假設其字模空間定為11×8點陣,也就是11行、8列,如下圖所示,為字元A的字模示意圖:

9897093-f7891914a88aebf3

因此,字元A的字模陣列為:

{0x30,0x78,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc}

類似的,我們實現對所有的字元都做好計算,並按照一定的編碼順序儲存到陣列中,那麼我們就可以在需要使用的時候以字元的編碼為索引,從陣列中取出字模檔案。這樣的庫就叫做字型庫。這裡我們說一下字元編碼。

①漢字的區位碼與內碼

國家標準的漢字字符集(GB2312-80)在漢字作業系統中是以漢字型檔的形式提供的。漢字型檔結構有統一規定,即將漢字型檔分成94個區,每個區有94個漢字(以位作區別),每個漢字在漢字型檔中有確定的區和位編號(用兩個位元組),這就是所謂的區位碼。區位碼的第一個位元組表示區號,第二個位元組表示位號,因而只要知道了區位碼,就可以知道該漢字在字型檔中的地址。每個漢字在字型檔中是以點陣字模形式儲存的,當用儲存單元儲存該字模資訊時,將需要32位元組。在計算機內,英文字元是用一個位元組的ASCII碼錶示的,而對於眾多的漢字,需用兩個位元組才能代表,國家為此制定了統一標準,稱為國標碼。又規定國標碼在機內表示漢字時,將每個位元組的最高位置1。這些國標碼的兩位元組最高位加1後的程式碼稱為機器內的漢字程式碼,簡稱內碼。

②內碼轉換為區位碼與取字模

漢字內碼與區位碼有固定的轉換關係,即若漢字內碼為十六進位制數aaff,則區號qh和位號wh分別為 qh= aa-0xa0,wh=ff-0xa0。由於在中文DOS下,輸入漢字時,其相應的內碼即已在程式中存在,如同在西文DOS下,輸入英文字元時,其對應的ASCII也在程式中存在一樣。因而得知漢字內碼,將其轉換為區位碼,這樣就可以找出該漢字字模在字型檔中存放的地址,由此地址調出該32位元組漢字的內容(字模)。

綜合上述分析看,我們採用C語言程式碼進行簡要實現:

DrawCHS( x, y, QW)

x:繪製的起始橫座標

y:繪製的起始縱座標

QW:要繪製的漢字編碼

a獲取字模陣列:

pZK = &__CHS[ (  ( (QW >> 8) - 1 )*94 + (QW & 0x00FF)- 1 )*32 ];  

b逐行逐個點進行繪製

mask = 0x80;  

for( i = 0 ; i < 11 ; i++ )  

{  

for( j = 0 ; j < 8 ; j++ )  

    {  

if( buf & mask ) DrawPixel(x+j,y+i);  

        mask = mask >> 1;  

    }  

}  


9897093-3a814dbce73cffe1.jpg

五、鍵盤輸入

主要有兩種方式,一種是輪詢法,一種是中斷法。輪詢法中,系統需要週期性的查詢鍵盤的輸入情況,如果有輸入,就需要將輸入資料送到訊息佇列中。中斷法中,當鍵盤有輸入時,打斷系統的正常執行,系統立即中止當前的工作,獲取鍵盤的輸入並送到訊息佇列中。

如下圖所示,是一個4×4矩陣鍵盤,4行4列共16個按鈕,行線P10~P13為輸出線,列線P14~P17為輸入線。

9897093-ee48a6b62e7ba4b5

判斷哪個鍵按下的具體方法是:首先將微控制器將行線(P10~P13)全部輸出低電平,此時讀入列線資料,若列線全為高電平則沒有鍵按下,當列線有出現低電平時呼叫延時程式以此來去除按鍵抖動。延時完成後再判斷是否有低電平,如果此時讀入列線資料還是有低電平,則說明確實有鍵按下。

最後一步確定鍵值。現在我們以第二行的S5鍵為例,若按下S5後我們應該怎麼得到這個鍵值呢?當判斷確實有鍵按下之後,行線輪流輸出低電平,根據讀入列線的資料可以確定鍵值。首先,微控制器將P10輸出為低電平,其它P11~P13輸出高電平,此時讀取列線的資料全為高電平,說明沒有在第一行有鍵按下;其次,微控制器將P11輸出低電平,其它P10、P12、P13仍為高電平,此時再來讀取列線資料,發現列線讀到的資料有低電平,數值為1011(0x0B),如果我們的鍵盤佈局已經確定,那麼0x0B就代表S5的值了。

按鍵消抖:按鍵消抖通常的按鍵所用開關為機械彈性開關,當機械觸點斷開、閉合時,由於機械觸點的彈性作用,一個按鍵開關在閉合時不會馬上穩定地接通,在斷開時也不會一下子斷開。因而在閉合及斷開的瞬間均伴隨有一連串的抖動,為了不產生這種現象而作的措施就是按鍵消抖。

9897093-2216d88d84516585

抖動時間:其長短由按鍵的機械特性決定,一般為5ms~10ms。這是一個很重要的時間引數,在很多場合都要用到。按鍵穩定閉合時間的長短則是由操作人員的按鍵動作決定的,一般為零點幾秒至數秒。鍵抖動會引起一次按鍵被誤讀多次。為確保CPU對鍵的一次閉合僅作一次處理,必須去除鍵抖動。在鍵閉合穩定時讀取鍵的狀態,並且必須判別到鍵釋放穩定後再作處理。

按鍵判斷完畢後,需要對按鍵訊息進行打包,然後送入訊息佇列中。在分時作業系統中,一般需要等到專門處理訊息佇列的任務獲取CPU控制權,還有一種就是訊息進入佇列後直接觸發等待此訊息的任務。如果一個任務需要等待鍵盤的輸入,它有兩種處理方式:一種是同步式的,一種是非同步式或阻塞式。通常我們會採取阻塞式的方式,但是對於一些特殊的場景,比如對實時性要求特別高的任務,或者必須等待鍵盤的某個輸入之後才能繼續往下執行的任務。阻塞式在程式設計中主要通過回撥的方式實現,系統需要提供標準的API。

相關文章