Graphical User Interface簡稱GUI,即圖形用戶界面,準確來說GUI就是屏幕產品的視覺體驗和互動操作部分。在工業控制領域里,各種儀器儀表、智能工控設備中廣泛采用了嵌入式技術,但由于資源有限,這些系統一般不希望建立在龐大累贅的、非常消耗系統資源的操作系統和GUI之上,如Windows或XWindows。這些系統對液晶顯示的常用GUI需求更加突出。因此,在工業控制系統中實現一個簡潔、快速、方便的常用GUI具有廣闊的市場應用前景。
在工業控制領域點陣液晶顯示(LCD)是應用最為廣泛的,如果使用GUI,那么在顯示設備(通常指的是LCD)上完成繪制圖形、顯示西文字符和漢字、顯示和使用控件以及窗口等工作,就可以通過調用GUI提供的函數來實現,無須自己為LCD編寫完成這些工作的程序,也無須選用自帶漢字庫的LCD了。“GUI”一詞是“圖形用戶界面(Graphics User Interface)”的縮寫,那么使用GUI的LCD,當然只能選擇圖形點陣LCD,1602之類的字符LCD不在考慮之列。
在進行液晶顯示GUI開發的時候首先要考慮MCU和LCD的選型。
MCU選型
8位單片機——8051系列單片機系統要求64Kb ROM和1Kb RAM,可以選擇單片增強型8051單片機,如宏晶科技增強型8051單片機STC89C516RD+,內部繼承64Kb Flash和1280B RAM,其中包括1Kb擴展RAM(Keil C51中為xdata);也可以用普通8051單片機外界ROM和RAM。
為了保證GUI的運行速度,8051單片機系統的主頻應盡量高一些,至少應在22MHz以上,如果單片機有內部倍頻可以打開,使用告訴的C8051F系列單片機更好,如C8051F020等。
如果選用AVR系列8位單片機,可以選擇內部Flash不小于32Kb,內部SRAM不小于2Kb的型號,如ATmega32、ATmega64、ATmega128等。
LCD選型
STN LCD——市面上銷售的單色LCD絕大多數都是這種類型。STN LCD可選擇自帶LCD驅動器/控制器的STN LCD模塊,如基于KS0107/KS0108的128×64單色圖形點陣液晶模塊,更大一些的同樣可以使用,無須自帶漢字庫。
TFT LCD——即俗稱的“真彩色”液晶。TFT LCD通常一定要選擇總線型液晶顯示器,或者外接單片機LCD驅動板也可以,總之要能夠連接單片機或者MCU。
注意:無論選擇何種LCD,LCD供電電壓和I/O電平應與MCU供電電壓和I/O電平相匹配,例如,都是5V或者都是3.3V,如果不匹配,可考慮使用LDO(低壓差穩壓器)和上拉電阻。
底層驅動函數
在選定MCU和LCD后,針對LCD控制器要編寫一些底層驅動函數,這些函數主要實現MCU對LCD控制器的控制,進而實現對LCD的控制。其中最主要的兩個驅動函數是控制器寫命令函數和控制器寫數據函數。值得注意的是不同的控制器的控制時序和控制特性有所不同,應針對所選用的MCU和LCD控制器選擇合適的連接方式以最簡捷的硬件連接來獲得最佳的控制效果。
GUI基本功能的實現
液晶顯示的常用GUI應實現最基本的畫點、畫圓、畫線、矩形、正方形、填充等功能,還須要實現ASCII顯示和漢字顯示以及簡單的圖標顯示和菜單顯示。
在實現GUI的這些基本要素時一個最重要的問題是準確定位光標位置。由于各控制器的不同,光標的定位也不同,例如有的控制器是以字節(8個點)為基本單位,而有的控制器是以點為基本單位。在應用以字節為基本單位的控制器時應注意要實現任意位置的操作時需要經過適當的算法進行移位處理。
在選用不帶漢字庫的LCD時,在實現漢字顯示功能時應用字模軟件對漢字進行取模存儲。根據實際要求ASCII字模可選用8×8和8×16,而漢字字模一般選用16×16和24×24。在實現單個ASCII和漢字的顯示后,建議最好實現ASCII和漢字混合字符串的顯示,因為實現此功能后將對后期開發菜單時帶來極大的方便。
實例:AVR單片機ATmega128控制SED1335實現GUI
ATmgeal28是AVR單片機中功能最強的,它有128KB的Flash程序存儲器、4Kb的SRAM和4Kb的EEPROM。在端口方面,它有邊界掃描JATG口、I2C串行口、SPI同步串行口和通用異步串行口UART。通過適當的外圍接口電路的設計,它能夠滿足工業控制器的要求。
SED1335是日本SEIKO EPSON公司出品的液晶顯示控制器,在同類產品中功能最強,它具有如下幾個特點:
①有較強功能的I/O緩沖器;
②指令功能豐富;
③四位數據可并行發送,最大驅動能力為640×256點陣;
④可混合顯示圖形和文本方式;
⑤具有垂直、水平和滾動功能;
⑥圖形方式下具有三重屏幕顯示;
⑦內含160個點陣字符的字符發生器。
SED1335在接口部設置了適配Intel 8080系列和M6800系列MPU的兩種操作時序電路,通過引腳的電平設置,可選擇二者之一。
本例采用的為Intel8080操作時序,如圖1所示。
圖1 SED1335與8080系列MPU接口時序
本例利用ATmega128豐富的管腳資源直接通過輸入輸出引腳控制SED1335。其中數據部分是8條數據線(DB0~DB8),控制部分包括RD(讀)、WR(寫)、CS(片選)、A0(數據類型選擇)。ATmega128與SED1335的接線原理圖如圖2所示。
圖2 ATmega128與SED1335連線原理圖
實際上,在對SED1335進行控制的過程中,最重要的一點就是對A0的控制。由于A0是數據類型選擇位,當A0為1時,ATmega128發出的數據會被SED1335認為是指令代碼而將它自動放到它的指令輸入緩存器內;當A0為0時,ATmega128發出的數據會被SED1335認為是數據代碼自動放到它本身的數據輸入緩存器內。
值得注意的是:ATmega128的輸入輸出端口必須自己設定,本文采用的編譯器是WinAVR(GCC),所以對輸入輸出口的設定如下程序語句:
DDRA=0XFF; //將PA口設為輸出
DDRD=0XF0; //將PC口PD4~PD7設為輸出
為了控制SED1335在底層需要編寫兩個重要的驅動函數分別為SED1335寫命令函數和SED1335寫數據函數。本文使用WinAVR(GCC)編譯器,具體實現如下:
void SED1335_write_command(unsigned char CommandByte)
{
PORTD|=BIT(1)|BIT(3)|BIT(4);
PORTD|=BIT(2); //A0置高 即A0=1
PORTD&=~BIT(1);
PORTD&=~BIT(3);
PORTA=CommandByte;
PORTD|=BIT(1);
PORTD|=BIT(3);
?? }
void SED1335_write_data(Uchar dataW)
{
PORTD|=BIT(1)|BIT(3)|BIT(4);
PORTD&=~BIT(2);//A0置低 即A0=0
PORTD&=~BIT(1);
PORTD&=~BIT(3);
PORTA=dataW;
PORTD|=BIT(1);
PORTD|=BIT(3);
}
SED1335具有一個13條指令的指令集,多數指令帶有參數,參數由用戶根據用戶所控制的液晶顯示模塊的特性和實際應用的需要來設置。這個指令集可實現初始化、顯示域、顯示狀態、光標(包括形狀、位置和移動方向)、顯示合成方式和數據讀寫設置等,可完成多種文本的顯示、刷新等功能。
在編寫菜單以前要對SED1335進行初始化設置,設置液晶屏顯示的方式、顯示的合成方式等各個方面。具體程序的初始化指令代碼如下:
void GuiInit(void)
{
//SYSTEM SET COMMAND
???? SED1335_write_command(SystemSet); //系統設置命令
???? SED1335_write_data(0x30);
SED1335_write_data(0x87);
SED1335_write_data(0x07);???
???? SED1335_write_data(0x27);???
???? SED1335_write_data(0x42);???
???? SED1335_write_data(0xef);???
???? SED1335_write_data(0x28);???
???? SED1335_write_data(0x00);
……
}
注意帶有多參數的指令在寫參數時,一定要按規定的順序依次寫入(參數可以不必全部寫入),不然就會出錯。另外,在初始化設置SED1335之前應先對ATmega128進行初始化,主要是對I/O口進行輸入輸出設定。
其他的工作就是具體實現畫點、畫圓、畫線、矩形、正方形、填充、ASCII顯示和漢字顯示以及簡單的圖標顯示等功能了。這里列出需要實現的函數,不再給出具體程序代碼。
void LcdOn(void); //允許液晶顯示
void LcdOff (void); //關閉液晶顯示
void DispClear (void); //清除32K RAM顯存
void GotoXY(Uint x,Uint y); //文本方式下將光標定位到指定位置
void GPix(Uint x,Uint y,char color); //任意位置的畫點或消點
void lcd_rectangle(Uint x1,Uint y1,Uint x2,Uint y2,char color); //畫方框圖
void GuiLevelLine(Uint x0,Uint x1,Uint y,char color); //畫水平線
void GuiUpdownLine(Uint x,Uint y0,Uint y1,char color); //畫垂直線
void GuiLine(Uint x0,Uint y0,Uint x1,Uint y1,char color); //畫直線
void GuiCirclePixel(Uint x0,Uint y0,Uint r,char color); //畫圓
void GuiBoxReverse(Uint dot_start_x, //指定區域的取反顯示
?????? Uint dot_start_y,
?????? Uint dot_end_x,
?????? Uint dot_end_y);
void GuiBoxFill?? (Uint dot_start_x,??? //指定區域的填充(置0或寫1)
?????? Uint dot_start_y,
?????? Uint dot_end_x,
?????? Uint dot_end_y,
??char color);
void write_string(char *ptr); //文本方式下寫8*8的字符
void PutCdotInAlpha(Uint x,Uint y,Uint Cnumber);//漢字寫入子程序(文本方式)
void PutCdotInGraph(Uint x,Uint y,Uint Cnumber,Uint DotWidth); //漢字寫入子程序(圖形方式)。每次調用輸出一個漢字(可顯示16*16或24*24的漢字)
void Locatexy(Uint x,Uint y); //圖形方式的光標定位函數
void GuiString(Uint x,Uint y,char *ptr,char color,char colorBk); //圖形方式的寫8*16的字符和16*16的漢字混合函數
void bprintf (Uint x,Uint y,Uint a,char color,char colorBk); //圖形方式的顯示變量數值的函數(8*16)
void mprintf (Uint x,Uint y,int *p,char color,char colorBk); //圖形方式的顯示文件名的函數(8*16)
整個系統的軟件流程圖如圖3所示。
圖3 系統軟件流程圖
在本實例中,通過液晶顯示屏和按鍵配合操作可完成各種功能選擇和參數的設置。由于采用漢字顯示菜單,接口直觀、簡便、美觀、友好。
液晶顯示常用GUI的通用性
通過上述實例可以看出:在應用本文設計的GUI時,只需要針對不同的MCU和LCD控制器進行很少的底層驅動函數的更改,使其滿足LCD控制器的控制時序和控制特性即可,而GUI基本的畫點、畫圓、畫線、矩形、正方形、填充、ASCII顯示和漢字顯示以及簡單的圖標顯示等功能,幾乎不用改動或只需針對光標定位進行改動。此外,對于AVR單片機而言由于具有豐富的管腳資源可以直接使用輸入輸出引腳,對LCD控制器進行控制,其實當該GUI作為嵌入式系統的顯示部分時可以不用? I/O進行控制來滿足時序。如本文所舉的實例如果由FPGA完成時序配置,則只需對SED1335寫命令函數和SED1335寫數據函數稍加修改,而其余GUI函數都可以直接應用。修改的SED1335寫命令函數和SED1335寫數據函數代碼如下:
void sed1335_write_command(Uchar CommandByte)
{
?*(volatile unsigned char*)SED1335_WRITE_COMMAND_ADDR =CommandByte;
}
void sed1335_write_data(Uchar dataW)
{
?*(volatile unsigned char*)SED1335_WRITE_DATA_ADDR=dataW;
}
結束語
工業測量控制儀器中,友好的人機對話窗口可使操作更加簡單,本文提出的液晶顯示的常用GUI不僅滿足工控要求,而且具備很好的通用性,同時還有輕型、占用資源少、高性能、高可靠性、可配置等特點,可以方便地移植到各種工控嵌入式系統中。
評論