STemWin是SEGGER公司授權給ST(意法半導體)的,使用ST芯片的用戶可以免費使用STemWin,其實不光授權給了ST,還有NXP,Energy Micro等等,凡是使用這些芯片廠商生產的處理器都可以,免費的使用的emWin但是出於一定的保護措施,使用STemWin的庫是不能用在其它芯片廠商的處理器上面的,因為在工程初始化STemWin前要使能CRC校驗。
移動到網頁最下方下載STemWin,如下所示,
下載完成的壓縮檔如下所示,
解完壓縮後前往\STemWin_Library_V1.2.0\Libraries\STemWinLibrary532,要移植的文件如下所示,
首先在要執行編寫的專案裡,新增GUI_Conf,GUI_Demo,GUI_lib,GUI_X這四個資料夾,如下所示,
在GUI_Conf,GUI_Demo這兩個資料夾裡增加inc與src這兩個資料夾,如下所示,
接下來開始移植程式,將\STemWin_Library_V1.2.0\Libraries\STemWinLibrary532\Config中的.c文件,如下所示,
移植至\GUI_Conf\src裡,如下所示,
將\STemWin_Library_V1.2.0\Libraries\STemWinLibrary532\Config中的.h文件,如下所示,
移植至\GUI_Conf\inc裡,如下所示,
其中LCDConf.h要額外新增,程式碼如下,
#ifndef LCDCONF_H
#define LCDCONF_H
#endif
\STemWinLibrary532中的inc如下所示,
複製至\GUI_Demo裡,在\GUI_Demo\inc裡的程式如下之100份文件,
\Lib的移植要根據MCU所用之架構與編輯軟體來決定,STM32F407ZG為CM4架構,本人用的編輯軟體為Keil C,依照以上這兩種情況就所用STemWin532_CM4_Keil.lib,如下所示,
複製至\GUI_lib裡,如下所示,
最後將\OS裡的GUI_X.c,如下所示,
複製至\GUI_X裡,如下所示,
以上移植完成後就要來修改程式,要修改的程式不多,只有在\GUI_Conf\src中的以下三份文件,以及\GUI_Demo\inc中的GUI_ConfDefaults.h,如下所示,
打開GUIConf.c來修改此GUI在MCU要佔多少記憶體,此規劃記憶體為1K(1024),修改完成程式如下,
//#define GUI_NUMBYTES 0x200000
#define GUI_NUMBYTES (1024)
#define GUI_BLOCKSIZE 0X80
void GUI_X_Config(void) {
//
// 32 bit aligned memory area
//
static U32 aMemory[GUI_NUMBYTES / 4];
//
// Assign memory to emWin
//
GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE);
//
// Set default font
//
GUI_SetDefaultFont(GUI_FONT_6X8);
}
接下來打開GUIDRV_Template.c,來添加此GUI繪製LCD畫面的執行方法,
首先在static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex)加入畫點的方法,如下所示,
static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) {
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
GUI_USE_PARA(PixelIndex);
{
//
// Write into hardware ... Adapt to your system
//
// TBD by customer...
//
LCD_DrawPoint(x, y, PixelIndex);
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
}
在static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y)加入讀點的方法,如下所示,
static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
unsigned int PixelIndex;
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
{
//
// Write into hardware ... Adapt to your system
//
// TBD by customer...
//
//PixelIndex = 0;
PixelIndex = LCD_ReadPoint(x, y);
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
return PixelIndex;
}
只要修改畫點與讀點這兩個方法,就可以執行此GUI所提供的全部繪圖方法,但有些方法在執行效果與速度上會不太好,為了提升繪圖執行效果與速度,接下來還需要修改四個方法,
修改static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1),新增填滿顏色矩形的方法,如下所示,
static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) {
LCD_PIXELINDEX PixelIndex;
int x;
PixelIndex = LCD__GetColorIndex();
if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) {
for (; y0 <= y1; y0++) {
for (x = x0; x <= x1; x++) {
_XorPixel(pDevice, x, y0);
}
}
} else {
/*
for (; y0 <= y1; y0++) {
for (x = x0; x <= x1; x++) {
_SetPixelIndex(pDevice, x, y0, PixelIndex);
}
}
*/
LCD_Fill(x0, y0, x1, y1, PixelIndex);
}
}
修改static void _DrawHLine(GUI_DEVICE * pDevice, int x0, int y, int x1),新增畫水平線的方法,如下所示,
static void _DrawHLine(GUI_DEVICE * pDevice, int x0, int y, int x1) {
//_FillRect(pDevice, x0, y, x1, y);
LCD_PIXELINDEX PixelIndex;
PixelIndex = LCD__GetColorIndex();
LCD_DrawLine(x0, y, x1, y, PixelIndex);
}
其中以下兩行程式為讀取當前所設定的顏色,
LCD_PIXELINDEX PixelIndex;
PixelIndex = LCD__GetColorIndex();
修改static void _DrawVLine(GUI_DEVICE * pDevice, int x, int y0, int y1),新增畫垂直線的方法,如下所示,
static void _DrawVLine(GUI_DEVICE * pDevice, int x, int y0, int y1) {
//_FillRect(pDevice, x, y0, x, y1);
LCD_PIXELINDEX PixelIndex;
PixelIndex = LCD__GetColorIndex();
LCD_DrawLine(x, y0, x, y1, PixelIndex);
}
修改static void _DrawBitLine16BPP(GUI_DEVICE * pDevice, int x, int y, U16 const GUI_UNI_PTR * p, int xsize),如下所示,
static void _DrawBitLine16BPP(GUI_DEVICE * pDevice, int x, int y, U16 const GUI_UNI_PTR * p, int xsize) {
LCD_PIXELINDEX pixel;
/* 設置起始座標 */
LCD_SetCursor(x,y);
/* 執行LCD寫入命令 */
LCD_WriteReg(RAMWR);
/* 將多個資料寫入LCD去執行 */
for (;xsize > 0; xsize--, x++, p++) {
//_SetPixelIndex(pDevice, x, y, *p);
pixel = *p;
LCD_WriteData(pixel);
}
}
打開LCDConf_FlexColor_Template.c來進行修改,這裡主要是刪除不必要的程式碼,
static void LcdWriteReg(U16 Data)
static void LcdWriteData(U16 Data)
static void LcdWriteDataMultiple(U16 * pData, int NumItems)
static void LcdReadDataMultiple(U16 * pData, int NumItems)
以上這四隻程式執行刪除,而void LCD_X_Config(void)就直接保留以下程式碼,其餘都刪除,如下所示,
void LCD_X_Config(void) {
GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_565, 0, 0);
LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
}
在\GUI_Demo\inc中的GUI_ConfDefaults.h,主要是修改顏色執行順序,在第87行以下說預設顏色執行順序為BGR,這裡要改成RGB這順序來執行,修改結果如下所示,
以上都修改完畢後就可以進行程式撰寫,STemWin可以使用編輯軟體來快速產生程式碼,工具放在\STemWin_Library_V1.2.0\Libraries\STemWinLibrary532\Software裡,如下所示,
這裡我示範BmpCvtST.exe這軟體,其餘可自行操作了解,點擊BmpCvtST.exe進入以下面畫按下"OK",如下所示,
進入後在File->Open選擇.bmp圖片
匯入結果如下所示,
在File->Save As...選擇儲存為.c檔,如下所示,
點擊存檔會跳出一個選擇視窗,此視窗是選擇此圖片的編碼方式,本人的LCD是採用16bit 565的方式顯示,所以就選擇565,如下所示,
產生出的.c檔如下所示,
接下來在\GUI_Demo\src新增MainTask.c來撰寫圖片顯示程式,如下所示,
將img-thing.c裡面的程式碼複製至MainTask.c裡,在MainTask.c裡新增void MainTask(void)來進行執行,如下所示,
void MainTask(void){
/* GUI初始化 */
GUI_Init();
/* 設定背景色為黑色 */
GUI_SetBkColor(GUI_BLACK);
/* 清除畫面為黑色 */
GUI_Clear();
/* 執行bmimgthing,圖片顯示位置在(60,60)的位置 */
GUI_DrawBitmap(&bmimgthing,60 ,60);
for(;;){
}
}
在\User\src中的main.c增加執行MainTask()此方法,如下所示,
#include "main.h"
/*
程式名稱:主程式
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/6
程式修改日期:N/A
程式說明:
*/
int main(void){
/* 啟用CRC校驗 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC,ENABLE);
/* 開發板全域變數初始化 */
BSP_VariableInit();
/* 開發板整體系統初始化 */
BSP_Init();
/* 執行圖片顯示 */
MainTask();
/* Infinite loop */
for(;;){
}
}
最後編譯->燒入->執行後結果如下所示,
留言列表