999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

uC/GUI實現OLED顯示的移植與優化研究

2016-11-08 08:36:20胡平平王晶杰
計算機應用與軟件 2016年10期
關鍵詞:指令設置優化

胡平平 王晶杰

(北京信息科技大學自動化學院 北京 100192)

?

uC/GUI實現OLED顯示的移植與優化研究

胡平平王晶杰

(北京信息科技大學自動化學院北京 100192)

為了擴展STM32系統中OLED顯示處理功能、提高處理效率,給出了uC/GUI實現OLED最小顯示系統的移植方法。并根據OLED顯示器的特性,提出了新的程序結構,設計了快速判決算法,對關鍵代碼進行了優化,在uC/GUI下實現了高效的OLED顯示處理。實際測試數據分析證明,所設計的算法不僅降低了處理復雜度,還使顯示處理速度成倍提高。

uC/GUIOLED移植算法優化

0 引 言

uC/GUI是著名的uC/OS-II開發者Micrium 公司的另一個優秀開源軟件,是專為嵌入式應用而設計的、可移植、可裁減的圖形用戶界面系統軟件[1]。uC/GUI可為任何使用圖像LCD的應用程序提供高效的、獨立于處理器和LCD控制器的圖形用戶接口[2]。uC/GUI可用于單任務和多任務嵌入式系統中,全部代碼用C語言完成,可方便地移植到各種CPU上[3,4]。

有機發光二極管(簡稱OLED)具有纖薄、可制成各種形狀、占用空間小等優勢,它是繼白熾燈、熒光燈、LED之后的又一次光源革命。由于它節能、環保、壽命長而應用廣泛,被列入我國戰略性新興產業[5]。和LCD相比,OLED具有體積小、亮度高、視角寬、自發光、低功耗、壽命長、動態范圍廣和可彎曲等諸多優點[6]。

由于uC/GUI主要是為LCD設計的,向各種LCD顯示器的移植不僅簡單,而且執行效率非常高。OLED有著與LCD不同的控制方式和RAM映像,雖然按常規方法將uC/GUI移植到OLED顯示器并不困難,但執行效率非常低。這既不符合嵌入式系統嚴苛的實時性要求,也沒有充分發揮uC/GUI的優勢。

本文在分析uC/GUI系統特點的基礎上,先給出了實現OLED最小顯示系統的移植方法,然后結合OLED顯示的特點,設計了全新的程序結構并對關鍵代碼進行了優化,提出了快速判決算法,不僅提高了軟件的執行效率,且快速實現了復雜的處理。

1 OLED顯示器及操作方法

本文所使用MCU是Cortex-M3系列芯片STM32F105,OLED為單色128×64點陣顯示器,驅動芯片為SSD1303。MCU與SSD1303的連接采用并行方式,如圖1所示。

圖1 MCU與SSD1303的連接圖

圖中PC0至PC7按8位I/O端口操作,其他四根控制線則按位進行輸出操作。操作宏的定義如下:

#define Oled_DCPAout(0)

#define Oled_CSPAout(2)

#define Oled_WRPBout(10)

#define Oled_RDPAout(11)

#define SetOledData(x)GPIOC->ODR=(GPIOC->ODR&0xff00)|x

#define GetOledData()(GPIOC->IDR&0xff)

SSD1303最大可驅動132列64行點陣顯示器,內部有132×64位顯示SRAM,MCU可對它進行讀寫操作。該SRAM的位和顯示點陣的映射關系如圖2所示。

圖2 顯示器點陣和SRAM的映射關系

顯示點陣的64行分為8頁,每頁8行;頁中的每一列映射為SRAM的一個字節,位序為bit7至bit0,每頁中的132列映射為SRAM中連續的132個字節。讀寫一個SRAM字節的代碼如下:

void WriteOledCmd(U8 Cmd)

{

SetOledData(Cmd);

Oled_DC= 0;Oled_WR= 0;

// 寫命令字

Oled_CS= 0;Oled_CS= 1;

// 產生CS低脈沖

Oled_WR= 1;Oled_DC= 1;

// 寫結束,默認數據字

}

void WriteOledByte(U8 Data, int Page, int Col)

{

WriteOledCmd(Page+0xB0);

// 設置頁號

WriteOledCmd(Col&0xf);

// 設置列低地址

WriteOledCmd((Col>>4)+0x10);

//設置列高地址

Oled_WR = 0;

// 寫操作

SetOledData(Data);

Oled_CS = 0;Oled_CS = 1;

// 產生CS脈沖

Oled_WR = 0;

// 寫結束

}

U8 ReadOledByte(int Page, int Col)

{

U8 Data;

WriteOledCmd(Page+0xB0);

// 設置頁號

WriteOledCmd(Col&0xf);

// 設置列低地址

WriteOledCmd((Col>>4)+0x10);

//設置列高地址

Oled_RD = 0; Oled_CS = 0;

// 讀操作

Data = GetOledData();

// 得到數據字節

Oled_CS = 1; Oled_RD = 0;

// 讀結束

return Data;

}

讀(寫)一個SRAM字節的處理需要92(95)條匯編指令,代碼長度為109(110)個字。

2 OLED最小顯示系統的uC/GUI移植方法

本文使用的是V3.94版的uC/GUI,移植過程分為添加源程序、修改配置文件和編制關鍵代碼三部分。

2.1添加uC/GUI源程序

uC/GUI的可裁剪性表現在其源程序按函數功能可細分為許多獨立的小源程序文件,如GUI_DispChars.c文件只含GUI_Disp Chars()一個函數,僅兩行代碼!簡單地將所有uC/GUI源程序都添加到項目文件中,對支持smart鏈接(僅鏈接用到的模塊)的編譯器來說不會增加目標代碼的尺寸,但臃腫的項目文件不符合uC/GUI短小精干原則和“綠色”編程精神。好的做法是在項目文件夾中創建一個與uC/GUI軟件包Start文件夾類似的兩層共五個文件夾:

需要添加的具體源程序文件是:

Config下的GUIConf.h和LCDConf.h。

Core下的GUI.h、GUI_ConfDefaults.h、GUI_DispChar.c、GUI_DispChars.c和GUI_DispString.c等30個文件。

LCDDriver下的LCDDummy.c,該文件包含了移植中所有需要修改的函數。

Font下的F8x16.c(本文僅使用了8×16點陣字符集)。

2.2修改uC/GUI配置文件

文件LCDConf.h中符號的修改:

LCD_XSIZE(128)

// 原值640

LCD_YSIZE(64)

// 原值480

LCD_BITSPERPIXEL (1)

// 原值8

LCD_CONTROLLER(1303)

// 原值1375,h

其中的1303表示SSD1303,沒有特殊含義,其用法見下文。

文件GUIConf.h中符號的修改:

GUI_OS(0)

// 不支持操作系統

GUI_SUPPORT_TOUCH(0)

// 不支持觸摸屏

GUI_SUPPORT_UNICODE(0)

// 不支持ASCII和Unicode混合使用

GUI_DEFAULT_FONT &GUI_Font8x16

// 原GUI_Font6x8

GUI_ALLOC_SIZE128*64

// 為WM和存儲設備用

GUI_WINSUPPORT0

// 不支持窗口

GUI_SUPPORT_MEMDEV0

// 不支持存儲設備

GUI_SUPPORT_AA0

// 不支持去鋸齒

2.3編制關鍵代碼

移植只需對LCDDummy.c里的相關代碼進行修改即可,基本系統的移植僅需修改三個函數:

(1) 初始化代碼

uC/GUI初始化由GUI_Init()完成,調用的一系列函數中僅GUI_X_Init()和LCD_L0_Init()需要修改。GUI_X_Init()用于初始化GUI運行之前需運行的硬件,本文系統沒有這樣的硬件,僅在LCDDummy.c中設置一個空的GUI_X_Init()函數即可。初始化移植只需將LCD_L0_Init()對LCD_INIT_CONTROL LER()的調用替換為對OLED控制器SSD1303的初始化處理就行了。

(2) 設置像素代碼

模板中設置像素函數是一個空函數,移植后的代碼如下:

void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex)

{

U8 Mask=0x80>>(y&7);

U8 Data = ReadOledByte(y>>3, x);

if ( PixelIndex ) Data |= Mask;

else Data &= ~Mask;

WriteOledByte(Data, y&7, x);

}

(3) 讀取像素代碼

模板中讀取像素函數是一個僅返回0的函數,移植后的代碼如下所示:

unsigned int LCD_L0_GetPixelIndex(int x, int y)

{

return (ReadOledByte(y>>3, x)&(0x80>>(y&7))) ? 1 : 0;

}

另外,必須將原始LCDDummy.c的編譯條件:

#if (LCD_CONTROLLER==-1) && (!defined(WIN32) ‖ defined(LCD_SIMCONTROLLER) ) 改為:

#if (LCD_CONTROLLER==1303) 才能通過編譯。

3 OLED顯示代碼的優化設計

3.1OLED顯示代碼存在的問題

上述移植完成的uC/GUI雖然能夠正確地實現OLED的顯示處理,但其執行效率非常低。分析uC/GUI的代碼發現,所有顯示處理最終都是通過LCD_L0_SetPixelIndex()和LCD_L0_GetPixelIndex()兩個函數實現的,而單獨對每一個像素處理并沒有充分利用OLED顯示器的特點。

首先,向OLED顯示器讀寫一個像素與讀寫一頁中該列的8行像素的處理量完全一樣。在上述讀(寫)SRAM字節代碼中,設置地址(頁號和列號)的指令數多達72條,占總代碼92(95)條的78.3%(75.8%)。而實際上OLED顯示器內部有一個可以自動加1的地址計數器,僅需設置一次頁號和列號,就可以連續讀寫最多達132個SRAM字節,這一特性在上面的代碼中完全沒有利用。

以顯示一個8×16點陣的字符為例,需要調用128次設置像素的函數,共需執行207×128=26 496條指令。而實際上需要設置SRAM的字節數量最多24個(若字符起始行正好在頁邊界上則僅為16個),如果連續設置,僅需設置3次地址和寫信號( (72+6)×3=234條指令),然后3次連續寫8個字節(13×8×3=312條指令),總指令數量為546條,是逐像素處理的2.06%。可見,提高顯示處理速度存在很大的空間。

3.2新的處理策略和關鍵代碼

為了充分利用OLED顯示的優勢,必須將像素的逐點處理改為批量處理,為此本文設計了新的處理策略:在MCU內存中設置一個OLEDSRAM的映像空間OledRamMap,同時設置一個SRAM更新標志OledRamUpdateFlag:

U8 OledRamMap[8*128];

// 長度1024B

U8 OledRamUpdateFlag[8*(128/8)];

// 長度128B

OledRamMap的每一個字節在OledRamUpdateFlag中都有一位標志表示該字節是否更新。所有處理像素的函數都不直接訪問OLED的SRAM,而是對OledRamMap和OledRamUpdate Flag進行設置,必要時由更新函數UpdateOledDisp()按更新標志將OledRamMap寫到OLED的SRAM中。

OledRamMap和OledRamUpdateFlag在初始化時被清零,OledRamUpdateFlag在每次更新后也清零。新策略關鍵代碼的實現如下所示:

void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex)

{

U8 BitMask = 0x80>>(y&7);

U8 *pCntData=&OledRamMap[(yPhys<<4)+xPhys];

if ( PixelIndex ) *pCntData |= BitMask;

else *pCntData &= ~BitMask;

OledRamUpdateFlag[(y<<1) +(x>>3)] |=0x80>> (x&7);

}

unsigned int LCD_L0_GetPixelIndex(int x, int y)

{

return (OledRamMap[(y<<4) +x]&(0x80>>(y&7)))?1:0;

}

void LCD_L0_XorPixel(int x, int y)

{

OledRamMap[(y<<4) +x] ^= (0x80>>(y&7));

OledRamUpdateFlag[(y<<1) +(x>>3)] |= 0x80>>(x&7);

}

UpdateOledDisp()的處理流程如圖3所示。

3.3更新處理的進一步優化和快速判決算法

上面的更新處理算法在更新數據分片位于連續空間的情況下效率確實很高,但在更新數據零碎且分散的情況下,效率并不高。最壞的情形是更新標志為1和0交替出現,此時要為每一個需更新的數據設置地址。分析發現,送一次數據需13條指令,而設置一次地址需要76條指令,是送數據的5.8倍。也就是說,如果兩個需要更新的數據間不需要更新的數據數量小于6個時,就應該連續發送這些無需更新的數據而不重新設置地址。

圖3 OLEDSRAM更新處理流程圖

為此,在更新標志由1變0時要根據該0后面連續4個標志位的16種情況來決定是否停止發送數據。由于標志由1變0出現的位置有8種(按字節訪問的),因此共有128種情況。顯然,為決定是否停止發送數據而進行128種判決處理是完全不可接受的。本文設計了快速算法,通過邏輯運算和查表操作,僅需一次判斷便可得出判決結果。實現方法如下:

新算法的原則是:如果判決結果是繼續發送數據,則將當前0標志及后面4位中某些0標志置位即可。這樣可保持處理的簡潔性,少增加新的分支。此外,當前0標志的8個位置中,有4個位置的后續4位將延伸到下一個標志字節,因此必須將連續16個更新標志用一個U16變量CntFlagW聯合處理。而檢測字MaskW也由0x8000移位至0x100,新增一個與此對應的變量BitShift由0變至7。設置一個判決門限數組FlagLevel如下:

const u16 FlagLevel[]={0x0400,0x0200,0x0100,0x0080,

0x0040,0x0020,0x0010,0x0008};

令Tmp = CntFlagW&(MaskW-1),

如果Tmp≥FlagLevel[BitShift],則應該繼續發送數據,此時應將CntFlagW修改為:

CntFlagW |= FlagSetV[(Tmp>>(11-BitShift)])<<(11-BitShift)

其中FlagSetV的定義如下:

const u8 FlagSetV[] = {0x1F,0x1E,0x1C,0x1C,0x18,0x1A,

0x18, 0x18,0x10,0x16,0x14,0x14,0x10,0x12,0x10,0x10};

例如,若CntFlagW=101000X(X表示后面10個無關二進制位,以下同),此時MaskW=0x4000,BitShift=1,Tmp=CntFlagW &0x3fff=001000X,顯然Tmp≥FlagLevel[1]=0x200,應該繼續發送數據且將CntFlagW與FlagSetV[8]<<10=0x4000邏輯或,變成111000X。此處的三個0是不能置位的,因為X的前3位為0時,后面的第1個0處應該停止發送數據。如果CntFlagW= 101001X,也應該繼續發送數據且將CntFlagW與FlagSetV[9] <<10=0x16<<10=0x5800邏輯或,變成111111X。對于BitShift=1時,僅CntFlagW= 100000X且X的第一個位為0的情況下Tmp的最大值是0x1FF,才會停止發送數據,此時從當前0標志開始已經有6個連續的0標志了。對于BitShift為其它值的情況與此完全類似。

另外,如果連續的8個標志都是0,則無需進行最內層的MaskW移位循環,從而進一步提高了速度。改進后的更新處理流程如圖4所示。

圖4 改進的OLEDSRAM更新處理流程圖

3.4優化結果的性能分析

1) 更新處理改進前后的性能比較

通過在實際代碼上對標志位各種組合共32類情況的精確測試分析,在0和1標志交替出現,較短(5個以內)連續0標志和較長(8個及以上)連續0標志的情況下,改進后都變快。僅在6至14個連續0標志且非整字節0標志的情況下,改進后速度基本沒變(最慢0.95)。大量連續0標志的情況下,改進后速度提升最多,最大為8.704倍。

2) 優化前后顯示字符的性能比較

優化前,顯示一個字符設置像素的指令數量為26 496條;優化后設置像素函數僅30條指令,顯示一個字符設置像素的指令數量為30×128=3840,而更新處理(按最多的24字節算)則需要1330(全0標志)+ 666×1(送24字節)+252(設置3次地址)-12×1(減去0標志已含)=2236,共6076,速度提高了4.36倍。同理,連續顯示N個字符再更新的速度比如表1所示。

表1 連續顯示N個字符再更新的速度比

可見,一次更新處理前顯示的字符越多,優化方案的速度提高越大。如果考慮到實際應用中顯示區域重疊的情況,本文方案的優勢就更大了。

3) 可優化的其它處理函數和使用注意事項

(1) 其他可以優化的函數

模板中的繪制函數LCD_L0_DrawHLine()、LCD_L0_Draw VLine()和LCD_L0_FillRect()也可以進行類似的優化。另外,由于經常會對全屏進行無條件更新,特編制一個將OledRamMap[]無條件傳送到OLEDSRAM的函數,其執行速度分別是上面改進前后更新處理代碼的1.497和1.596倍。

(2) 關于顯示顏色

在使用顏色設置函數GUI_SetColor()和GUI_ SetBkColor()時需要特別注意。雖然單色OLED僅需0和1兩種顏色,但uC/GUI系統的顏色仍然是由紅r、綠g和藍b三個分量構成的U32類型(即r×65536+g×256+b),要想將顏色設置為1,必須保證r+g+b≥(255×3/2)=383。如GUI_SetColor(0x80ff)將前景色設置為1,而GUI_SetColor(0x7fff)則將前景色設置為0。

4 結 語

本文給出的處理方法已在實際硬件上進行了完整的測試和驗證,因移植uC/GUI而增加的代碼為7754 B、點陣數據3374 B、RAM空間1488 B(含SRAM映像1024 B和標志128 B,實際uC/GUI使用的空間為336 B)。而不用uC/GUI實現的僅有字符(且只能在整頁地址行上)顯示的代碼,其長度是:代碼2040 B、點陣數據3376 B、RAM空間16 B。相比之下,具有強大功能和易用、易擴展性的uC/GUI的確是短小精干,具有很大的優勢。此外本文所述的方法同樣適用于彩色OLED,而其中的快速判決思想則可應用到其它類似的軟件設計中。

[1] 石億,黃輝先,趙娟,等.uC/OS-Ⅱ與uC/GUI在Cortex-M3上的移植研究與實現[J].微計算機信息,2012,28(9):159-161.

[2] 葛欣,孟凡榮.使用uC/GUI開發圖形用戶界面[J].計算機工程與設計,2005,26(1):253-255.

[3] 李向陽,曾旖,奚大順.在uC/GUI中實現漢字顯示[J].單片機與嵌入式系統應用,2005(5):76-77.

[4] 葛欣,孟凡榮.移植uC/GUI應用程序時有關LCD配置的研究[J].計算機工程與設計,2005,26(4):1006-1008.

[5] 劉飛.OLED照明技術及應用進展[J].照明工程學報,2014,25(3):93-97.

[6] 劉勇.基于MSP430F149的OLED顯示系統的設計[J].電子技術與軟件工程,2013(21):177-179.

[7] Solomon Systech Limited.SSD1303用戶手冊[EB/OL].2006.6,V2.4. http://wenku.baidu.com/view/6aa1891aff00bed5b9f31d7f.html.

[8] Micrium.uC-GUI 5-26 user manual.pdf[EB/OL]. 2014.12,V5.26. https://doc.micrium.com/download/attachments/10753198.

RESEARCH ON TRANSPLANT AND OPTIMISATION OF OLED DISPLAY IMPLEMENTED WITH uC/GUI

Hu PingpingWang Jingjie

(SchoolofAutomation,BeijingInformationScienceandTechnologyUniversity,Beijing100192,China)

To expand the functions of OLED display and processing in STM32 system and to improve processing efficiency, we presented the transplant approach for OLED minimum display system implemented with uC/GUI. According to the features of OLED monitor we proposed new program structure, designed the fast discrimination algorithm, and optimised the key codes. The efficient OLED display and processing under uC/GUI is then implemented. It is proved by actual test data analysis that the designed algorithm decreases the complexity of processing and doubles the display and processing speed as well.

uC/GUIOLEDTransplantAlgorithm optimisation

2015-07-31。北京市重點學科項目(5111523302)。胡平平,副教授,主研領域:信號處理,智能儀器。王晶杰,副教授。

TP311.54

A

10.3969/j.issn.1000-386x.2016.10.057

猜你喜歡
指令設置優化
聽我指令:大催眠術
超限高層建筑結構設計與優化思考
房地產導刊(2022年5期)2022-06-01 06:20:14
中隊崗位該如何設置
少先隊活動(2021年4期)2021-07-23 01:46:22
民用建筑防煙排煙設計優化探討
關于優化消防安全告知承諾的一些思考
一道優化題的幾何解法
ARINC661顯控指令快速驗證方法
測控技術(2018年5期)2018-12-09 09:04:26
LED照明產品歐盟ErP指令要求解讀
電子測試(2018年18期)2018-11-14 02:30:34
本刊欄目設置說明
中俄臨床醫學專業課程設置的比較與思考
主站蜘蛛池模板: 91亚洲精选| 天天综合亚洲| 91精品免费久久久| 欧美激情成人网| 制服丝袜一区| 免费国产高清精品一区在线| 欧美成人亚洲综合精品欧美激情| 亚洲性一区| 国产美女在线免费观看| 久久亚洲AⅤ无码精品午夜麻豆| 99资源在线| 成人亚洲国产| 91麻豆精品国产高清在线| 亚洲成人网在线观看| 成人午夜视频网站| 九色免费视频| 国产精品女人呻吟在线观看| 午夜a视频| 亚洲第一在线播放| 亚洲精品第一在线观看视频| 欧美一区福利| 成人夜夜嗨| 成年女人a毛片免费视频| 亚洲人成电影在线播放| 欧美翘臀一区二区三区| 一本大道无码高清| 久久精品丝袜| 亚洲精品777| 米奇精品一区二区三区| 亚洲第一综合天堂另类专| 亚洲天天更新| 亚洲免费黄色网| 熟妇丰满人妻av无码区| 四虎影视8848永久精品| 国产精品视频第一专区| 日韩无码真实干出血视频| 精品无码国产自产野外拍在线| 日韩a级毛片| 99re在线视频观看| 成人亚洲天堂| 色天堂无毒不卡| 91精品国产自产在线老师啪l| 色噜噜在线观看| 国产免费网址| 狠狠干欧美| 乱人伦中文视频在线观看免费| 欧美日韩中文国产| 国产激情无码一区二区免费| 日本高清有码人妻| 在线欧美一区| 伊人久久精品无码麻豆精品| 国产喷水视频| 亚洲精品自产拍在线观看APP| 久久亚洲国产最新网站| 国产大片黄在线观看| 国产精品内射视频| 国产三级成人| 国产麻豆精品在线观看| 天天操天天噜| 四虎国产在线观看| 天天综合网亚洲网站| 日韩精品毛片人妻AV不卡| 久久久久久久久亚洲精品| 亚洲中文字幕国产av| 日韩无码一二三区| 成年片色大黄全免费网站久久| 日韩精品视频久久| 日韩精品高清自在线| 欧美黄网在线| 国产亚洲欧美日韩在线一区二区三区| 一本视频精品中文字幕| 99精品伊人久久久大香线蕉| 欧美精品导航| 欧美国产视频| 日韩欧美91| 日本不卡在线播放| 精品国产自在在线在线观看| 456亚洲人成高清在线| 丁香婷婷激情网| 国产精品开放后亚洲| 日韩第一页在线| 国产剧情国内精品原创|