手把手教你在STM32下移植UCGUI(基於正點原子的MINI開發板)
準備資料:
1、 到網上下載UCGUI3.90的原始碼,如果下不到,可以點選以下連結進行下載:
下載後解壓,可看到如下目錄:
Sample目錄主要包含一些示例程式碼,Start目錄包含工程檔案和原始碼,Tool包含一些取模工具,很實用。
開始移植:
1、 此例程是基於“ALIENTEKMINISTM32 實驗10 TFTLCD顯示實驗”來移植的。開啟該目錄目錄,可以看到:
在此路徑下建立一個UCGUI資料夾。建立後如下:
2、 將UCGUI 3.90目錄下的Start\GUI下的所有資料夾和Config資料夾拷貝到上面建立的UCGUI資料夾下:
此時需要注意:由於UCGUI\Core下有LCD.C和LCD.H檔案,而例程中也有,如下:
所以將ALIENTEK MINISTM32實驗10 TFTLCD顯示實驗\HARDWARE\LCD路徑下的Lcd.c改名為local_lcd.c,Lcd.h改名為local_lcd.h。
3、 將UCGUI原始碼和local_lcd.c新增到工程中,如下:
記得新增路徑到工程中,
4、 將local_lcd.c和main.c中的#include"lcd.h"改為#include "local_lcd.h",編譯,報錯如下:
函式重名引起的錯誤,在此將local_lcd.c和local_lcd.h中的void LCD_Init(void);改為void LCD_Local_Init(void); 同時把main.c中的LCD_Init();呼叫先註釋掉。再次編譯,報錯如下:
將UCGUI最新3.90版原始碼\UCGUI390a\Sample下的GUI_X資料夾也拷貝到UCGUI路徑下,並把GUI_X.c新增到工程中。
再次編譯,報錯:
可在LCD.h中找到如下巨集定義:
然後繼續跟蹤,可以看到在LCDDummy.c、LCDNull.c、LCDWin.c都有定義LCD_L0_SetLUTEntry函式。在此例程中使用LCDDummy.c檔案,開啟該檔案可看到整個檔案都由以下巨集決定是否參與編譯:
將其修改為
在工程中查詢LCD_CONTROLLER,可以看到在LCDConf.h中定義了:
將其改為:
再次編譯,報錯:
開啟gui_touch_driveranalog.c檔案,可以看到:
查詢GUI_SUPPORT_TOUCH,可以在GUIConf.h檔案中看到如下定義:
由於在此沒有跑作業系統,也沒有使用觸控式螢幕,也暫時用不到中文字元,更沒有用到動態記憶體分配,只是用TFT來做顯示。所以改動如下:
可以看到,編譯通過了:
5、 在main.c中包含gui.h標頭檔案,即#include“gui.h”,又報錯了:
這個問題我找了大半天,可以查到在GUIType.h中有如下定義:
LCD_COLOR是在LCD.h中定義的,而GUIType.h中是有#include “LCD.h”的,那這是為啥呢?
開啟LCD.h,可以看到預編譯指令如下:
開啟local_lcd.h和local_lcd.c,可以找到如下:
看到原因了吧?local_lcd.h用LCD_H定義了TFT屏的高度,而LCD.h用LCD_H作為整個檔案的預編譯控制。所以導致了#include “LCD.h”根本就沒包含到GUIType.h裡面去!!!所以做如下修改:
將local_lcd.h和local_lcd.c中的LCD_W改為LCD_WIDTH,LCD_H改為LCD_HEIGHT。改完後如下:
再次編譯,通過了!!
6、 接下來需要在UCGUI原始碼中新增一些LCD驅動的函式。具體如下:
① 我們使用GUI之前,肯定要對GUI進行初始化,此時會呼叫GUI_Init()函式,GUI_Init()函式中呼叫了LCD_Init();由於我們此例程用的是LCDDummy.c檔案,在LCDDummy.c檔案的LCD_Init();函式中又呼叫了LCD_INIT_CONTROLLER();我們可以在LCDConf.h檔案中找到該定義:
將其改為
然後在LCDDummy.c檔案頭新增
② 在local_lcd.c中新增以下函式,並在local_lcd.h中新增宣告:
③ 在LCDDummy.c中包含local_lcd.h標頭檔案,然後在其中幾個函式中新增內容:
7、 此時可以寫一個測試程式測試了,我們一般使用紅黃藍565的分配比例,而且在有些TFT屏會發現紅藍兩種顏色是相反的,我使用的屏正好是相反的,所以可以在LCDConf.h中通過定義以下巨集,來交換紅藍兩色:
8、 下面我寫了一個測試的例程,是顯示進度條的簡單例程。
Main.c中改成如下:
燒錄到板子上,你會發現只有“Progressbar”字幕和進度條顯示,但是進度條沒動作。
這是為啥呢,可以查到,是卡死在GUI_Delay(intPeriod)函式中,深入到底層檢視,可以知道如果不帶作業系統,是會陷入死迴圈的。可以自己寫一個函式做延時函式,也可以使用正點原子的SysTick作為延時的基準。我的處理如下:
在GUITime.c中新增
9、 編譯後通過,下載到板子,可以看到有一個進度條在執行進度。