准备:
硬件环境:STM32F429I-DISCOVERY
软件环境:Keil MDK v5.26
嵌入式RTOS:Keil RTX5
说明:假设已经写好了裸机的LCD驱动程序且能正常显示信息。
完整工程
链接:https://pan.baidu.com/s/1UXiAj1zWlncpJabUgPpqHQ
提取码:n8my
上一篇文章我们已经选择好了display驱动——GUIDRV_Lin,这里我们将会讲解如何使用此驱动以及如何配置等。
查看GUIDRV_Lin章节获取信息
1. 颜色深度、显示方向。我们这里选择GUIDRV_LIN_16
2. GUIDRV_Lin属于Run-Time Configurations中支持的驱动,所以这里在GUIDRV_Lin章节找到配置过程中需要用到配置函数 。如下图所示
3.
配置emWin
在emWin手册中找到Configurations章节(2669页)
从这个图中可以得出,要正常使用emWin得实现2个函数:GUI_X_Config()、LCD_X_Config()
继续查看手册,使用Run-Time配置我们需要新建3个.c文件并在相应的.c文件中实现GUI_X_Config()、LCD_X_Config()、GUI_X_Delay() 函数。结合Display driver章节中的GUIDRV_Lin的配置例程可以知道LCD_X_Config()函数中的内容信息。
编写移植代码
新建三个c文件:GUIConf.c、LCDConf.c、GUI_X.c分别用于定义我们上面提到的三个函数GUI_X_Config()、LCD_X_Config()、GUI_X_Delay()
GUIConf.c文件内容:
这里我们只需要实现GUI_X_Config()函数
#include "GUI.h"
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES 0x4000 //给GUI组件分配的RAM空间:6~10K这个在emWin手册中可以查到
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_X_Config
*
* Purpose:
* Called during the initialization process in order to set up the
* available memory for the GUI.
*/
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);
//
// Set default font
//
GUI_SetDefaultFont(GUI_FONT_6X8);
}
emWin库对系统硬件要求参考手册80页
注:查看emWin手册中Configuration中的Run-time configuration章节获取详细信息。
LCDConf.c文件:
这里需要编写的内容就比较多,需要实现LCD_X_Config() 、LCD_X_DisplayDriver() 函数。其中LCD_X_DisplayDriver() 函数是一个回调函数用于实现我们添加的一些功能,这个不是必须的。
void LCD_X_Config(void)
{
//
// Set display driver and color conversion for 1st layer
//
GUI_DEVICE_CreateAndLink(GUIDRV_LIN_16, GUICC_565, 0, 0);
//
// Display driver configuration
//
LCD_SetSizeEx (0, 320, 240);//设置屏幕大小
LCD_SetVSizeEx (0, 320, 240);//设置虚拟屏幕大小在RAM中保存的数据。
//这个地址是SDRAM中的地址,因为我们需要使用SDRAM作为LCD屏幕中显存用于保存RGB数据发送屏幕显示颜色。
//SDRAM使用最小值:屏幕率*每个像素占用的字节数。这个STM32F429I-DISCOVERY开发板对SDRAM大小为>=320*240*3=225K,这里只要给了SDRAM使用区别的起始地址。保证结束地址-起始地址 >= 225K就行。
LCD_SetVRAMAddrEx(0, (void *)0xD0000000);
/*添加自己的代码,比如:如何将LCD与emWin驱动链接上的代码*/
//
// Setting up custom functions
//
for (i = 0; i < GUI_NUM_LAYERS; i++) {
if (_aOrientation[i] == ROTATION_0) {
LCD_SetDevFunc(i, LCD_DEVFUNC_COPYBUFFER, (void(*)(void))_LCD_CopyBuffer); // Set custom function for copying complete buffers (used by multiple buffering) using DMA2D
LCD_SetDevFunc(i, LCD_DEVFUNC_COPYRECT, (void(*)(void))_LCD_CopyRect); // Set custom function for copy recxtangle areas (used by GUI_CopyRect()) using DMA2D
//
// Set functions for direct color mode layers. Won't work with indexed color modes because of missing LUT for DMA2D destination
//
PixelFormat = _GetPixelformat(i);
if (PixelFormat <= LTDC_PIXEL_FORMAT_ARGB4444) {
LCD_SetDevFunc(i, LCD_DEVFUNC_FILLRECT, (void(*)(void))_LCD_FillRect); // Set custom function for filling operations using DMA2D
LCD_SetDevFunc(i, LCD_DEVFUNC_DRAWBMP_8BPP, (void(*)(void))_LCD_DrawBitmap8bpp); // Set up custom drawing routine for index based bitmaps using DMA2D
}
//
// Set up drawing routine for 16bpp bitmap using DMA2D
//
if (PixelFormat == LTDC_PIXEL_FORMAT_RGB565) {
LCD_SetDevFunc(i, LCD_DEVFUNC_DRAWBMP_16BPP, (void(*)(void))_LCD_DrawBitmap16bpp); // Set up drawing routine for 16bpp bitmap using DMA2D. Makes only sense with RGB565
}
}
}
//
// Set up custom color conversion using DMA2D, works only for direct color modes because of missing LUT for DMA2D destination
//
GUICC_M1555I_SetCustColorConv(_Color2IndexBulk_M1555I_DMA2D, _Index2ColorBulk_M1555I_DMA2D); // Set up custom bulk color conversion using DMA2D for ARGB1555
//GUICC_M565_SetCustColorConv (_Color2IndexBulk_M565_DMA2D, _Index2ColorBulk_M565_DMA2D); // Set up custom bulk color conversion using DMA2D for RGB565 (does not speed up conversion, default method is slightly faster!)
GUICC_M4444I_SetCustColorConv(_Color2IndexBulk_M4444I_DMA2D, _Index2ColorBulk_M4444I_DMA2D); // Set up custom bulk color conversion using DMA2D for ARGB4444
GUICC_M888_SetCustColorConv (_Color2IndexBulk_M888_DMA2D, _Index2ColorBulk_M888_DMA2D); // Set up custom bulk color conversion using DMA2D for RGB888
GUICC_M8888I_SetCustColorConv(_Color2IndexBulk_M8888I_DMA2D, _Index2ColorBulk_M8888I_DMA2D); // Set up custom bulk color conversion using DMA2D for ARGB8888
//
// Set up custom alpha blending function using DMA2D
//
GUI_SetFuncAlphaBlending(_DMA_AlphaBlending); // Set up custom alpha blending function using DMA2D
//
// Set up custom function for translating a bitmap palette into index values.
// Required to load a bitmap palette into DMA2D CLUT in case of a 8bpp indexed bitmap
//
GUI_SetFuncGetpPalConvTable(_LCD_GetpPalConvTable);
//
// Set up a custom function for mixing up single colors using DMA2D
//
GUI_SetFuncMixColors(_DMA_MixColors);
//
// Set up a custom function for mixing up arrays of colors using DMA2D
//
GUI_SetFuncMixColorsBulk(_LCD_MixColorsBulk);
}
注:查看emWin手册中对LCD_SetDevFun()函数描述部分,完成LCD底层操作函数与LCD层的链接。
GUI_X.c文件:
实现GUI延时函数用于刷新UI界面
void GUI_X_Delay(int ms)
{
osDelay((uint32_t)ms);
}
使用MDK创建基于中间件——图形界面的工程
工程新建过程略,这里只说下Manage Run-Time Enviroment窗口需要添加的组件。最后点击Resolve按钮,让软件帮忙我们自动勾选需要的其他组件。
这里添加SPI组件是因为LCD屏幕在初始化过程中MCU使用了SPI接口发送命令给LCD屏幕
注:对于组件使用可以点击描述列中相应的蓝色字符,会打开相应的帮助文档。
确定内存要求
1. 由于采用R565格式,一帧数据大小:2*240*320=150KB然后还要做其他事情。这样内存不够所以使用了SDRAM空间。在代码中就需要使能DATA_IN_ExtSDRAM宏定义初始化SDRAM。
在LCD_X_Config函数中添加以下代码,将LCD使用的内存资源变量定位到SDRAM空间的变量上。
for (i = 0; i < GUI_NUM_LAYERS; i++) {
LCD_SetVRAMAddrEx(i, (void *)(_aAddr[i])); // Setting up VRam address
_aBytesPerPixels[i] = LCD_GetBitsPerPixelEx(i) >> 3; // Remember pixel size
}