<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 基于狀態(tài)機的LCD多級菜單設計方案

基于狀態(tài)機的LCD多級菜單設計方案

作者: 時(shí)間:2017-10-21 來(lái)源:網(wǎng)絡(luò ) 收藏

  1 概述

本文引用地址:http://dyxdggzs.com/article/201710/367067.htm

  液晶顯示器(Liquid Crystal Display,LCD)由于其體積和功耗等因素,非常適合嵌入式環(huán)境的使用。近年來(lái),隨著(zhù)微處理器性能的提高,實(shí)現的功能越來(lái)越強大,產(chǎn)生的數據量也越來(lái)越大。相對應地,需要顯示的數據量也隨之增大。嵌入式環(huán)境下使用器,由于條件限制,體積較小,且顯示的內容有限。而且,傳統的 模式總是不加選擇地顯示所有監控的信息,在監控的信息量非常龐大時(shí)會(huì )導致不能及時(shí)顯示用戶(hù)所需求的信息。多級菜單顯示則是將信息分類(lèi)顯示的一種顯示方式,該方式根據用戶(hù)的選擇,對顯示信息加以篩選并分級顯示,這樣既保證用戶(hù)獲取其所需的信息,又能保障信息顯示的實(shí)時(shí)性。

  2 多級菜單的結構

  設計多級菜單的目的在于將需要顯示的信息分門(mén)歸類(lèi),方便用戶(hù)篩選。所以在設計菜單時(shí)需要根據整個(gè)系統的功能和要求來(lái)設定菜單的級數,以及各級子菜單的個(gè)數。整個(gè)多級菜單的拓撲結構為樹(shù)型結構,主菜單為根節點(diǎn),子菜單為枝節點(diǎn),最后一級菜單為葉節點(diǎn),如圖1所示。

  

  圖1 多級菜單的結構圖

  3 多級菜單的程序設計

  3.1 循環(huán)方式

  循環(huán)方式的設計思路:預先定義一個(gè)包含6個(gè)結構元素的結構體、5個(gè)字符型和1個(gè)指針型。第1個(gè)字符變量存放當前界面的索引號;第2個(gè)字符變量存放按下 “down(向下)”鍵時(shí)需要跳轉到的索引號;第3個(gè)字符變量存放按下“up(向上)”鍵時(shí)需要跳轉到的索引號;第4個(gè)字符變量存放按下“enter(進(jìn)入)”鍵時(shí)需要跳轉的索引號;第5個(gè)字符變量存放按下“esc(退出)”鍵時(shí)需要跳轉的索引號;第6個(gè)變量為函數指針變量,存放當前索引號下需要執行的函數的入口地址。

  將所有需要顯示的界面其所對應的執行函數和按鍵索引號以結構體的形式列表存儲。具體實(shí)現如下:

  typedef struct{

  uchardown_index;

  ucharup_index;

  ucharenter_index;

  ucharesc_index;

  void (*operate)();

  }Key_index_struct;

  假設菜單分3級,共10個(gè)界面,則有:

  Key_index_struct const Key_tab[10]={

  {0, 0, 0, 1, 0,(*main_menu)},

  {1, 2, 3, 4, 0,(*sub_menu1)},

  {2, 3, 1, 5, 0,(*sub_menu2)},

  {3, 1, 2, 7, 0,(*sub_menu3)},

  {4, 4, 4, 4, 1,(*sub_menu1_1)},

  {5, 6, 6, 5, 2,(*sub_menu2_1)},

  {6, 5, 5, 5, 2,(*sub_menu2_2)},

  {7, 8, 9, 7, 3,(*sub_menu3_1)},

  {8, 9, 7, 8, 3,(*sub_menu3_2)},

  {9, 7, 8, 9, 3,(*sub_menu3_3)},

  };

  void Lcd_display(void){

  switch(Key_status){

  case enter:

  Key_fun=Key_tab[Key_fun].enter_index;

  break;

  case down:

  Key_fun=Key_tab[Key_fun].down_index;

  break;

  case up:

  Key_fun=Key_tab[Key_fun].up_index;

  break;

  case esc:

  Key_fun=Key_tab[Key_fun].esc_index;

  break;

  default:

  return;

  break;

  }

  Key_fun_Pt=Key_tab[Key_fun].operate;

 ?。?Key_fun_Pt)();//執行當前按鍵的操作

  }

  當微處理器掃描鍵盤(pán)檢測到有按鍵按下時(shí),根據按鍵按下的類(lèi)型,返回在當前界面下其所對應的跳轉索引號,并執行相應的函數。

  由于每個(gè)界面的繪制都是由一個(gè)獨立函數實(shí)現的,從循環(huán)方式的實(shí)現過(guò)程中發(fā)現,每發(fā)生一次按鍵按下操作都需要重新繪制整個(gè)屏幕。如果核心處理器是低速主頻的處理器,在界面切換的時(shí)候會(huì )閃爍。而且,每一個(gè)界面都有固定不變的索引號,在增加或刪除界面的時(shí)候需要重新修改整個(gè)列表,降低了程序的可移植性。

  3.2 查詢(xún)方式

  查詢(xún)方式是通過(guò)結構體對自身的遞歸調用實(shí)現菜單的多級嵌套。

  結構體通過(guò)對自身的兩次調用構建雙向列表。一個(gè)菜單界面即為一個(gè)節點(diǎn),節點(diǎn)的前驅和后繼分別存放其父節點(diǎn)和子節點(diǎn)的入口地址。

  菜單參數的結構體定義如下:

  typedef struct Lcd_menu_content{

  uchar *lpIcon;//顯示圖標

  uchar *lpText;//顯示文本信息

  uchar nTextCount; //菜單對應的文本信息的個(gè)數

  }Lcd_menu_content;

  每個(gè)界面對應一個(gè)節點(diǎn),節點(diǎn)都定義成如下結構體的變量:

  typedef struct Lcd_menu{

  struct Lcd_menu*lpfather;//父級

  struct Lcd_menu*lpson;//大兒子

  uchar nSonCount;//父級的兒子個(gè)數

  Lcd_menu_content lpIconAndText;

  uchar Flag_return;//返回標志

  void (*operate)();//處理函數入口地址

  }Lcd_menu;

  由圖1可知,多級菜單的拓撲結構為樹(shù)型拓撲結構,即每一個(gè)節點(diǎn)只有一個(gè)父節點(diǎn)和若干個(gè)子節點(diǎn)。所以,對整個(gè)叉樹(shù)進(jìn)行遍歷即可準確地查找到菜單界面所在的節點(diǎn)。

  結構體實(shí)現的鏈表如圖2所示。

  

  圖2 結構體鏈表

  查詢(xún)方式與循環(huán)方式相比,由于減少了查表次數,因而改善了MPU的效率;但查詢(xún)方式占用MPU處理時(shí)間過(guò)長(cháng),不適應需要高速處理數據的應用。而且,在查詢(xún)方式中增加或刪除節點(diǎn)對程序改動(dòng)較大,也不適合移植。

  3.3 方式

  是由事件驅動(dòng),在各個(gè)狀態(tài)之間跳轉。采用方式時(shí),只需要提供驅動(dòng)事件(在此設計中驅動(dòng)事件為有效的按鍵按下),然后根據按鍵掃描返回的鍵值,決定所要跳轉的下一狀態(tài)。

  如圖3所示,系統啟動(dòng)初始化是顯示Main_menu界面,當按鍵檢測有返回值(即有按鍵按下)時(shí),根據按下的按鍵所代表的操作跳轉到指定的狀態(tài)。例如:按下Up或者是down鍵時(shí),只是在Main_menu界面內高亮顯示不同區域;按下Enter時(shí),則要根據原來(lái)按下的Up和down鍵來(lái)選擇需要跳轉的方向,假設在按下Enter之前僅按下一次down鍵,則key_v的值為2(key_v的值默認為1,即默認選中子菜單的第一項),就跳轉為 Sub_menu2界面;按下Esc鍵時(shí),為從子菜單返回到上一級菜單,如果已經(jīng)是主菜單了則返回的還是主菜單。

  

  圖3 多級菜單的狀態(tài)圖

  由于使用的是狀態(tài)機的方式,只有發(fā)生一次有效的按鍵,狀態(tài)才會(huì )發(fā)生一次跳轉。而且,僅當Enter和Esc鍵按下時(shí),才會(huì )切換界面。所以即便是在高速MPU應用中,也不會(huì )出現屏幕閃爍的效果。

  從圖3中可以看出,當要發(fā)生狀態(tài)跳轉時(shí),目的狀態(tài)只能是當前狀態(tài)幾個(gè)分支預測中的一個(gè),從而不需要遍歷整個(gè)列表,能夠適應高速數據處理的場(chǎng)合。

  多級菜單的程序流程如圖4所示。系統上電初始化后顯示主菜單,鍵盤(pán)掃描可以通過(guò)主程序中循環(huán)查詢(xún)或者中斷掃描來(lái)實(shí)現,最終根據鍵盤(pán)返回的鍵值選擇下一狀態(tài)。

  圖5為基于狀態(tài)機的多級菜單的實(shí)現。

  

  圖4 多級菜單的程序流程圖

  

  圖5 多級菜單的實(shí)現

  結語(yǔ)

  以上三種多級菜單的實(shí)現方式均具有很強的實(shí)用性。循環(huán)方式和查詢(xún)方式下,程序結構簡(jiǎn)單易用,而狀態(tài)機方式下程序可移植性強。狀態(tài)機程序設計不僅可以用在人機接口設計中,還可用于嵌入式通信協(xié)議等其他場(chǎng)合中。



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>