低成本的單色LCD在工業(yè)領(lǐng)域應(yīng)用非常廣泛,英利公司提供的基于嵌入式Linux平臺的EM9160支持外接單色LCD屏,目前應(yīng)用得比較多的規(guī)格包括有LCD320x240、LCD240x128、LCD128x64、LCD160x160等。在實際應(yīng)用中有許多對于菜單界面操作的需求,需要客戶根據(jù)應(yīng)用的具體要求自行構(gòu)建菜單顯示界面,本文將重點介紹這方面的內(nèi)容。
基于菜單界面操作過程實質(zhì)一個簡單的交互式操作,需要實時響應(yīng)鍵盤消息、定時消息等。嵌入式Linux操作系統(tǒng)是一個實時多任務(wù)系統(tǒng),可以利用多線程的方式來實現(xiàn)各個應(yīng)用請求的響應(yīng)。在本案例是通過創(chuàng)建多個線程的方式來實現(xiàn)對于鍵盤、定時任務(wù)的實時響應(yīng),從而實現(xiàn)對于菜單界面的操作。
下面分兩個部分來介紹該例程:
1、應(yīng)用程序框架
為了便于程序的設(shè)計和管理,利用了Linux多任務(wù)的編程優(yōu)勢,利用內(nèi)核的任務(wù)調(diào)度機制,采用面向?qū)ο蟮?a href="http://wenjunhu.com/tags/C++/" target="_blank">C++編程將各個應(yīng)用功能模塊化。在該例程中需要實現(xiàn)的響應(yīng)功能:鍵盤和定時任務(wù)的響應(yīng),在應(yīng)用程序中通過創(chuàng)建兩個線程來實現(xiàn)。
在該程序例程中main(…)函數(shù),首先進行初始化操作,包括對于LCD屏的初始化、菜單界面的初始化操作等;然后是創(chuàng)建鍵盤處理線程、再進入主線程,主線程的功能主要是處理定時任務(wù),在本方案中實現(xiàn)的是定時顯示界面刷新。如下圖所示:
// LCD顯示屏的初始化操作
i1 = LCD_Init( LCD_160160 );
if( i1《0 )
{
printf( ‘LCD Init fail!\n’ );
}
LCD_LoadSmallFnt( );
LCD_SetMode( 1 ); // set to XOR mode
LCD_SetFont( 12 ); // 設(shè)置漢字顯示為12點陣模式
// 加載缺省菜單界面
status = MenuManager.LoadMenu( );
if( status 《 0 )
{
printf( ‘status=%d\n’, status);
return status;
}
MenuManager.Show( );
MenuManager.Update();
// 打開鍵盤設(shè)備,并啟動鍵盤處理線程
KeyManager.Open( );
for( ExitFlag=0; ; )
{
if( ExitFlag )
{
break;
}
// 延時1S 執(zhí)行一次顯示刷新操作
sleep( 1 );
MenuManager.Update( );
}
// 關(guān)閉鍵盤設(shè)備,并卸載鍵盤處理線程
KeyManager.Close( );
LCD_DeInit( );
return 0;
其中的主線程很簡單,只是定時處理的任務(wù),直接調(diào)用sleep(1)函數(shù)阻塞等待。
鍵盤處理線程主要檢查是否有鍵按下,一旦有鍵按下則讀取相應(yīng)的鍵碼值,并作相應(yīng)的響應(yīng)處理。當一個鍵按下時,EM9160內(nèi)核中的鍵盤驅(qū)動程序?qū)⒌玫降挠行фI碼存儲在內(nèi)部的緩沖區(qū)中,應(yīng)用程序可直接通過read函數(shù)讀取鍵碼。
應(yīng)用程序打開矩陣鍵盤驅(qū)動程序的方法還是打開相應(yīng)的設(shè)備文件,如下:
key_fd = open(‘/dev/em9x60_keypad’, O_RDONLY | O_NONBLOCK);
以下為讀取鍵碼值并作相應(yīng)的處理代碼:
FD_ZERO(&fs_read);
FD_SET(key_fd,&fs_read);
time.tv_sec = 0;
time.tv_usec = 100000; //timeout = 100ms
fs_sel = select(key_fd+1, &fs_read, NULL, NULL, &time);
if(fs_sel)
{
//data available, so get it!
len = read(key_fd, &KeyCode, sizeof(KeyCode));
if(len 》 0)
{
//printf(‘len=%d KeyCode= 0x%x\r\n’, len, KeyCode);
switch( KeyCode )
{
case 0x011b:
KeyCmd = ESC;
MenuManager.Key_ESC( );
break;
case 0x1c0d:
KeyCmd = ENTER;
MenuManager.Key_ENTER( );
break;
case 0x0635:
KeyCmd = UP;
MenuManager.Key_SHIFT( 1 );
break;
case 0x0938:
KeyCmd = DOWN;
MenuManager.Key_SHIFT( 0 );
break;
case 0x0837:
KeyCmd = LEFT;
break;
case 0x0939:
KeyCmd = RIGHT;
break;
}
}
}
2、菜單界面設(shè)計
在本例程中主要是針對一個基于LCD160x160顯示終端所設(shè)計的二級菜單顯示界面,功能鍵有六個:Key_ESC、Key_Enter以及Key_UP、Key_Down、Key_Left、Key_Right鍵,通過Key_UP、Key_Down鍵選擇菜單項,Key_Enter確認鍵來進入下一級,Key_ESC返回上一級菜單。
菜單的顯示和管理是通過C++方式來實現(xiàn),Class Item定義菜單中各個菜單項的顯示特性以及操作特性;Class Menu定義了菜單的特性,其中包含又對于菜單中各個菜單項管理的功能;Class MenuManager是一個菜單管理類,這個類實現(xiàn)了對于各個菜單的管理和操作特性,相當于一個人機交互界面的功能。它們定義分別在 Item.h Menu.h文件中。
為了增加菜單設(shè)計的靈活性,對于各個菜單界面的顯示內(nèi)容采用了讀取配置文件的方式,即在配置文件中定義各個菜單的顯示名稱和顯示位置,如:
// item的類型 顯示名稱 X位置 Y位置 下一級菜單名稱
item=101 D1 0 0
item=100 D0 100 0
item=301 測量點數(shù)據(jù)顯示 0 32 menu1
item=301 參數(shù)設(shè)置與查看 0 48 menu2
item=301 終端管理與維護 0 64 menu3
根據(jù)該配置文件所形成的顯示菜單如下:
-
Linux
+關(guān)注
關(guān)注
87文章
11304瀏覽量
209476 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6085瀏覽量
35329
發(fā)布評論請先 登錄
相關(guān)推薦
評論