普中科技-麒麟F407-开发板基础实验的中间件StemWin移植到FreeRTOS项目中 操作要点记录
StemWin version 5.22,移植到cubeMX生成的FreeRTOS上,芯片STM32F407ZETR。
一、移植举例:
1、移植时,添加到项目中的emWin的.c和lib文件有:
STemWin\Config\GUIConf.c
STemWin\Config\GUIDRV_Template.c
STemWin\Config\LCDConf_FlexColor_Template.c
STemWin\Config\GUI_X_Touch_Analog.c
STemWin\OS\GUI_X_FreeRTOS.c
STemWin\Lib\STemWin526_CM4_OS_Keil.lib
注意添加头文件。 sram.h , touch.h, tftlcd.h是用户你开发SRAM、触摸屏、显示屏的外设驱动。
2、在GUIConf.c配置emWin使用的RAM
#include "GUI.h" #include "sram.h" // GUI的RAM驱动,移植时添加 ////GUI_X_Config ////初始化的时候调用,用来设置emwin所使用的内存 /* 定义用于GUI的可用字节数 */ #if USE_EXTMEMHEAP #define GUI_NUMBYTES (512* 2*1024) // xByte 移植:外扩SRAM的BYTE数 #else #define GUI_NUMBYTES (1024 * 32) // xByte #endif #ifdef USE_EXTMEMHEAP static U32 HeapMem[GUI_NUMBYTES / 4] __attribute__((at( Bank1_SRAM3_ADDR))); //移植: Bank1_SRAM3_ADDR 外扩SRAM首地址,见"sram.h" #else static U32 extMem[GUI_NUMBYTES / 4]; #endif void GUI_X_Config(void) { #if USE_EXTMEMHEAP GUI_ALLOC_AssignMemory(HeapMem, GUI_NUMBYTES); #else GUI_ALLOC_AssignMemory(extMem, GUI_NUMBYTES); #endif }
3、在GUIDRV_Template.c修改emWin使用的屏幕画点、读点和颜色填充函数
/********************************************************************* * Portions COPYRIGHT 2013 STMicroelectronics * * Portions SEGGER Microcontroller GmbH & Co. KG * * Solutions for real time microcontroller applications * ********************************************************************** * * * (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * * * * Internet: www.segger.com Support: support@segger.com * * * ********************************************************************** ** emWin V5.22 - Graphical user interface for embedded applications ** All Intellectual Property rights in the Software belongs to SEGGER. emWin is protected by international copyright laws. Knowledge of the source code may not be used to write a similar product. This file may only be used in accordance with the following terms: The software has been licensed to STMicroelectronics International N.V. a Dutch company with a Swiss branch and its headquarters in Plan- les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ troller products commercialized by Licensee only, sublicensed and dis_ tributed under the terms and conditions of the End User License Agree_ ment supplied by STMicroelectronics International N.V. Full source code is available at: www.segger.com We appreciate your understanding and fairness. ---------------------------------------------------------------------- File : GUIDRV_Template.c Purpose : Template driver, could be used as starting point for new simple display drivers supporting only one color depth. ---------------------------END-OF-HEADER------------------------------ */ /** ****************************************************************************** * @attention * * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ #include <stddef.h> #include "LCD_Private.h" #include "GUI_Private.h" #include "LCD_ConfDefaults.h" #include "tftlcd.h" // 显示屏驱动,移植时添加 /********************************************************************* * * Defines * ********************************************************************** */ /********************************************************************* * * Macros for MIRROR_, SWAP_ and LUT_ */ #if (!defined (LCD_LUT_COM) && !defined(LCD_LUT_SEG)) #if (!LCD_MIRROR_X && !LCD_MIRROR_Y && !LCD_SWAP_XY) #define LOG2PHYS_X(x, y) x #define LOG2PHYS_Y(x, y) y #elif (!LCD_MIRROR_X && !LCD_MIRROR_Y && LCD_SWAP_XY) #define LOG2PHYS_X(x, y) y #define LOG2PHYS_Y(x, y) x #elif (!LCD_MIRROR_X && LCD_MIRROR_Y && !LCD_SWAP_XY) #define LOG2PHYS_X(x, y) x #define LOG2PHYS_Y(x, y) LCD_YSIZE - 1 - (y) #elif (!LCD_MIRROR_X && LCD_MIRROR_Y && LCD_SWAP_XY) #define LOG2PHYS_X(x, y) y #define LOG2PHYS_Y(x, y) LCD_XSIZE - 1 - (x) #elif ( LCD_MIRROR_X && !LCD_MIRROR_Y && !LCD_SWAP_XY) #define LOG2PHYS_X(x, y) LCD_XSIZE - 1 - (x) #define LOG2PHYS_Y(x, y) y #elif ( LCD_MIRROR_X && !LCD_MIRROR_Y && LCD_SWAP_XY) #define LOG2PHYS_X(x, y) LCD_YSIZE - 1 - (y) #define LOG2PHYS_Y(x, y) x #elif ( LCD_MIRROR_X && LCD_MIRROR_Y && !LCD_SWAP_XY) #define LOG2PHYS_X(x, y) LCD_XSIZE - 1 - (x) #define LOG2PHYS_Y(x, y) LCD_YSIZE - 1 - (y) #elif ( LCD_MIRROR_X && LCD_MIRROR_Y && LCD_SWAP_XY) #define LOG2PHYS_X(x, y) LCD_YSIZE - 1 - (y) #define LOG2PHYS_Y(x, y) LCD_XSIZE - 1 - (x) #endif #else #if ( defined (LCD_LUT_COM) && !defined(LCD_LUT_SEG)) #define LOG2PHYS_X(x, y) x #define LOG2PHYS_Y(x, y) LCD__aLine2Com0[y] #elif (!defined (LCD_LUT_COM) && defined(LCD_LUT_SEG)) #define LOG2PHYS_X(x, y) LCD__aCol2Seg0[x] #define LOG2PHYS_Y(x, y) y #elif ( defined (LCD_LUT_COM) && defined(LCD_LUT_SEG)) #define LOG2PHYS_X(x, y) LCD__aCol2Seg0[x] #define LOG2PHYS_Y(x, y) LCD__aLine2Com0[y] #endif #endif /********************************************************************* * * Types * ********************************************************************** */ typedef struct { U32 VRAMAddr; int xSize, ySize; int vxSize, vySize; int vxSizePhys; int BitsPerPixel; } DRIVER_CONTEXT_TEMPLATE; /********************************************************************* * * Static functions * ********************************************************************** */ /********************************************************************* 打点函数 设置在像素坐标点(x,y)的颜色值,移植时需修改。 */ static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) { LCD_DrawFRONT_COLOR(x,y,PixelIndex); //移植:调用tftlcd.c文件中的打点函数 } /********************************************************************* * 读点函数 移植:读取像素坐标点(x,y)的颜色值,移植时需修改。 */ static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) { unsigned int PixelIndex; #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); { PixelIndex = LCD_ReadPoint(x,y);//移植:调用tftlcd.c } #if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0) #undef xPhys #undef yPhys #endif return PixelIndex; } /********************************************************************* * * _XorPixel */ static void _XorPixel(GUI_DEVICE * pDevice, int x, int y) { LCD_PIXELINDEX PixelIndex; LCD_PIXELINDEX IndexMask; PixelIndex = _GetPixelIndex(pDevice, x, y); IndexMask = pDevice->pColorConvAPI->pfGetIndexMask(); _SetPixelIndex(pDevice, x, y, PixelIndex ^ IndexMask); } /********************************************************************* * * _FillRect 移植:颜色填充矩形区域,移植时需修改。 */ static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) { LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX);//移植:调用tftlcd.c } /********************************************************************* * * _DrawHLine */ static void _DrawHLine(GUI_DEVICE * pDevice, int x0, int y, int x1) { _FillRect(pDevice, x0, y, x1, y); } /********************************************************************* * * _DrawVLine, not optimized */ static void _DrawVLine(GUI_DEVICE * pDevice, int x, int y0, int y1) { _FillRect(pDevice, x, y0, x, y1); } /********************************************************************* * * Draw Bitmap 1 BPP */ static void _DrawBitLine1BPP(GUI_DEVICE * pDevice, int x, int y, U8 const GUI_UNI_PTR * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) { LCD_PIXELINDEX IndexMask, Index0, Index1, Pixel; Index0 = *(pTrans + 0); Index1 = *(pTrans + 1); x += Diff; switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: do { _SetPixelIndex(pDevice, x++, y, (*p & (0x80 >> Diff)) ? Index1 : Index0); if (++Diff == 8) { Diff = 0; p++; } } while (--xsize); break; case LCD_DRAWMODE_TRANS: do { if (*p & (0x80 >> Diff)) _SetPixelIndex(pDevice, x, y, Index1); x++; if (++Diff == 8) { Diff = 0; p++; } } while (--xsize); break; case LCD_DRAWMODE_XOR | LCD_DRAWMODE_TRANS: case LCD_DRAWMODE_XOR: IndexMask = pDevice->pColorConvAPI->pfGetIndexMask(); do { if (*p & (0x80 >> Diff)) { Pixel = _GetPixelIndex(pDevice, x, y); _SetPixelIndex(pDevice, x, y, Pixel ^ IndexMask); } x++; if (++Diff == 8) { Diff = 0; p++; } } while (--xsize); break; } } /********************************************************************* * * Draw Bitmap 2 BPP */ static void _DrawBitLine2BPP(GUI_DEVICE * pDevice, int x, int y, U8 const GUI_UNI_PTR * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) { LCD_PIXELINDEX Pixels, PixelIndex; int CurrentPixel, Shift, Index; Pixels = *p; CurrentPixel = Diff; x += Diff; switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: if (pTrans) { do { Shift = (3 - CurrentPixel) << 1; Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; PixelIndex = *(pTrans + Index); _SetPixelIndex(pDevice, x++, y, PixelIndex); if (++CurrentPixel == 4) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } else { do { Shift = (3 - CurrentPixel) << 1; Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; _SetPixelIndex(pDevice, x++, y, Index); if (++CurrentPixel == 4) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } break; case LCD_DRAWMODE_TRANS: if (pTrans) { do { Shift = (3 - CurrentPixel) << 1; Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; if (Index) { PixelIndex = *(pTrans + Index); _SetPixelIndex(pDevice, x, y, PixelIndex); } x++; if (++CurrentPixel == 4) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } else { do { Shift = (3 - CurrentPixel) << 1; Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; if (Index) { _SetPixelIndex(pDevice, x, y, Index); } x++; if (++CurrentPixel == 4) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } break; } } /********************************************************************* * * Draw Bitmap 4 BPP */ static void _DrawBitLine4BPP(GUI_DEVICE * pDevice, int x, int y, U8 const GUI_UNI_PTR * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) { LCD_PIXELINDEX Pixels, PixelIndex; int CurrentPixel, Shift, Index; Pixels = *p; CurrentPixel = Diff; x += Diff; switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: if (pTrans) { do { Shift = (1 - CurrentPixel) << 2; Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; PixelIndex = *(pTrans + Index); _SetPixelIndex(pDevice, x++, y, PixelIndex); if (++CurrentPixel == 2) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } else { do { Shift = (1 - CurrentPixel) << 2; Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; _SetPixelIndex(pDevice, x++, y, Index); if (++CurrentPixel == 2) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } break; case LCD_DRAWMODE_TRANS: if (pTrans) { do { Shift = (1 - CurrentPixel) << 2; Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; if (Index) { PixelIndex = *(pTrans + Index); _SetPixelIndex(pDevice, x, y, PixelIndex); } x++; if (++CurrentPixel == 2) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } else { do { Shift = (1 - CurrentPixel) << 2; Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; if (Index) { _SetPixelIndex(pDevice, x, y, Index); } x++; if (++CurrentPixel == 2) { CurrentPixel = 0; Pixels = *(++p); } } while (--xsize); } break; } } /********************************************************************* * * Draw Bitmap 8 BPP */ static void _DrawBitLine8BPP(GUI_DEVICE * pDevice, int x, int y, U8 const GUI_UNI_PTR * p, int xsize, const LCD_PIXELINDEX * pTrans) { LCD_PIXELINDEX Pixel; switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: if (pTrans) { for (; xsize > 0; xsize--, x++, p++) { Pixel = *p; _SetPixelIndex(pDevice, x, y, *(pTrans + Pixel)); } } else { for (; xsize > 0; xsize--, x++, p++) { _SetPixelIndex(pDevice, x, y, *p); } } break; case LCD_DRAWMODE_TRANS: if (pTrans) { for (; xsize > 0; xsize--, x++, p++) { Pixel = *p; if (Pixel) { _SetPixelIndex(pDevice, x, y, *(pTrans + Pixel)); } } } else { for (; xsize > 0; xsize--, x++, p++) { Pixel = *p; if (Pixel) { _SetPixelIndex(pDevice, x, y, Pixel); } } } break; } } /********************************************************************* * * Draw Bitmap 16 BPP, not optimized 绘图像,移植时需修改。 * * Purpose: * Drawing of 16bpp high color bitmaps. * Only required for 16bpp color depth of target. Should be removed otherwise. * */ static void _DrawBitLine16BPP(GUI_DEVICE * pDevice, int x, int y, U16 const GUI_UNI_PTR * p, int xsize) { LCD_PIXELINDEX pixel; for (;xsize > 0; xsize--, x++, p++) { if(xsize>tftlcd_data.width)y++;//移植:调用tftlcd.c LCD_Set_Window(x,y,tftlcd_data.width-xsize,y);//移植:调用tftlcd.c pixel = *p; LCD_WriteData_Color(pixel);//移植:调用tftlcd.c //led2=0; //printf("x=%d y=%d pixel=%x\r\n",x,y,pixel); } } /********************************************************************* * * Draw Bitmap 32 BPP, not optimized * * Purpose: * Drawing of 32bpp true color bitmaps. * Only required for 32bpp color depth of target. Should be removed otherwise. */ static void _DrawBitLine32BPP(GUI_DEVICE * pDevice, int x, int y, U32 const GUI_UNI_PTR * p, int xsize) { for (;xsize > 0; xsize--, x++, p++) { _SetPixelIndex(pDevice, x, y, *p); } } /********************************************************************* * * _DrawBitmap */ static void _DrawBitmap(GUI_DEVICE * pDevice, int x0, int y0, int xSize, int ySize, int BitsPerPixel, int BytesPerLine, const U8 GUI_UNI_PTR * pData, int Diff, const LCD_PIXELINDEX * pTrans) { int i; switch (BitsPerPixel) { case 1: for (i = 0; i < ySize; i++) { _DrawBitLine1BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans); pData += BytesPerLine; } break; case 2: for (i = 0; i < ySize; i++) { _DrawBitLine2BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans); pData += BytesPerLine; } break; case 4: for (i = 0; i < ySize; i++) { _DrawBitLine4BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans); pData += BytesPerLine; } break; case 8: for (i = 0; i < ySize; i++) { _DrawBitLine8BPP(pDevice, x0, i + y0, pData, xSize, pTrans); pData += BytesPerLine; } break; // // Only required for 16bpp color depth of target. Should be removed otherwise. // case 16: for (i = 0; i < ySize; i++) { _DrawBitLine16BPP(pDevice, x0, i + y0, (const U16 *)pData, xSize); pData += BytesPerLine; } break; // // Only required for 32bpp color depth of target. Should be removed otherwise. // case 32: for (i = 0; i < ySize; i++) { _DrawBitLine32BPP(pDevice, x0, i + y0, (const U32 *)pData, xSize); pData += BytesPerLine; } break; } } /********************************************************************* * * _InitOnce * * Purpose: * Allocates a fixed block for the context of the driver * * Return value: * 0 on success, 1 on error */ static int _InitOnce(GUI_DEVICE * pDevice) { DRIVER_CONTEXT_TEMPLATE * pContext; if (pDevice->u.pContext == NULL) { pDevice->u.pContext = GUI_ALLOC_GetFixedBlock(sizeof(DRIVER_CONTEXT_TEMPLATE)); pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext; pContext->BitsPerPixel = LCD__GetBPP(pDevice->pColorConvAPI->pfGetIndexMask()); } return pDevice->u.pContext ? 0 : 1; } /********************************************************************* * * _GetDevProp */ static I32 _GetDevProp(GUI_DEVICE * pDevice, int Index) { DRIVER_CONTEXT_TEMPLATE * pContext; pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext; switch (Index) { case LCD_DEVCAP_XSIZE: return pContext->xSize; case LCD_DEVCAP_YSIZE: return pContext->ySize; case LCD_DEVCAP_VXSIZE: return pContext->vxSize; case LCD_DEVCAP_VYSIZE: return pContext->vySize; case LCD_DEVCAP_BITSPERPIXEL: return pContext->BitsPerPixel; case LCD_DEVCAP_NUMCOLORS: return 0; case LCD_DEVCAP_XMAG: return 1; case LCD_DEVCAP_YMAG: return 1; case LCD_DEVCAP_MIRROR_X: return 0; case LCD_DEVCAP_MIRROR_Y: return 0; case LCD_DEVCAP_SWAP_XY: return 0; } return -1; } /********************************************************************* * * _GetDevData */ static void * _GetDevData(GUI_DEVICE * pDevice, int Index) { GUI_USE_PARA(pDevice); #if GUI_SUPPORT_MEMDEV switch (Index) { case LCD_DEVDATA_MEMDEV: return (void *)&GUI_MEMDEV_DEVICE_16; // TBD: Has to be adapted to the right memory device depending on the used color depth! } #else GUI_USE_PARA(Index); #endif return NULL; } /********************************************************************* * * _GetRect */ static void _GetRect(GUI_DEVICE * pDevice, LCD_RECT * pRect) { DRIVER_CONTEXT_TEMPLATE * pContext; pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext; pRect->x0 = 0; pRect->y0 = 0; pRect->x1 = pContext->vxSize - 1; pRect->y1 = pContext->vySize - 1; } /********************************************************************* * * _SetOrg */ static void _SetOrg(GUI_DEVICE * pDevice, int x, int y) { LCD_X_SETORG_INFO Data = {0}; Data.xPos = x; Data.yPos = y; LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETORG, (void *)&Data); } /********************************************************************* * * Static code: Functions available by _GetDevFunc() * ********************************************************************** */ /********************************************************************* * * _SetVRAMAddr */ static void _SetVRAMAddr(GUI_DEVICE * pDevice, void * pVRAM) { DRIVER_CONTEXT_TEMPLATE * pContext; LCD_X_SETVRAMADDR_INFO Data = {0}; _InitOnce(pDevice); if (pDevice->u.pContext) { pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext; pContext->VRAMAddr = (U32)pVRAM; Data.pVRAM = pVRAM; LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETVRAMADDR, (void *)&Data); } } /********************************************************************* * * _SetVSize */ static void _SetVSize(GUI_DEVICE * pDevice, int xSize, int ySize) { DRIVER_CONTEXT_TEMPLATE * pContext; _InitOnce(pDevice); if (pDevice->u.pContext) { pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext; pContext->vxSize = xSize; pContext->vySize = ySize; pContext->vxSizePhys = xSize; } } /********************************************************************* * * _SetSize */ static void _SetSize(GUI_DEVICE * pDevice, int xSize, int ySize) { DRIVER_CONTEXT_TEMPLATE * pContext; LCD_X_SETSIZE_INFO Data = {0}; _InitOnce(pDevice); if (pDevice->u.pContext) { pContext = (DRIVER_CONTEXT_TEMPLATE *)pDevice->u.pContext; pContext->vxSizePhys = (pContext->vxSizePhys == 0) ? xSize : pContext->vxSizePhys; pContext->xSize = xSize; pContext->ySize = ySize; Data.xSize = xSize; Data.ySize = ySize; LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETSIZE, (void *)&Data); } } /********************************************************************* * * _Init */ static int _Init(GUI_DEVICE * pDevice) { int r; r = _InitOnce(pDevice); r |= LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_INITCONTROLLER, NULL); return r; } /********************************************************************* * * _On */ static void _On (GUI_DEVICE * pDevice) { LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_ON, NULL); } /********************************************************************* * * _Off */ static void _Off (GUI_DEVICE * pDevice) { LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_OFF, NULL); } /********************************************************************* * * _SetLUTEntry */ static void _SetLUTEntry(GUI_DEVICE * pDevice, U8 Pos, LCD_COLOR Color) { LCD_X_SETLUTENTRY_INFO Data = {0}; Data.Pos = Pos; Data.Color = Color; LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETLUTENTRY, (void *)&Data); } /********************************************************************* * * _GetDevFunc */ static void (* _GetDevFunc(GUI_DEVICE ** ppDevice, int Index))(void) { GUI_USE_PARA(ppDevice); switch (Index) { case LCD_DEVFUNC_SET_VRAM_ADDR: return (void (*)(void))_SetVRAMAddr; case LCD_DEVFUNC_SET_VSIZE: return (void (*)(void))_SetVSize; case LCD_DEVFUNC_SET_SIZE: return (void (*)(void))_SetSize; case LCD_DEVFUNC_INIT: return (void (*)(void))_Init; case LCD_DEVFUNC_ON: return (void (*)(void))_On; case LCD_DEVFUNC_OFF: return (void (*)(void))_Off; case LCD_DEVFUNC_SETLUTENTRY: return (void (*)(void))_SetLUTEntry; } return NULL; } /********************************************************************* * * Public data * ********************************************************************** */ /********************************************************************* * * GUI_DEVICE_API structure */ const GUI_DEVICE_API GUIDRV_Template_API = { // // Data // DEVICE_CLASS_DRIVER, // // Drawing functions // _DrawBitmap, _DrawHLine, _DrawVLine, _FillRect, _GetPixelIndex, _SetPixelIndex, _XorPixel, // // Set origin // _SetOrg, // // Request information // _GetDevFunc, _GetDevProp, _GetDevData, _GetRect, }; /*************************** End of file ****************************/
4、在LCDConf_FlexColor_Template.c修改emWin使用的屏幕大小,横竖屏等参数
#include "GUI.h" #include "tftlcd.h" #include "touch.h" #include "GUIDRV_Template.h" #include "GUIDRV_FlexColor.h" //与触摸屏有关定义,根据实际情况填写 #define TOUCH_AD_TOP 160 //按下触摸屏的顶部,写下 Y 轴模拟输入值。 #define TOUCH_AD_BOTTOM 3990 //按下触摸屏的底部,写下 Y 轴模拟输入值。 #define TOUCH_AD_LEFT 160 //按下触摸屏的左侧,写下 X 轴模拟输入值。 #define TOUCH_AD_RIGHT 3990 //按下触摸屏的右侧,写下 X 轴模拟输入值。 //#define TOUCH_AD_TOP 3390 //按下触摸屏的顶部,写下 Y 轴模拟输入值。 //#define TOUCH_AD_BOTTOM 160 //按下触摸屏的底部,写下 Y 轴模拟输入值。 //#define TOUCH_AD_LEFT 3990 //按下触摸屏的左侧,写下 X 轴模拟输入值。 //#define TOUCH_AD_RIGHT 160 //按下触摸屏的右侧,写下 X 轴模拟输入值。 //屏幕大小 #define XSIZE_PHYS 480 //X轴 移植:修改 #define YSIZE_PHYS 800 //Y轴 移植:修改 #define VXSIZE_PHYS 800 //移植:修改 #define VYSIZE_PHYS 480 //移植:修改 //配置检查 #ifndef VXSIZE_PHYS #define VXSIZE_PHYS XSIZE_PHYS #endif #ifndef VYSIZE_PHYS #define VYSIZE_PHYS YSIZE_PHYS #endif #ifndef XSIZE_PHYS #error Physical X size of display is not defined! #endif #ifndef YSIZE_PHYS #error Physical Y size of display is not defined! #endif #ifndef GUICC_565 #error Color conversion not defined! #endif #ifndef GUIDRV_FLEXCOLOR #error No display driver defined! #endif //配置程序,用于创建显示驱动器件,设置颜色转换程序和显示尺寸 void LCD_X_Config(void) { GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0); //创建显示驱动器件 LCD_SetSizeEx (0, tftlcd_data.width , tftlcd_data.height);//移植:使用tftlcd LCD_SetVSizeEx(0, tftlcd_data.width , tftlcd_data.height);//移植:使用tftlcd #if defined(TFTLCD_HX8357D)||defined(TFTLCD_ILI9341)||defined(TFTLCD_HX8352C)|| \ defined(TFTLCD_R61509V)||defined(TFTLCD_R61509VN)||defined(TFTLCD_R61509V3)|| \ defined(TFTLCD_ILI9486)||defined(TFTLCD_ST7793)||defined(TFTLCD_ILI9325)|| \ defined(TFTLCD_ILI9327)||defined(TFTLCD_ILI9481)||defined(TFTLCD_R61509VE)|| \ defined(TFTLCD_ILI9488)||defined(TFTLCD_HX8357DN) if(tftlcd_data.dir == 0) //竖屏 { // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 // GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.width,155,3903); // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 // GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.height,188,3935); // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.width,3903,155); // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.height,3935,188); }else //横屏 { GUI_TOUCH_SetOrientation(GUI_SWAP_XY|GUI_MIRROR_X); //|GUI_MIRROR_Y // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 // GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.height,155,3903); // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 // GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.width,188,3935); // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.height,3903,155); // 触摸屏点和显示屏点对应, 根据touch_test()函数调整 GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.width,3935,188); } #endif #if defined(TFTLCD_SSD1963N) if(tftlcd_data.dir == 0) //竖屏 { GUI_TOUCH_SetOrientation(GUI_SWAP_XY|GUI_MIRROR_Y); GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.height,155,3903); GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.width,188,3935); }else //横屏 { GUI_TOUCH_SetOrientation(GUI_MIRROR_X|GUI_MIRROR_Y); GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.width,155,3903); GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.height,188,3935); } #endif #if defined(TFTLCD_SSD1963) if(tftlcd_data.dir == 0) //竖屏 { GUI_TOUCH_SetOrientation(GUI_MIRROR_X|GUI_MIRROR_Y); GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.width,155,3903); GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.height,188,3935); }else //横屏 { GUI_TOUCH_SetOrientation(GUI_SWAP_XY|GUI_MIRROR_Y); GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.height,155,3903); GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.width,188,3935); } #endif #if defined(TFTLCD_NT35510)||defined(TFTLCD_ILI9806) if(tftlcd_data.dir == 0) //竖屏 移植:使用tftlcd { GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.width,0,479);//移植:使用tftlcd GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.height,0,799);//移植:使用tftlcd }else //横屏 { GUI_TOUCH_SetOrientation(GUI_MIRROR_X|GUI_MIRROR_Y); //|GUI_MIRROR_Y GUI_TOUCH_Calibrate(GUI_COORD_X,0,tftlcd_data.height,0,479); //移植:使用tftlcd GUI_TOUCH_Calibrate(GUI_COORD_Y,0,tftlcd_data.width,0,799); //移植:使用tftlcd } #endif } //显示器驱动的回调函数 int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) { int r; (void) LayerIndex; (void) pData; switch (Cmd) { case LCD_X_INITCONTROLLER: { //当初始化的时候被调用,主要是设置显示控制器,如果显示控制器在外部初始化则需要用户初始化 // TFTLCD_Init(); //初始化LCD 已经在开始初始化了,所以此处不需要初始化。 return 0; } default: r = -1; } return r; }
5、添加GUI_X_Touch_Analog.c,修改emWin使用的触摸屏读取X坐标、Y坐标函数
/********************************************************************* * SEGGER Microcontroller GmbH & Co. KG * * Solutions for real time microcontroller applications * ********************************************************************** * * * (c) 1996 - 2012 SEGGER Microcontroller GmbH & Co. KG * * * * Internet: www.segger.com Support: support@segger.com * * * ********************************************************************** ** emWin V5.16 - Graphical user interface for embedded applications ** All Intellectual Property rights in the Software belongs to SEGGER. emWin is protected by international copyright laws. Knowledge of the source code may not be used to write a similar product. This file may only be used in accordance with the following terms: The software has been licensed to ARM LIMITED whose registered office is situated at 110 Fulbourn Road, Cambridge CB1 9NJ, England solely for the purposes of creating libraries for ARM7, ARM9, Cortex-M series, and Cortex-R4 processor-based devices, sublicensed and distributed as part of the MDK-ARM Professional under the terms and conditions of the End User License supplied with the MDK-ARM Professional. Full source code is available at: www.segger.com We appreciate your understanding and fairness. ---------------------------------------------------------------------- File : GUI_TOUCH_X.C Purpose : Config / System dependent externals for GUI ---------------------------END-OF-HEADER------------------------------ */ #include "GUI.h" #include "touch.h" // 触摸屏驱动,移植时添加 #include "tftlcd.h" // 显示屏驱动,移植时添加 #include "usart.h" // 调试串口驱动,移植时添加 void GUI_TOUCH_X_ActivateX(void) { // XPT2046_WriteCMD(0x90); } void GUI_TOUCH_X_ActivateY(void) { //XPT2046_WriteCMD(0xd0); } int GUI_TOUCH_X_MeasureX(void) // 读取触摸屏当前点X坐标,移植时修改 { #if defined(TFTLCD_HX8357D)||defined(TFTLCD_ILI9341)||defined(TFTLCD_HX8352C)|| \ defined(TFTLCD_R61509V)||defined(TFTLCD_R61509VN)||defined(TFTLCD_R61509V3)|| \ defined(TFTLCD_ILI9486)||defined(TFTLCD_ST7793)||defined(TFTLCD_ILI9325)|| \ defined(TFTLCD_ILI9327)||defined(TFTLCD_ILI9481)||defined(TFTLCD_SSD1963)|| \ defined(TFTLCD_R61509VE)||defined(TFTLCD_SSD1963N)||defined(TFTLCD_ILI9488)|| \ defined(TFTLCD_HX8357DN) //电阻屏 //return TP_Read_AD(0XD0); //CMD_RDX=0XD0 return TP_Read_AD(0X90); //CMD_RDY=0X90 #endif #if defined(TFTLCD_NT35510)||defined(TFTLCD_ILI9806) int32_t xvalue; //电容屏 TP_Scan(0); xvalue=tp_dev.x[0]; return xvalue; #endif } int GUI_TOUCH_X_MeasureY(void) // 读取触摸屏当前点Y坐标,移植时修改 { #if defined(TFTLCD_HX8357D)||defined(TFTLCD_ILI9341)||defined(TFTLCD_HX8352C)|| \ defined(TFTLCD_R61509V)||defined(TFTLCD_R61509VN)||defined(TFTLCD_R61509V3)|| \ defined(TFTLCD_ILI9486)||defined(TFTLCD_ST7793)||defined(TFTLCD_ILI9325)|| \ defined(TFTLCD_ILI9327)||defined(TFTLCD_ILI9481)||defined(TFTLCD_SSD1963)|| \ defined(TFTLCD_R61509VE)||defined(TFTLCD_SSD1963N)||defined(TFTLCD_ILI9488)|| \ defined(TFTLCD_HX8357DN) //电阻屏 //return TP_Read_AD(0X90); //CMD_RDY=0X90 return TP_Read_AD(0XD0); //CMD_RDX=0XD0 #endif #if defined(TFTLCD_NT35510)||defined(TFTLCD_ILI9806) int32_t yvalue; //电容屏 TP_Scan(0); yvalue=tp_dev.y[0]; return yvalue; #endif }
6、GUI_X_FreeRTOS.c,直接使用,基本无修改。
7、按照使用arm的M4核,FreeRTOS选择STemWin526_CM4_OS_Keil.lib
8、特殊问题:为了周期性(25ms一次)实现触摸屏扫描,在freeRTOS中添加软定时器调用stemwin函数 如下:
GUI_X_Lock();
GUI_TOUCH_Exec();// 扫描触摸屏
GUI_X_Unlock();
在显示任务中,延时函数必须使用stemwin函数
GUI_Delay(50);//50ms延时
二、移植步骤
参考野火资料的步骤
https://doc.embedfire.com/stemwin/emwin/zh/latest/book/transplant_8080.html
三、使用GUIBuilder设计界面,生成代码
参考野火资料的步骤
https://doc.embedfire.com/stemwin/emwin/zh/latest/book/GUIBuilder.html
特殊点: 在任务函数的 for(;;){}内,必须要使用GUI_Delay(100); 不得使用osDelay(100);
/* USER CODE END Header_GuiTaskFun */ void GuiTaskFun(void *argument) { /* USER CODE BEGIN GuiTaskFun */ // 初始化见main()函数 //Touch_Test(); //GUI触摸屏功能测试 //GUIDEMO_Main();//GUI 功能演示 CreateFramewin();// GUIBuilder的使用 /* Infinite loop */ for(;;) { GUI_Delay(100);//osDelay(100); } /* USER CODE END GuiTaskFun */ }

浙公网安备 33010602011771号