【第3版emWin教程】第20章emWin6.x存储设备之基本函数

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【第3版emWin教程】第20章emWin6.x存储设备之基本函数
教程不断更新中:
第20章 emWin6.x存储设备之基本函数
本章节为⼤家讲解存储设备之基本函数,存储设备⽐较重要,如果想做出⽐较华丽,流畅的界⾯得靠这个。

另外把存储设备放在本章节讲解是因为下个章节讲解BMP,JPG和GIF的图⽚显⽰要⽤到。

20.1 初学者重要提⽰
20.2 存储设备基础知识
20.3 存储设备基本函数及其应⽤
20.4 实验例程说明(RTOS)
20.5 实验例程说明(裸机)
20.6 总结
20.1 初学者重要提⽰
1. 相对来说,存储设备章节还是⽐较重要的,初学者只需掌握本章节讲到的函数即可。

未讲解的函数也有很多,以后的⼯程中⽤到的时候再查阅即可。

2. 存储设备的的所有API函数在emWin⼿册中都有讲解,下图是中⽂版⼿册⾥⾯API函数的位置
下图是英⽂版⼿册⾥⾯API函数的位置:
20.2 存储设备基础知识
说明:介绍知识整理⾃emWin官⽅⼿册。

20.2.1 什么是存储设备
存储设备就是指的emWin的动态内存,操作存储设备就是操作emWin动态内存,只是对于这种类型的使⽤起了⼀个名字叫存储设备。

存储设备主要⽤于防⽌在绘制重叠项⽬时出现显⽰器闪烁。

其基本思想很简单,不使⽤存储设备时,绘制操作直接写⼊显⽰器,屏幕在执⾏绘制操作时随时更新,导致在进⾏各种更新时使屏幕闪烁。

例如,如果要在背景中绘制⼀个位图,在前景中绘制⼀些透明⽂本,应⾸先绘制位图,然后绘制⽂本,效果将使⽂本出现闪烁。

但是,如果在此过程中使⽤存储设备,则所有绘制操作都在存储器中执⾏,仅在所有操作都完成后才将最终结果显⽰在屏幕上,其优点是没有闪烁。

下⾯我们通过⼀个实例来说明使⽤存储设备和不使⽤存储设备的区别。

两种情况下的⽬的是相同的:将蓝⾊背景旋转10°,字符不旋转。

第⼀种情况下:不使⽤存储设备,屏幕必须清除,然后在新位置重绘多边形,并写⼊带新标志的字符串。

第⼆种情况下:使⽤存储设备,在存储器中执⾏相同的操作,但屏幕此时不更新。

仅在调⽤ GUI_MEMDEV_CopyToLCD() 例程时出现更新,并且仅更新⼀次就反映出所有操作。

请注意,这两种操作步骤的初始状态和最终输出是相同的。

通过上⾯四步对⽐可以发现:如果不使⽤存储设备,则可以看到⼀步步的绘制操作效果,缺点是会出现显⽰器闪烁。

使⽤存储设备时,仅更新⼀次可见到所有操作的效果,就象单次操作⼀样,不能实际看见中间步骤,其优点是完全消除了显⽰器的闪烁,这个就是使⽤存储设备的优势。

20.2.2 ⽀持的颜⾊深度(bpp)
bpp的含义是bit per pixel,即每个像素点由⼏位来表⽰,⽐如1bpp就表⽰每个像素点由1位⼆进制数来表⽰,8bpp就是由8位⼆进制数来表⽰,依此类推。

存储设备有 4 种不同的⾊彩深度可⽤:1bpp、 8bpp、 16bpp 和 32bpp。

emWin⽀持两种存储设备的创建⽅式。

⾃动创建与显⽰屏颜⾊格式兼容的存储设备
有两种创建与显⽰屏颜⾊格式兼容的存储设备的⽅法。

如果要避免闪烁,则应创建与显⽰器兼容的存储设备。

兼容的存储设备必须具有与显⽰器相同或更⾼的⾊彩深度。

如果使⽤了函数 GUI_MEMDEV_Create()、GUI_MEMDEV_CreateEx(),则 emWin 会⾃动为显⽰器选择正确类型的存储设备。

窗⼝管理器也能为系统中的某些或全部窗⼝使⽤存储设备,同样也使⽤这些函数。

这样会⾃动使⽤具有最低⾊彩深度(消耗动态内存最⼩)的存储设备。

创建指定颜⾊格式的存储设备
通过函数GUI_MEMDEV_CreateFixed()来实现创建指定颜⾊格式的存储设备。

20.2.3 存储设备和窗⼝管理器
(注意,窗⼝管理器在后⾯的章节中会讲到,这⾥作为了解内容即可)
窗⼝管理器可与存储设备完美搭配。

每个窗⼝都有⼀个标记,告诉窗⼝管理器是否应使⽤存储设备进⾏渲染。

此标记可以在创建窗⼝时指定,也可在任何时候进⾏设置或者重设。

如果为特定窗⼝设置了存储设备标记,则窗⼝管理器在绘制窗⼝时⾃动使⽤存储设备。

它会在绘制窗⼝前创建⼀个存储设备,然后在绘制操作完成后将其删除。

如果有⾜够的内存可⽤,会将整个窗⼝装⼊窗⼝管理器所创建存储设备的内存中。

如果没有⾜够的内存将整个窗⼝装⼊存储设备中,则窗⼝管理器使⽤“分段”来绘制窗⼝。

⽤于绘制操作的内存仅在绘制操作期间分配。

如果在绘制或者重绘窗⼝时没有⾜够的内存可⽤,则不使⽤存储设备重绘窗⼝。

20.2.4 基本函数⽤法
以下是使⽤存储设备时通常的使⽤流程,⽐较容易:
1. 创建存储设备(使⽤ GUI_MEMDEV_Create()等函数)。

2. 激活它(使⽤ GUI_MEMDEV_Select())。

3. 执⾏绘制操作。

4. 将结果复制到显⽰器中(使⽤ GUI_MEMDEV_CopyToLCD()等函数)。

5. 不再需要它时,删除该存储设备(使⽤ GUI_MEMDEV_Delete())。

20.3 存储设备基本函数及其应⽤
存储设备相关的API函数也⾮常多,这⾥我们选择⼏个常⽤的函数进⾏说明。

20.3.1 存储设备创建函数
存储设备的创建主要有以下三个函数:
GUI_MEMDEV_Handle GUI_MEMDEV_Create(int x0, int y0, int XSize, int YSize)
在位置x0,y0创建长为Xsize,宽为Ysize的存储设备,即⼀块显⽰区。

此函数会创建与显⽰器颜⾊格式兼容的存储设备(⽐如,STM32F429⽀持8种颜⾊格式设置,存储设备的创建就与这些颜⾊格式兼容)。

GUI_MEMDEV_Handle GUI_MEMDEV_CreateEx(int x0, int y0,int XSize, int Ysize,int Flags))
此函数与上⾯的函数功能⼀样,只是多了⼀个参数flag,此参数有两种数值可以取:
GUI_MEMDEV_HASTRANS
实际应⽤中推荐使⽤这个标志,表⽰使⽤透明性标记创建存储设备,该标记确保正确绘制背景。

使⽤此参数时,等效于函数GUI_MEMDEV_Create。

GUI_MEMDEV_NOTRANS
创建存储设备,⽆透明性。

优势是速度较快,使⽤此标记可加速存储设备约 30% - 50%,且可将存储设备⽤于⾮矩形区域。

缺点是⽤户必须确保正确绘制背景。

GUI_MEMDEV_Handle GUI_MEMDEV_CreateFixed(int x0, int y0,
Int xSize, int ySize, int Flags,
const tLCDDEV_APIList * pMemDevAPI,
constLCD_API_COLOR_CONV * pColorConvAPI);
此函数⽤于创建指定颜⾊格式的存储设备,这个函数涉及参数较多,我们这⾥不再进⾏说明,具体参数看emWin官⽅⼿册的API函数说明即可,实际调⽤是⽐较容易的。

下⾯是在模拟器上实际运⾏的例⼦,可以在模拟器上⾯运⾏的完整例⼦代码在V7-518_emWin6.x实验_存储设备之基础函数(模拟器)⾥⾯。

#include "GUI.h"
#include "stdio.h"
#ifndef GUI_CONST_STORAGE
#define GUI_CONST_STORAGE const
#endif
extern GUI_CONST_STORAGE GUI_BITMAP bmpic;
static GUI_CONST_STORAGE unsigned short _acpic[] = {
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF 0xFFBE, 0xFFBE, 0xFFBE, 0xFFDE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFBD, 0xF75B, 0xF6F9 0xEDD1, 0xEDD1, 0xEDD1, 0xEE13, 0xEE55, 0xF6B7, 0xF71A, 0xF75C, 0xFFBE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF /* 后⾯的数据未列出 */
};
GUI_CONST_STORAGE GUI_BITMAP bmpic = {
64, // xSize
64, // ySize
128, // BytesPerLine
16, // BitsPerPixel
(unsigned char *)_acpic, // Pointer to picture data
NULL, // Pointer to palette
GUI_DRAW_BMP565
};
static GUI_CONST_STORAGE unsigned long _acpic1[] = {
0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000 /* 后⾯的数据未列出 */
};
GUI_CONST_STORAGE GUI_BITMAP bmpic1 = {
64, // xSize
64, // ySize
256, // BytesPerLine
32, // BitsPerPixel
(unsigned char *)_acpic1, // Pointer to picture data
NULL, // Pointer to palette
GUI_DRAW_BMP8888
}
/*********************************************************************
*
* MainTask
*/
void MainTask(void) {
GUI_MEMDEV_Handle hMem0;
GUI_MEMDEV_Handle hMem1;
GUI_MEMDEV_Handle hMem2;
GUI_MEMDEV_Handle hMem3;
/* emWin初始化 */
GUI_Init();
/* 设置字体 */
GUI_SetFont(&GUI_Font16B_ASCII);
//////////////////////////⽅式⼀/////////////////////////////////////
/* 创建内存设备,并将RGB565格式的位图绘制到内存设备上 */
hMem0 = GUI_MEMDEV_CreateEx(0, 0, 64, 64, GUI_MEMDEV_HASTRANS);
GUI_MEMDEV_Select(hMem0);
GUI_DrawBitmap(&bmpic, 0, 0);
GUI_MEMDEV_Select(0);
/* 显⽰RGB565格式的位图 */
GUI_DispStringAt("This is RGB565 bitmap & GUI_MEMDEV_CreateEx", 100, 50);
GUI_MEMDEV_WriteAt(hMem0, 20, 20);
////////////////////////////⽅式⼆///////////////////////////////////
/* 创建内存设备,并将RGB565格式的位图绘制到内存设备上 */
hMem1 = GUI_MEMDEV_CreateFixed(0, 0, 64, 64, GUI_MEMDEV_HASTRANS,
GUI_MEMDEV_APILIST_16,
GUI_COLOR_CONV_565);
GUI_MEMDEV_Select(hMem1);
GUI_DrawBitmap(&bmpic, 0, 0);
GUI_MEMDEV_Select(0);
/* 显⽰RGB565格式的位图 */
GUI_DispStringAt("This is RGB565 bitmap & GUI_MEMDEV_CreateFixed", 100, 150);
GUI_MEMDEV_WriteAt(hMem1, 20, 120);
//////////////////////////////⽅式三/////////////////////////////////
/* 创建内存设备,并将ARGB8888格式的位图绘制到内存设备上 */
hMem2 = GUI_MEMDEV_CreateEx(0, 0, 64, 64, GUI_MEMDEV_HASTRANS);
GUI_MEMDEV_Select(hMem2);
GUI_DrawBitmap(&bmpic1, 0, 0);
GUI_MEMDEV_Select(0);
/* 显⽰ARGB8888格式的位图 */
GUI_DispStringAt("This is ARGB8888 bitmap & GUI_MEMDEV_CreateEx", 100, 250);
GUI_MEMDEV_WriteAt(hMem2, 20, 220);
////////////////////////////////⽅式四///////////////////////////////
/* 创建内存设备,并将ARGB8888格式的位图绘制到内存设备上 */
hMem3 = GUI_MEMDEV_CreateFixed(0, 0, 64, 64, GUI_MEMDEV_HASTRANS,
GUI_MEMDEV_APILIST_32,
GUI_COLOR_CONV_8888);
GUI_MEMDEV_Select(hMem3);
GUI_DrawBitmap(&bmpic1, 0, 0);
GUI_MEMDEV_Select(0);
/* 显⽰ARGB8888格式的位图 */
GUI_DispStringAt("This is ARGB8888 bitmap & GUI_MEMDEV_CreateFixed", 100, 350);
GUI_MEMDEV_WriteAt(hMem3, 20, 320);
while (1)
{
GUI_Delay(10);
}
}
/*************************** End of file ****************************/
实际显⽰效果如下,分辨率600*400:
20.3.2 存储设备的选择和显⽰函数
在20.3.1⼩节的例⼦中,我们⽤到了存储设备选择函数和显⽰函数:
void GUI_MEASDEV_Select (GUI_MEASDEV_Handle hMem)
此函数⽤于选择要使⽤的存储设备,打算在哪个存储设备上⾯进⾏绘制操作,参数就添加哪个存储设备的句柄,。

如果参数填为0,将激活LCD,即绘制操作是在LCD上⾯进⾏的,⽽不是在存储设备上⾯进⾏的。

void GUI_MEMDEV_WriteAt(GUI_MEMDEV_Handle hMem, int x, int y);
此函数⽤于将存储设备的内容绘制到LCD显⽰屏上。

20.3.3 存储设备的其它函数
存储设备的还有很多其它的函数,我们这⾥暂时不做讲解了,20.3.1和20.3.2⼩节中的函数是实际项⽬中⽤到最多的,其余的函数在emWin的官⽅⼿册中⼤部分都有举例说明,可以在模拟器上⾯运⾏下,看看实际的效果。

另外在我们论坛的这个帖⼦中也有其它部分函数说明,有兴趣可以看下:。

20.4 实验例程说明(RTOS)
配套例⼦:
V7-520_emWin6.x实验_存储设备之基础函数(RTOS)
实验⽬的:
1. 学习emWin的存储设备之基本函数。

2. emWin功能的实现在MainTask.c⽂件⾥⾯。

实验内容:
1、K1按键按下,串⼝或者RTT打印任务执⾏情况(串⼝波特率115200,数据位8,奇偶校验位⽆,停⽌位1)。

2、(1) 凡是⽤到printf函数的全部通过函数App_Printf实现。

(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

3、默认上电是通过串⼝打印信息,如果使⽤RTT打印信息:
MDK AC5,MDK AC6或IAR通过使能bsp.h⽂件中的宏定义为1即可
#define Enable_RTTViewer 1
4、各个任务实现的功能如下:
App Task Start 任务:启动任务,这⾥⽤作BSP驱动包处理。

App Task MspPro任务:消息处理,这⾥⽤作LED闪烁。

App Task UserIF 任务:按键消息处理。

App Task COM 任务:暂未使⽤。

App Task GUI 任务:GUI任务。

µCOS-III任务调试信息(按K1按键,串⼝打印):
RTT 打印信息⽅式:
程序设计:
任务栈⼤⼩分配:
µCOS-III任务栈⼤⼩在app_cfg.h⽂件中配置:
#define APP_CFG_TASK_START_STK_SIZE 512u
#define APP_CFG_TASK_MsgPro_STK_SIZE 2048u
#define APP_CFG_TASK_COM_STK_SIZE 512u
#define APP_CFG_TASK_USER_IF_STK_SIZE 512u
#define APP_CFG_TASK_GUI_STK_SIZE 2048u
任务栈⼤⼩的单位是4字节,那么每个任务的栈⼤⼩如下:
App Task Start 任务:2048字节。

App Task MspPro任务:8192字节。

App Task UserIF 任务:2048字节。

App Task COM 任务:2048字节。

App Task GUI 任务:8192字节。

系统栈⼤⼩分配:
µCOS-III的系统栈⼤⼩在os_cfg_app.h⽂件中配置:
#define OS_CFG_ISR_STK_SIZE 512u
系统栈⼤⼩的单位是4字节,那么这⾥就是配置系统栈⼤⼩为2KB
emWin动态内存配置:
GUIConf.c⽂件中的配置如下:
#define EX_SRAM 1/*1 used extern sram, 0 used internal sram */
#if EX_SRAM
#define GUI_NUMBYTES (1024*1024*24)
#else
#define GUI_NUMBYTES (100*1024)
#endif
通过宏定义来配置使⽤内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:#define EX_SRAM 1 表⽰使⽤外部SDRAM作为emWin动态内存,⼤⼩24MB。

#define EX_SRAM 0 表⽰使⽤内部SRAM作为emWin动态内存,⼤⼩100KB。

默认情况下,本教程配套的所有emWin例⼦都是⽤外部SDRAM作为emWin动态内存。

emWin界⾯显⽰效果:
800*480分辨率界⾯效果。

20.5 实验例程说明(裸机)
配套例⼦:
V7-520_emWin6.x实验_存储设备之基础函数(RTOS)
实验⽬的:
1. 学习emWin的存储设备之基本函数。

2. emWin功能的实现在MainTask.c⽂件⾥⾯。

emWin界⾯显⽰效果:
800*480分辨率界⾯效果。

emWin动态内存配置:
GUIConf.c⽂件中的配置如下:
#define EX_SRAM 1/*1 used extern sram, 0 used internal sram */
#if EX_SRAM
#define GUI_NUMBYTES (1024*1024*24)
#else
#define GUI_NUMBYTES (100*1024)
#endif
通过宏定义来配置使⽤内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表⽰使⽤外部SDRAM作为emWin动态内存,⼤⼩24MB。

#define EX_SRAM 0 表⽰使⽤内部SRAM作为emWin动态内存,⼤⼩100KB。

默认情况下,本教程配套的所有emWin例⼦都是⽤外部SDRAM作为emWin动态内存。

20.6 总结
本章节主要为⼤家讲解了存储设备⾥⾯⼏个常⽤的函数,还有很多其它函数没有做讲解,有兴趣的话,这些没有讲到的函数可以练习下。

相关文档
最新文档