笔者之前做了一个带LCD屏的项目,根据评估,果断选择 STemWin + FreeRTOS的方案。下面讲讲移植优化emWin的过程 -------------------- 不喜勿喷呀!
基本硬件平台:STM32F205VGTx(Cortex M3) 3.5寸LCD屏(ILI9488)------------- 没有SDRAM,所以资源不怎样
移植相关平台:FreeRTOS V9.0.0 STemWin528
1.FreeRTOS移植内容
OS根目录必备资源如图
根据MCU型号,工程配置文件如下(具体可以找找相关资料,这里不细讲了):
2.STemWin移植
根目录下基本文件夹如下(资源具体作用,根据名称,也能猜到部分,config是配置相关的参考例子,笔者直接使用的是修改后的GUIConfig)
因为采用的是带OS的emWin 所以注意别移植错了(如:GUI_X_FreeRTOS CM3_OS_Keil.lib);xBSP_LCD_Config 实际是 LCDConf 的变体,笔者加了相关LCD配置,加上个人命名习惯,所以采用这个名称。
GUI_X_FreeRTOS 具体内容,看了这些大家也知道为什么必须移植修改这部分了吧:
3.emWin的优化:
$1.LCD驱动的优化:
根据LCD IC型号,项目中用到的刷屏方向,刷新速率来修改,下面展示修改比较重要的部分(分段的哦):
LcdWriteReg(0xB1); //Frame rate
LcdWriteData(0xC0);
LcdWriteData(0x11);
LcdWriteReg(0xB6); //Display Function Control
LcdWriteData(0x02);
LcdWriteData((0<<6)|(1<<5)|(0<<4)); //D6:GS D5:SS D4:SM //0x22
LcdWriteReg(0x36);
LcdWriteData((1<<7)|(0<<6)|(0<<5)|(1<<4)|(0<<2)); //D7:MY D6:MX D5:MV D4:V Refersh D2:H Refersh
SRAM_Timing.AddressSetupTime = 1;
SRAM_Timing.AddressHoldTime = 0;
SRAM_Timing.DataSetupTime = 1; /* 根据SRAM的最大速度进行调整 */
SRAM_Timing.BusTurnAroundDuration = 0;
SRAM_Timing.CLKDivision = 0;
SRAM_Timing.DataLatency = 0;
另外根据将基本的绘制通过写命令的方式直接得到,这样用到emWin上会大大提高绘制时间,减少MCU负荷(下面的函数将用到emWin 中):
void xLCD_SetPixel(uint16_t _usX, uint16_t _usY, uint16_t _usColor)
{
xLCD_SetCursor(_usX,_usY); //设置光标位置
LcdWriteReg(0x2c);
LcdWriteData(_usColor);
}
uint16_t xLCD_GetPixel(uint16_t _usX, uint16_t _usY)
{
uint16_t R = 0, G = 0, B = 0 ;
xLCD_SetCursor(_usX,_usY); //设置光标位置
LcdWriteReg(0x2e);
R = LcdReadData(); /* 第1个哑读,丢弃 */
R = LcdReadData();
G = LcdReadData();
B = LcdReadData();
return (((R >> 11) << 11) | ((G >> 10 ) << 5) | (B >> 11));
}
void xLCD_DrawVLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usY2 , uint16_t _usColor)
void xLCD_DrawHLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usColor)
void xLCD_DrawLine(uint16_t _usX1 , uint16_t _usY1 , uint16_t _usX2 , uint16_t _usY2 , uint16_t _usColor)
void xLCD_DrawRect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor)
void xLCD_DrawFillRect(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth, uint16_t _usColor)
$2.emWin 初始化 和 驱动的优化:
前面已经说了我们最好根据项目需要,选择最优的刷屏方向(横屏还是竖屏),另外选对RGB 还是 GBR(IC手册有命令),能用命令解决,就用命令解决,不要让emWin来帮我们配置好,这样效率很低下。
void LCD_X_Config(void)
{
GUI_DEVICE *pDevice;
CONFIG_FLEXCOLOR Config = {0};
GUI_PORT_API PortAPI = {0};
//
// Set display driver and color conversion
//
pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_565, 0, 0); //RGB 基础色配置选择 GUICC_565 //
//
// Display driver configuration, required for Lin-driver
//
LCD_SetSizeEx(0, XSIZE_PHYS , YSIZE_PHYS);
LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
// LCD_SetSizeEx(0, 480 , 320);
// LCD_SetVSizeEx(0, 480, 320);
//
// Orientation
//
Config.FirstCOM = 0;
Config.FirstSEG = 0;
Config.NumDummyReads = 2;
{
// Config.Orientation = GUI_SWAP_XY| GUI_MIRROR_Y;//
}
GUIDRV_FlexColor_Config(pDevice, &Config);
//
// Set controller and operation mode
//
PortAPI.pfWrite16_A0 = LcdWriteReg;
PortAPI.pfWrite16_A1 = LcdWriteData;
PortAPI.pfWriteM16_A1 = LcdWriteDataMultiple;
PortAPI.pfReadM16_A1 = LcdReadDataMultiple;
PortAPI.pfRead16_A1 = LcdReadData;
// Find the current LCD and initialize GUIDRV
GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66709, GUIDRV_FLEXCOLOR_M16C0B16); // GUIDRV_FLEXCOLOR_M16C0B8
}
接下来,很重要的优化部分,在GUIDRV.c中,因为只要我们使用emWin,那么最基本绘制都调用这里的函数,所以我们必须优化这里。最基本的绘制是什么呢?无非就是点,线,面。这里我们直接使用自己配置好基础绘制,删除emWin自带的。
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);
{
//优化位置
xLCD_SetPixel(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) {
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 = xLCD_GetPixel(xPhys, yPhys);
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
return PixelIndex;
}
内容较多,直接省略掉。。。。。。
最终结果,你会发现,LCD刷屏快,绘制速度快,这样我们大大释放了MCU,那岂不美滋滋!!!
具体代码可以根据链接下载 https://download.csdn.net/download/weixin_38426553/11032284