教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第40章 emWin6.x支持的颜色格式
本章节为大家讲解emWin支持的颜色格式,了解了这些颜色就可以很方便的根据液晶屏支持的颜色选择emWin相应的颜色配置。简单的说就是,如果大家使用的屏只支持黑白两色,那么就得使用emWin配套的颜色格式GUICC_1。
STM32H7支持8种颜色格式,用户可以根据项目需要选择合适的颜色格式,同时emWin也要选择相应的颜色格式。
40.1 初学者重要提示
40.2 颜色格式说明
40.3 固定调色板及其说明
40.4 颜色格式选择RGB565实验例程说明(RTOS)
40.5 颜色格式选择RGB565实验例程说明(裸机)
40.6 颜色格式选择RGB888实验例程说明(RTOS)
40.7 颜色格式选择RGB888实验例程说明(裸机)
40.8 总结
40.1 初学者重要提示
1、 对于初学者来说,主要掌握RGB888和RGB565两种颜色格式的使用即可,因为这两种格式在实际项目中用到的最多。
2、 对于32位色,24位色,16位色和8位色的显示效果及其刷屏速度可以看这个帖子(帖子是基于STM32F429做的速度测试,同样适用于STM32H7):http://www.armbbs.cn/forum.php?mod=viewthread&tid=16963 。
通过这个帖子对不同颜色格式的显示效果有个感性认识。
3、 颜色格式相关知识在emWin手册中都有讲解,下图是中文版讲解位置
下图是英文版手册讲解位置:
40.2 颜色格式说明
emWin支持黑色/白色、灰度(具有不同强度的单色)和彩色显示器。几乎市面上大家能够见到的颜色格式,emWin都支持。明白了这点后,下面说两个比较重要的概念,逻辑颜色和物理颜色。
40.2.1 逻辑颜色
逻辑颜色是应用程序处理的颜色,emWin5.30版本之前仅支持ABGR(这里没有写错,就是BGR),也就是说我们操作emWin的时候,emWin是按照BGR格式处理写入的颜色数值,这个也就解释了初学者经常会有的疑问,为什么写入的颜色数值0x0000FF显示出来的是红色,本应该是绘制出蓝色啊,根本原因就在这个ABGR格式上了(大多数情况,我们都是直接使用emWin定义好的颜色,比如显示红色就调用GUI_RED,导致很多初学者没有注意到这个问题)。32位的ABGR颜色格式表示的含义如下:
从上面的表格可以看出alpha透明通道用8位来表示,三原色BGR也都是用8位数据来表示。从emWin5.30版本之后为什么又推出了ARGB格式呢?主要是因为越来越多显示屏控制器基本都采用这种颜色格式了,比如STM32H7就是这种颜色格式。32位的ARGB颜色格式表示的含义如下:
那么问题来了,STM32H7的LCD控制器是ARGB格式的,跟emWin默认的ABGR格式不兼容,岂不是每次显示前都要做颜色的转换,实际上的确是这样的,在一定程度上比较影响LCD性能,但是由于三缓冲,内存设备和H7的DMA2D颜色格式硬件转换在一定程度上降低了影响。
另外根据官方手册的说明,在GUIConf.h文件中设置如下宏定义就可以使用ARGB格式了(注意,由于emWin是库,这个宏定义仅用于修改GUI.h文件的颜色值):
#define GUI_USE_ARGB (1)
下面是GUI.h文件中几种常用的ARGB和ABRG格式颜色定义:
/********************************************************************* * * Standard colors */ #if (GUI_USE_ARGB) 这里是ARGB格式颜色 #define GUI_BLUE 0xFF0000FF #define GUI_GREEN 0xFF00FF00 #define GUI_RED 0xFFFF0000 #define GUI_CYAN 0xFF00FFFF #define GUI_MAGENTA 0xFFFF00FF #define GUI_YELLOW 0xFFFFFF00 #define GUI_LIGHTBLUE 0xFF8080FF #define GUI_LIGHTGREEN 0xFF80FF80 #define GUI_LIGHTRED 0xFFFF8080 #define GUI_LIGHTCYAN 0xFF80FFFF #define GUI_LIGHTMAGENTA 0xFFFF80FF #define GUI_LIGHTYELLOW 0xFFFFFF80 #define GUI_DARKBLUE 0xFF000080 #define GUI_DARKGREEN 0xFF008000 #define GUI_DARKRED 0xFF800000 #define GUI_DARKCYAN 0xFF008080 #define GUI_DARKMAGENTA 0xFF800080 #define GUI_DARKYELLOW 0xFF808000 #define GUI_WHITE 0xFFFFFFFF #define GUI_LIGHTGRAY 0xFFD3D3D3 #define GUI_GRAY 0xFF808080 #define GUI_DARKGRAY 0xFF404040 #define GUI_BLACK 0xFF000000 #define GUI_BROWN 0xFFA52A2A #define GUI_ORANGE 0xFFFFA500 #define GUI_TRANSPARENT 0x00000000 #define GUI_GRAY_3F 0xFF3F3F3F #define GUI_GRAY_50 0xFF505050 #define GUI_GRAY_55 0xFF555555 #define GUI_GRAY_60 0xFF606060 #define GUI_GRAY_7C 0xFF7C7C7C #define GUI_GRAY_9A 0xFF9A9A9A #define GUI_GRAY_AA 0xFFAAAAAA #define GUI_GRAY_C0 0xFFC0C0C0 #define GUI_GRAY_C8 0xFFC8C8C8 #define GUI_GRAY_D0 0xFFD0D0D0 #define GUI_GRAY_E7 0xFFE7E7E7 #define GUI_BLUE_98 0xFF000098 #else 这里是ABGR格式颜色 #define GUI_BLUE 0x00FF0000 #define GUI_GREEN 0x0000FF00 #define GUI_RED 0x000000FF #define GUI_CYAN 0x00FFFF00 #define GUI_MAGENTA 0x00FF00FF #define GUI_YELLOW 0x0000FFFF #define GUI_LIGHTBLUE 0x00FF8080 #define GUI_LIGHTGREEN 0x0080FF80 #define GUI_LIGHTRED 0x008080FF #define GUI_LIGHTCYAN 0x00FFFF80 #define GUI_LIGHTMAGENTA 0x00FF80FF #define GUI_LIGHTYELLOW 0x0080FFFF #define GUI_DARKBLUE 0x00800000 #define GUI_DARKGREEN 0x00008000 #define GUI_DARKRED 0x00000080 #define GUI_DARKCYAN 0x00808000 #define GUI_DARKMAGENTA 0x00800080 #define GUI_DARKYELLOW 0x00008080 #define GUI_WHITE 0x00FFFFFF #define GUI_LIGHTGRAY 0x00D3D3D3 #define GUI_GRAY 0x00808080 #define GUI_DARKGRAY 0x00404040 #define GUI_BLACK 0x00000000 #define GUI_BROWN 0x002A2AA5 #define GUI_ORANGE 0x0000A5FF #define GUI_TRANSPARENT 0xFF000000 #define GUI_GRAY_3F 0x003F3F3F #define GUI_GRAY_50 0x00505050 #define GUI_GRAY_55 0x00555555 #define GUI_GRAY_60 0x00606060 #define GUI_GRAY_7C 0x007C7C7C #define GUI_GRAY_9A 0x009A9A9A #define GUI_GRAY_AA 0x00AAAAAA #define GUI_GRAY_C0 0x00C0C0C0 #define GUI_GRAY_C8 0x00C8C8C8 #define GUI_GRAY_D0 0x00D0D0D0 #define GUI_GRAY_E7 0x00E7E7E7 #define GUI_BLUE_98 0x00980000 #endif
对于ABGR格式,官方专门制作了一个常用颜色的实际显示效果,这里将其粘贴出来:
40.2.2 物理颜色
物理颜色是可用显示器实际显示的颜色,按照与逻辑颜色相同的24位RGB或者BGR格式进行定义。在运行时,逻辑颜色映射到物理颜色。对于仅有几种颜色的显示器,如单色显示器或8/16色LCD,emWin使用优化版的“最小二乘偏差搜索”对其进行转换,将显示的颜色(逻辑颜色)与LCD可实际显示的所有可用颜色(物理颜色)进行比较,最终使用最接近的颜色。
40.2.3 STM32H7支持的颜色格式
STM32H7支持8种颜色格式:
- ARGB8888
- RGB888
- RGB565
- ARGB1555
- ARGB4444
- L8( 8 位 Luminance 或 CLUT)
- AL44( 4 位 alpha + 4 位 luminance)
- AL88( 8 位 alpha + 8 位 luminance)
对于这8种颜色格式,本教程配套的例子已经都实现了,用户只需设置LCDConf_Lin_Template.C文件的宏配置:
/* 6. STM32F429/439支持的颜色模式,所有模式都支持,用户可任意配置。 特别注意如下两个问题: (1) 如果用户选择了ARGB8888或者RGB888模式,LCD闪烁比较厉害的话, 请降低LTDC的时钟大小,在文件bsp_tft_429.c的函数LCD_ConfigLTDC里面设置。 a. 一般800*480分辨率的显示屏,ARGB8888或者RGB888模式LTDC时钟选择10-20MHz即可。 b. 480*272分辨率的可以高些,取20MHz左右即可。 (2) 16位色或者8位色模式,LTDC的时钟频率一般可以比24位色或者32位色的高一倍。 */ #define _CM_ARGB8888 1 #define _CM_RGB888 2 #define _CM_RGB565 3 #define _CM_ARGB1555 4 #define _CM_ARGB4444 5 #define _CM_L8 6 #define _CM_AL44 7 #define _CM_AL88 8 /* 7. 配置图层1的颜色模式和分辨率大小 */ #define COLOR_MODE_0 _CM_RGB565 #define XSIZE_0 XSIZE_PHYS #define YSIZE_0 YSIZE_PHYS /* 8. 配置图层2的的颜色模式和分辨率大小 */ #define COLOR_MODE_1 _CM_RGB565 #define XSIZE_1 XSIZE_PHYS #define YSIZE_1 YSIZE_PHYS /* 9. 单图层情况下,根据用户选择的颜色模式可自动选择图层1的emWin的驱动和颜色模式 */ #if (COLOR_MODE_0 == _CM_ARGB8888) #define COLOR_CONVERSION_0 GUICC_M8888I #define DISPLAY_DRIVER_0 GUIDRV_LIN_32 #elif (COLOR_MODE_0 == _CM_RGB888) #define COLOR_CONVERSION_0 GUICC_M888 #define DISPLAY_DRIVER_0 GUIDRV_LIN_24 #elif (COLOR_MODE_0 == _CM_RGB565) #define COLOR_CONVERSION_0 GUICC_M565 #define DISPLAY_DRIVER_0 GUIDRV_LIN_16 #elif (COLOR_MODE_0 == _CM_ARGB1555) #define COLOR_CONVERSION_0 GUICC_M1555I #define DISPLAY_DRIVER_0 GUIDRV_LIN_16 #elif (COLOR_MODE_0 == _CM_ARGB4444) #define COLOR_CONVERSION_0 GUICC_M4444I #define DISPLAY_DRIVER_0 GUIDRV_LIN_16 #elif (COLOR_MODE_0 == _CM_L8) #define COLOR_CONVERSION_0 GUICC_8666 #define DISPLAY_DRIVER_0 GUIDRV_LIN_8 #elif (COLOR_MODE_0 == _CM_AL44) #define COLOR_CONVERSION_0 GUICC_1616I #define DISPLAY_DRIVER_0 GUIDRV_LIN_8 #elif (COLOR_MODE_0 == _CM_AL88) #define COLOR_CONVERSION_0 GUICC_88666I #define DISPLAY_DRIVER_0 GUIDRV_LIN_16 #else #error Illegal color mode 0! #endif /* 10. 双图层情况下,根据用户选择的颜色模式可自动选择图层2的emWin的驱动和颜色模式 */ #if (GUI_NUM_LAYERS > 1) #if (COLOR_MODE_1 == _CM_ARGB8888) #define COLOR_CONVERSION_1 GUICC_M8888I #define DISPLAY_DRIVER_1 GUIDRV_LIN_32 #elif (COLOR_MODE_1 == _CM_RGB888) #define COLOR_CONVERSION_1 GUICC_M888 #define DISPLAY_DRIVER_1 GUIDRV_LIN_24 #elif (COLOR_MODE_1 == _CM_RGB565) #define COLOR_CONVERSION_1 GUICC_M565 #define DISPLAY_DRIVER_1 GUIDRV_LIN_16 #elif (COLOR_MODE_1 == _CM_ARGB1555) #define COLOR_CONVERSION_1 GUICC_M1555I #define DISPLAY_DRIVER_1 GUIDRV_LIN_16 #elif (COLOR_MODE_1 == _CM_ARGB4444) #define COLOR_CONVERSION_1 GUICC_M4444I #define DISPLAY_DRIVER_1 GUIDRV_LIN_16 #elif (COLOR_MODE_1 == _CM_L8) #define COLOR_CONVERSION_1 GUICC_8666 #define DISPLAY_DRIVER_1 GUIDRV_LIN_8 #elif (COLOR_MODE_1 == _CM_AL44) #define COLOR_CONVERSION_1 GUICC_1616I #define DISPLAY_DRIVER_1 GUIDRV_LIN_8 #elif (COLOR_MODE_1 == _CM_AL88) #define COLOR_CONVERSION_1 GUICC_88666I #define DISPLAY_DRIVER_1 GUIDRV_LIN_16 #else #error Illegal color mode 1! #endif #else #undef XSIZE_0 #undef YSIZE_0 #define XSIZE_0 XSIZE_PHYS #define YSIZE_0 YSIZE_PHYS #endif
比如要实现图层0使用RGB565,只需设置: #define COLOR_MODE_0 _CM_RGB565
配置了这个后,在接下来的条件编译中会选择执行宏定义
- #define COLOR_CONVERSION_0 GUICC_M565
此宏定义表示:STM32H7要输出RGB565颜色格式,emWin要使用GUICC_M565颜色转换格式,即将emWin应用程序使用的ARGB8888或者ABGR8888颜色格式按照GUICC_M565转换后才可以发给STM32H7使用。GUICC_M565就是起到这么一个作用。
- #define DISPLAY_DRIVER_0 GUIDRV_LIN_16
这个是emWin按照颜色转换格式GUICC_M565实现的底层驱动。
如果用户选择了STM32H7支持的其它类型颜色格式,上面代码中的条件编译都会选择相应的颜色转换格式和驱动。
40.3 固定调色板及其说明
emWin支持的调色板模式很多,这里我们只介绍下面五种,其它的看官方手册。
如果大家看emWin手册固定调色板部分,会发现有很多类似GUICC_565和GUICC_M565的情况,多一个字母M。如果含字母M,表示RGB的颜色格式顺序,如果没有字母M表示BGR顺序。
40.3.1 GUICC_1
这种调色板适合用于OLED,12864等单色的显示屏。GUICC_1仅支持2种颜色,彩带显示效果下:
40.3.2 GUICC_8666
这种颜色格式主要通过颜色查找表来实现,把支持的256种颜色全部存贮到颜色查找表里面,需要那种颜色就从查找表里面获取。彩带显示效果如下:
40.3.3 GUICC_M565
这种格式比较常用,支持65536种颜色。这里565的意思是红色和蓝色分量为5位,绿色分量为6位,即RRRRRGGGGGGBBBBB。彩带显示效果如下:
40.3.4 GUICC_M888
这种颜色格式也比较常用。这里888的意思是红绿蓝三原色都是用8位来表示,即RRRRRRRRGGGGGGGGBBBBBBBB。彩带显示效果如下:
40.3.5 GUICC_M8888I
相比GUICC_M888多了一个alpha通道,其中低位3字节用于颜色分量,高位字节用于Alpha混合。红、绿、蓝和Alpha混合分量都是8位。颜色格式:AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB。
彩带显示效果如下:
40.4 颜色格式选择RGB565实验例程说明(RTOS)
配套例子:
V7-554_emWin6.x实验_颜色格式RGB565(RTOS)
实验目的:
- 本实验主要演示RGB565格式彩带显示效果。
- 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分辨率界面效果。
40.5 颜色格式选择RGB565实验例程说明(裸机)
配套例子:
V7-553_emWin6.x实验_颜色格式RGB565(裸机)
实验目的:
- 本实验主要演示RGB565格式彩带显示效果。
- 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动态内存。
40.6 颜色格式选择RGB565实验例程说明(RTOS)
配套例子:
V7-556_emWin6.x实验_颜色格式RGB888(RTOS)
实验目的:
- 本实验主要演示RGB888格式彩带显示效果。
- 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分辨率界面效果。
40.7 颜色格式选择RGB565实验例程说明(裸机)
配套例子:
V7-555_emWin6.x实验_颜色格式RGB888(裸机)
实验目的:
- 本实验主要演示RGB888格式彩带显示效果。
- 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动态内存。
40.8 总结
本章节就为大家讲解这么多,主要讲解了部分常用的颜色格式,不过实际项目中已经够用了。更多相关的知识还是要大家看官方手册的颜色章节。