【STM32H7】第6章 ThreadX GUIX上手之STM32H7 DMA2D加速

2023-12-17 01:38

本文主要是介绍【STM32H7】第6章 ThreadX GUIX上手之STM32H7 DMA2D加速,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最新教程下载:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429

第6章   ThreadX GUIX上手之STM32H7 DMA2D加速

本章节为大家讲解DMA2D应用中经常用到的刷色块,刷位图,Alpha混合和图片混合的实现。

目录

第6章   ThreadX GUIX上手之STM32H7 DMA2D加速

6.1   初学者重要提示

6.2   DMA2D驱动设计

6.2.1      DMA2D驱动设计思路

6.2.2      行偏移的含义(重要)

6.3   制作C文件格式的位图

6.3.1      什么是位图

6.3.2      图标下载

6.3.3        转换PNG图片为ARGB8888格式位图

6.3.4        转换PNG图片为RGB565格式位图

6.4   DMA2D常用操作(重要)

6.4.1      函数_DMA2D_Fill

6.4.2      函数_DMA2D_Copy

6.4.3      函数_DMA2D_MixColorsBulk

6.4.4      函数_DMA2D_AlphaBlendingBulk

6.4.5      函数_DMA2D_DrawAlphaBitmap

6.5   DMA2D驱动移植和使用

6.6   实验例程设计框架

6.7   实验例程说明

6.8   总结


 

6.1   初学者重要提示

  1.   本章是为ThreadX GUIX的LCD DMA2D加速做准备。
  2.   DMA2D里面有一个重要的概念就是行偏移,这知识点务必要认识到位,详见本章2.2小节。
  3.   DMA2D可以直接绘制ARGB8888,RGB565颜色格式位图,并且可以方便的做各种透明效果和图像混合显示。
  4.   LCD的加速全靠DMA2D,所以务必要熟练掌握其用法。
  5.   屏蔽MDK AC6使用中文GBK编码的警告方法,让大家可以继续使用GBK编码汉字:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98670 。

6.2   DMA2D驱动设计

6.2.1      DMA2D驱动设计思路

DMA2D的驱动设计比较省事:

  •   用户仅需调用函数__HAL_RCC_DMA2D_CLK_ENABLE使能DMA2D即可使用。
  •   默认DMA2D的API都是采用阻塞式,这种方式在使用RTOS的时候比较方便,用户可以将GUI任务的优先级设置的仅比空闲任务高即可,这样有高优先级任务要执行,可以及时切换到高优先级任务里,GUI任务等待DMA2D执行完成即可。从而可以充分利用DMA2D和CPU,使芯片性能得到最大发挥。
  •   最重要的一条,所有的DMA2D操作,直接采用寄存器方式,不再使用HAL库给的API,让性能得到最大发挥。

6.2.2      行偏移的含义(重要)

理解DMA2D传输的关键就是理解行偏移。前景层,背景层和输出区都有一个行偏移的寄存器,为了方便大家理解,这里画一个框图:

条件:

  •   前景层,背景层和输出区分辨率都是800*480分辨率,颜色格式均为RGB565。
  •   将前景层里面起始坐标(40,30),长480,高272的数据与背景层里面起始坐标(50,40),长480,高272的数据复制到输出区起始地址(60,50),长480,高272的区域。

引出问题:

那么问题来了,前景层和背景层的起始坐标在各自数据缓冲区的起始位置都比较好计算。比如前景层就是前景层首地址加上30*800*2 + 40*2,乘以2的原因是RGB565颜色格式的1个像素占用两个字节。

而难点就在如何保证前景层复制完480长度的数据后,如何切换到下一行。这个时候,行偏移就派上用场了,行偏移的意思是一行结束到下一行开始的距离,单位像素个数(也就是上面框图中两个红色箭头的总长度)。通过这个行偏移,我们就可以从前景层复制出来480*272的数据。

同理,背景层和输出区的行偏移也是这个意思。

6.3   制作C文件格式的位图

由于DMA2D刷新图片要用到,所以本小节为大家介绍下位图的制作。

6.3.1      什么是位图

位图(bitmap),又称为点阵图,是使用像素阵列来表示图像。位图中每个位置的像素都有自己的颜色值,这些颜色值是由RGB组合或者灰度值来表示。其中,RGB是指的Red红色,Green绿色和Blue蓝色,任何颜色都可以由这三种颜色来组成。电脑端绘图类的软件基本都有自定义颜色功能,可以很好的说明RGB三原色的作用:

根据位深度,可以将位图分为1位(单色),2位(4色,CGA),4位(16色,VGA),8位(256色),16位(增强色),24位(真彩色)和32位等。

关于位图,还有个概念就是alpha通道。所谓alpha通道就是指在原有的图片编码方法的基础上,增加像素的透明度信息。图形处理中,通常把RGB三种颜色信息称为红通道、绿通道和蓝通道,相应的把透明度称为Alpha通道。

6.3.2      图标下载

这里为大家推荐一个图标下载网址:http://www.easyicon.net/ ,此网站非常好用,需要什么图标直接检索关键字就可以了。这里以关键字cartoon进行检索,最终选择地址:

https://www.easyicon.net/581941-Lufy_cartoon_icon.html里面的图标,我们下载128*128点阵大小的PNG图片(下载的图片已经放在了本章教程配套例子的Doc文件夹里面):

下面我们分两步走,分别将其转换为ARGB8888格式位图和RGB565格式位图。

6.3.3        转换PNG图片为ARGB8888格式位图

  • 下载小软件BmpCvt:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93478 。
  •   第1步:打开BmpCvtST.exe ,直接将PNG格式的图片拖到此软件里面即可,或者点击File->Open进行加载也是可以的。

  •  第2步:点击File->Save as,弹出如下窗口

上面截图中共分了4步进行操作,其中第2步修改名字是因为原有的名字太长了,不方便程序代码的调用。

  •   第3步:第2步操作完毕后,弹出如下窗口:

第1个选项的True color with alpha颜色格式是ABGR,我们这里选择的第2个,这个是ARGB格式。当然,也可以选择ABGR格式,因为H7的DMA2D可以设置Alpha通过翻转和R通道与B通道交互位置,从而实现ABGR转为ARGB格式。

点击OK按钮后会在桌面出现一个新文件,即lufy.c,保存在桌面是因为第2步中选择的路径是桌面。

打开lufy.c文件,代码如下:

/*********************************************************************
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                           www.segger.com                           *
**********************************************************************
*                                                                    *
* C-file generated by                                                *
*                                                                    *
*        Bitmap Converter (ST) for emWin V5.32.                      *
*        Compiled Oct  8 2015, 11:58:22                              *
*                                                                    *
*        (c) 1998 - 2015 Segger Microcontroller GmbH & Co. KG        *
*                                                                    *
**********************************************************************
*                                                                    *
* Source file: pic                                                   *
* Dimensions:  64 * 64                                               *
* NumColors:   16bpp: 65536                                          *
*                                                                    *
**********************************************************************
*/#include <stdlib.h>#include "GUI.h"#ifndef GUI_CONST_STORAGE#define GUI_CONST_STORAGE const
#endifextern GUI_CONST_STORAGE GUI_BITMAP bmlufy;static GUI_CONST_STORAGE unsigned long _aclufy[] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0042454E, 0x00494C4E, 0x00393E50, 0x0046402A, 0x00968C62, 0x093E3C26, 0x2A787653, 0x597F8266, 0x606F6F4D, 0x5F7D7D54, 0x37747B50, 0x0B455035, 0x00745F3F, 0x00615856, 0x00655751, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* 后面的数据未列出 */};GUI_CONST_STORAGE GUI_BITMAP bmlufy = {128, // xSize128, // ySize512, // BytesPerLine32, // BitsPerPixel(unsigned char *)_aclufy,  // Pointer to picture dataNULL,  // Pointer to paletteGUI_DRAW_BMPM8888I
};/*************************** End of file ****************************/

对于生成的代码仅需用到数组static GUI_CONST_STORAGE unsigned long _aclufy[],这个数值要稍微修改下,将GUI_CONST_STORAGE修改为const即可用到工程里面。const表示数组存储到flash里面。

6.3.4        转换PNG图片为RGB565格式位图

转换方法与56.4.1小节相似,主要下面两个地方不同:

  •   第1点不同:使用电脑端的画图小软件将前面下载的图标转换为BMP格式(PNG图片中的透明通道会滤被掉),再用BmpCvt软件打开后的效果如下,已经没有Alpha通道。

  •   第2点不同,转换格式选择如下:

转换后生成的代码如下:

/*********************************************************************
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                           www.segger.com                           *
**********************************************************************
*                                                                    *
* C-file generated by                                                *
*                                                                    *
*        Bitmap Converter (ST) for emWin V5.44.                      *
*        Compiled Nov 10 2017, 08:52:20                              *
*                                                                    *
*        (c) 1998 - 2017 Segger Microcontroller GmbH & Co. KG        *
*                                                                    *
**********************************************************************
*                                                                    *
* Source file: Lufy_cartoon_128px_581941_easyiconnet                 *
* Dimensions:  128 * 128                                             *
* NumColors:   16bpp: 65536                                          *
*                                                                    *
**********************************************************************
*/#include <stdlib.h>#include "GUI.h"#ifndef GUI_CONST_STORAGE#define GUI_CONST_STORAGE const
#endifextern GUI_CONST_STORAGE GUI_BITMAP bmLufy_cartoon_128px_581941_easyiconnet;static GUI_CONST_STORAGE unsigned short _acLufy_cartoon_128px_581941_easyiconnet[] = {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, 0xF7BE, 0xE73C, 0xD699, 0xC657, 0xCE77, 0xDF1A, 0xF7BE, 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,/* 后面的数据未列出 */};GUI_CONST_STORAGE GUI_BITMAP bmlufy = {128, // xSize128, // ySize256, // BytesPerLine16, // BitsPerPixel(unsigned char *) aclufy,  // Pointer to picture dataNULL,  // Pointer to paletteGUI_DRAW_BMPM565
};/*************************** End of file ****************************/

这里生成的代码也是仅需用到数组static GUI_CONST_STORAGE unsigned long _aclufy[],并将GUI_CONST_STORAGE修改为const即可用到工程里面。

6.4   DMA2D常用操作(重要)

DMA2D的常用API要熟练掌握,后面的GUI的底层驱动加速,JPEG硬解,摄像头等部分都要用到。这里为大家介绍如下几个常用API:

  •   _DMA2D_Fill
  •   _DMA2D_Copy
  •   _DMA2D_MixColorsBulk
  •   _DMA2D_AlphaBlendingBulk
  •   _DMA2D_DrawAlphaBitmap

6.4.1      函数_DMA2D_Fill

函数原型:

1.    /*
2.    ******************************************************************************************************
3.    *    函 数 名: _DMA2D_Fill
4.    *    功能说明: DMA2D颜色填充功能
5.    *    形    参: pDst          颜色数据目的地址
6.    *             xSize         色块X轴大小,即每行像素数
7.    *             ySize         色块Y轴大小,即行数
8.    *             OffLine       前景层图像的行偏移
9.    *             ColorIndex    色块颜色值
10.    *             PixelFormat   目标区颜色格式
11.    *    返 回 值: 无
12.    ******************************************************************************************************
13.    */
14.    static void _DMA2D_Fill(void * pDst, 
15.                            uint32_t xSize, 
16.                            uint32_t ySize, 
17.                            uint32_t OffLine, 
18.                            uint32_t ColorIndex, 
19.                            uint32_t PixelFormat) 
20.    {
21.        
22.        /* DMA2D采用寄存器到存储器模式, 这种模式用不到前景层和背景层 */  
23.        DMA2D->CR      = 0x00030000UL | (1 << 9);
24.        DMA2D->OCOLR   = ColorIndex;
25.        DMA2D->OMAR    = (uint32_t)pDst;
26.        DMA2D->OOR     = OffLine;
27.        DMA2D->OPFCCR  = PixelFormat;
28.        DMA2D->NLR     = (uint32_t)(xSize << 16) | (uint16_t)ySize;
29.    
30.        /* 启动传输 */
31.        DMA2D->CR   |= DMA2D_CR_START;   
32.    
33.        /* 等待DMA2D传输完成 */
34.        while (DMA2D->CR & DMA2D_CR_START) {} 
35.    }

函数描述:

此函数主要用于LCD的颜色填充。

  •   第23行,设置DMA2D采用寄存器往存储器传输数据模式,即DMA2D将OCOLR寄存器设置颜色值填充到存储器里面。
  •   第24行,OCOLR寄存器用于设置输出颜色值,特别注意要跟第27行的输出颜色格式匹配。比如设置的是RGB565,那么设置的颜色值就要是16位色的。
  •   第25行,设置输出填充区的首地址。
  •   第26行,设置输出行偏移。
  •   第27行,设置输出颜色格式,如果是输出到LCD显存,那么此格式要与LCD颜色格式一致,否则显示不正常。
  •   第28行,高16位用于设置每行的像素数,低16位用于设置行数,合并起来决定总传输次数。
  •   第31-34行,启动传输,并等待传输完成。

注意事项:

  1. 使用此函数前务必要调用函数__HAL_RCC_DMA2D_CLK_ENABLE使能DMA2D时钟。

使用举例:

起始坐标(24, 20),输出颜色格式RGB565,绘制一个128x128的红色填充区:

1.        _DMA2D_Fill((void *)(SDRAM_LCD_BUF1 + g_LcdWidth*20*2 + 24*2),  /* 显示起始地址(24, 20) */  
2.                      128,                                               /* 色块长 */  
3.                    128,                                               /* 色块高 */
4.                    g_LcdWidth-128,                                    /* 色块行偏移 */
5.                    CL_RED,                                            /* 色块颜色 */
6.                    LTDC_PIXEL_FORMAT_RGB565);                         /* 色块颜色格式 */  
  •   第1行,根据设置的起始坐标,计算起始坐标在LCD显存中的具体位置。

SDRAM_LCD_BUF1表示LCD显存首地址。

g_LcdWidth*20*2计算的是行数占用的字节数。

24*2计算的是所在行的具体地址。

乘以2是因为RGB565颜色格式的1个像素占用两个字节。

  •   第4行,输出行偏移的意思就是一行结束到下一行开始的距离,单位像素个数。由于填充区的长度是128,那么行偏移就是LCD的长度减去128。

6.4.2      函数_DMA2D_Copy

函数原型:

1.    /*
2.    ******************************************************************************************************
3.    *    函 数 名: _DMA2D_Copy
4.    *    功能说明: 通过DMA2D从前景层复制指定区域的颜色数据到目标区域
5.    *    形    参: pSrc         颜色数据源地址
6.    *             pDst          颜色数据目的地址
7.    *             xSize         目的区域的X轴大小,即每行像素数
8.    *             ySize         目的区域的Y轴大小,即行数
9.    *             OffLineSrc    前景层图像的行偏移
10.    *             OffLineDst    输出的行偏移
11.    *             PixelFormat   目标区颜色格式
12.    *    返 回 值: 无
13.    ******************************************************************************************************
14.    */
15.    static void _DMA2D_Copy(void * pSrc, 
16.                            void * pDst, 
17.                            uint32_t xSize, 
18.                            uint32_t ySize, 
19.                            uint32_t OffLineSrc, 
20.                            uint32_t OffLineDst, 
21.                            uint32_t PixelFormat) 
22.    {
23.    
24.        /* DMA2D采用存储器到存储器模式, 这种模式是前景层作为DMA2D输入 */  
25.        DMA2D->CR      = 0x00000000UL | (1 << 9);
26.        DMA2D->FGMAR   = (uint32_t)pSrc;
27.        DMA2D->OMAR    = (uint32_t)pDst;
28.        DMA2D->FGOR    = OffLineSrc;
29.        DMA2D->OOR     = OffLineDst;
30.        
31.        /* 前景层和输出区域都采用的RGB565颜色格式 */
32.        DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB565;
33.        DMA2D->OPFCCR  = LTDC_PIXEL_FORMAT_RGB565;
34.        
35.        DMA2D->NLR     = (uint32_t)(xSize << 16) | (uint16_t)ySize;
36.    
37.        /* 启动传输 */
38.        DMA2D->CR   |= DMA2D_CR_START;   
39.    
40.        /* 等待DMA2D传输完成 */
41.        while (DMA2D->CR & DMA2D_CR_START) {} 
42.    }

函数描述:

此函数用于从前景层复制指定区域的颜色数据到目标区域。

  •   第25行,设置DMA2D采用存储器往存储器传输数据模式,输入存储器只能是前景层。即DMA2D将FGMAR寄存器所指向的存储数据传输到寄存器OMAR所指向的存储器。
  •   第26行,设置前景层数据首地址。
  •   第27行,设置输出存储器首地址。
  •   第28行,设置前景层行偏移。
  •   第29行,设置输出区行偏移。
  •   第32-33行,设置前景层和输出区域都采用RGB565颜色格式。另外注意,如果是输出到LCD显存,那么输出颜色格式要与LCD颜色格式一致,否则显示不正常。
  •   第35行,高16位用于设置每行的像素数,低16位用于设置行数,合并起来决定总传输次数。
  •   第38-41行,启动传输,并等待传输完成。

注意事项:

  1. 使用此函数前务必要调用函数__HAL_RCC_DMA2D_CLK_ENABLE使能DMA2D时钟。

使用举例:

将大小128*128,颜色格式为RGB565的位图绘制到LCD起始坐标为(328, 20)的区域,输出颜色格式也配置为RGB565。

1.        _DMA2D_Copy((uint32_t *)_acmickey,                                      /* 位图地址 */
2.                    (uint32_t *)(SDRAM_LCD_BUF1 + g_LcdWidth*20*2 + 328*2),     /* 显示起始地址(328, 20) */  
3.                    128,                                                      /* 位图长 */
4.                    128,                                                      /* 位图高 */
5.                    0,                                                        /* 位图行偏移 */
6.                    g_LcdWidth-128,                                           /* 目标区行偏移 */
7.                    LTDC_PIXEL_FORMAT_RGB565);                               /* 目标区颜色格式 */ 
  •   第1行是位图首地址。
  •   第2行,根据设置的起始坐标,计算起始坐标在LCD显存中的具体位置。

SDRAM_LCD_BUF1表示LCD显存首地址。

g_LcdWidth*20*2计算的是行数占用的字节数。

328*2计算的是所在行的具体地址。

乘以2是因为RGB565颜色格式的1个像素占用两个字节。

  •   第5行是位图的行偏移,行偏移的意思就是一行结束到下一行开始的距离,单位像素个数。由于整个位图都要绘制,所有行偏移就是0。
  •   第6行,输出行偏移的,由于输出区需要的长度是128,那么行偏移就是LCD的长度减去128。

6.4.3      函数_DMA2D_MixColorsBulk

函数原型:

1.    /*
2.    ******************************************************************************************************
3.    *    函 数 名: _DMA2D_MixColorsBulk
4.    *    功能说明: 前景层和目标区域的颜色混合
5.    *    形    参: pColorFG     前景层数据源地址
6.    *             OffLineSrcFG  前景层图像的行偏移
7.    *             pColorDst     目标区数据地址
8.    *             OffLineDst    目标区的行偏移
9.    *             xSize         目的区域的X轴大小,即每行像素数
10.    *             ySize         目的区域的Y轴大小,即行数
11.    *             Intens        设置前景层的透明度,255表示完全不透明,0表示完全透明
12.    *    返 回 值: 无
13.    ******************************************************************************************************
14.    */
15.    static void _DMA2D_MixColorsBulk(uint32_t * pColorFG,  
16.                                    uint32_t OffLineSrcFG,
17.                                     uint32_t * pColorDst, 
18.                                     uint32_t OffLineDst,
19.                                uint32_t xSize, 
20.                                     uint32_t ySize, 
21.                                     uint8_t Intens)
22.    {
23.    /* DMA2D采用存储器到存储器模式, 这种模式前景层和背景层作为DMA2D输入,且支持颜色格式转换和颜色混合 */  
24.        DMA2D->CR      = 0x00020000UL | (1 << 9);
25.        DMA2D->FGMAR   = (uint32_t)pColorFG;
26.        DMA2D->BGMAR   = (uint32_t)pColorDst;
27.        DMA2D->OMAR    = (uint32_t)pColorDst;
28.        DMA2D->FGOR    = OffLineSrcFG;
29.        DMA2D->BGOR    = OffLineDst;
30.        DMA2D->OOR     = OffLineDst;
31.    
32.        /* 前景层,背景层和输出区都是用的RGB565格式 */
33.        DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB565
34.                     | (1UL << 16)
35.                     | ((uint32_t)Intens << 24);
36.        DMA2D->BGPFCCR = LTDC_PIXEL_FORMAT_RGB565;
37.        DMA2D->OPFCCR  = LTDC_PIXEL_FORMAT_RGB565;
38.    
39.        DMA2D->NLR     = (uint32_t)(xSize << 16) | (uint16_t)ySize;
40.      
41.        /* 启动传输 */
42.        DMA2D->CR   |= DMA2D_CR_START;   
43.    
44.        /* 等待DMA2D传输完成 */
45.        while (DMA2D->CR & DMA2D_CR_START) {} 
46.    }

函数描述:

此函数用于前景层和目标区域的颜色混合,并将混合后的图像输出到目标区域。

  •   第24行,DMA2D采用存储器到存储器模式, 这种模式把前景层和背景层作为DMA2D输入,且支持颜色格式转换和颜色混合。
  •   第25行,设置前景层数据首地址。
  •   第26行,设置背景层数据首地址,这里是把输出区中的数据作为背景层。
  •   第27行,设置输出存储器首地址。
  •   第28行,设置前景层行偏移。
  •   第29行,设置背景层行偏移。
  •   第29行,设置输出区行偏移。
  •   第33-37行,前景层,背景层和输出区都采用RGB565格式,并且为前景层配置一个Alpha值。另外注意,如果是输出到LCD显存,那么输出颜色格式要与LCD颜色格式一致,否则显示不正常。
  •   第39行,高16位用于设置每行的像素数,低16位用于设置行数,合并起来决定总传输次数。
  •   第42-45行,启动传输,并等待传输完成。

注意事项:

  1. 使用此函数前务必要调用函数__HAL_RCC_DMA2D_CLK_ENABLE使能DMA2D时钟。

使用举例:

将大小128*128,颜色格式为RGB565的位图绘制到LCD起始坐标为(176, 168)的区域,输出颜色格式也配置为RGB565,透明度设置为200(255表示完全不透明,0表示完全透明)。

1.    _DMA2D_MixColorsBulk((uint32_t *)_achuoying,                               /* 位图地址 */
2.                      0,                                                     /* 位图行偏移 */                     
3.                     (uint32_t *)(SDRAM_LCD_BUF1 + g_LcdWidth*168*2 + 176*2), /* 显示起始地址(176, 168) */
4.                      g_LcdWidth-128,                                        /* 目标区行偏移 */                                    
5.                      128,                                                   /* 目标区长 */
6.                      128,                                                   /* 目标区高 */          
7.                      200);                                                  /* 位图显示透明度200 */
  •   第1行是位图首地址。
  •   第2行是位图的行偏移,行偏移的意思就是一行结束到下一行开始的距离,单位像素个数。由于整个位图都要绘制,所有行偏移就是0。
  •   第3行,根据设置的起始坐标,计算起始坐标在LCD显存中的具体位置。

SDRAM_LCD_BUF1表示LCD显存首地址。

g_LcdWidth*168*2计算的是行数占用的字节数。

176*2计算的是所在行的具体地址。

乘以2是因为RGB565颜色格式的1个像素占用两个字节。

  •   第4行,输出行偏移的,由于输出区需要的长度是128,那么行偏移就是LCD的长度减去128。

6.4.4      函数_DMA2D_AlphaBlendingBulk

函数原型:

1.    /*
2.    ******************************************************************************************************
3.    *    函 数 名: _DMA2D_AlphaBlendingBulk
4.    *    功能说明: 前景层和背景层的颜色混合
5.    *    形    参: pColorFG      前景层源数据地址
6.    *             OffLineSrcFG  前景层源数据行偏移
7.    *             pColorBG      背景层源数据地址
8.    *             OffLineSrcBG  背景层源数据行偏移
9.    *             pColorDst     目标区地址
10.    *             OffLineDst    目标区行偏移
11.    *             xSize         目标区域的X轴大小,即每行像素数
12.    *             ySize         目标区域的Y轴大小,即行数
13.    *    返 回 值: 无
14.    ******************************************************************************************************
15.    */
16.    static void _DMA2D_AlphaBlendingBulk(uint32_t * pColorFG,  
17.                                         uint32_t OffLineSrcFG,
18.                                         uint32_t * pColorBG,  
19.                                         uint32_t OffLineSrcBG,
20.                                         uint32_t * pColorDst, 
21.                                         uint32_t OffLineDst,
22.                                    uint32_t xSize, 
23.                                         uint32_t ySize) 
24.    {  
25.    /* DMA2D采用存储器到存储器模式, 这种模式前景层和背景层作为DMA2D输入,且支持颜色格式转换和颜色混合 */  
26.        DMA2D->CR      = 0x00020000UL | (1 << 9);
27.        DMA2D->FGMAR   = (uint32_t)pColorFG;
28.        DMA2D->BGMAR   = (uint32_t)pColorBG;
29.        DMA2D->OMAR    = (uint32_t)pColorDst;
30.        DMA2D->FGOR    = OffLineSrcFG;
31.        DMA2D->BGOR    = OffLineSrcBG;
32.        DMA2D->OOR     = OffLineDst;
33.    
34.        /* 前景层,背景层采用ARGB8888格式,输出区采用RGB565格式 */
35.        DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888;
36.        DMA2D->BGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888;
37.        DMA2D->OPFCCR  = LTDC_PIXEL_FORMAT_RGB565;
38.        DMA2D->NLR     = (uint32_t)(xSize << 16) | (uint16_t)ySize;
39.    
40.        /* 启动传输 */
41.        DMA2D->CR   |= DMA2D_CR_START;   
42.    
43.        /* 等待DMA2D传输完成 */
44.        while (DMA2D->CR & DMA2D_CR_START) {} 
45.    }

函数描述:

此函数用于前景层和背景层的颜色混合,并将混合后的图像输出到目标区域。

  •   第26行,DMA2D采用存储器到存储器模式, 这种模式把前景层和背景层作为DMA2D输入,且支持颜色格式转换和颜色混合。
  •   第27行,设置前景层数据首地址。
  •   第28行,设置背景层数据首地址。
  •   第29行,设置输出存储器首地址。
  •   第30行,设置前景层行偏移。
  •   第31行,设置背景层行偏移。
  •   第32行,设置输出区行偏移。
  •   第35-37行,前景层,背景层采用ARGB8888格式,输出区采用RGB565格式。另外注意,如果是输出到LCD显存,那么输出颜色格式要与LCD颜色格式一致,否则显示不正常。
  •   第38行,高16位用于设置每行的像素数,低16位用于设置行数,合并起来决定总传输次数。
  •   第41-44行,启动传输,并等待传输完成。

注意事项:

  1. 使用此函数前务必要调用函数__HAL_RCC_DMA2D_CLK_ENABLE使能DMA2D时钟。

使用举例:

将两个大小128*128,颜色格式为ARGB8888的位图混合后绘制到LCD起始坐标为(24, 168)的区域,输出颜色格式配置为RGB565。

1.    _DMA2D_AlphaBlendingBulk((uint32_t *)_aclufei,                     /* 前景层位图地址 */
2.                    0,                                              /* 前景层行偏移  */  
3.                    (uint32_t *)_acsuolong,                         /* 背景层位图地址  */  
4.                    0,                                              /* 背景层行偏移  */ 
5.                    (uint32_t *)(SDRAM_LCD_BUF1 +  g_LcdWidth*168*2 + 24*2), /* 显示起始地址(24, 168) */  
6.                    g_LcdWidth-128,                                 /* 目标区行偏移 */
7.                    128,                                            /* 目标区长 */
8.                    128);                                           /* 目标区高 */
  •   第1行是前景层位图首地址。
  •   第2行是位图的行偏移,行偏移的意思就是一行结束到下一行开始的距离,单位像素个数。由于整个位图都要绘制,所有行偏移就是0。
  •   第3行是背景层位图首地址。
  •   第4行是背景层行偏移。
  •   第5行,根据设置的起始坐标,计算起始坐标在LCD显存中的具体位置。

SDRAM_LCD_BUF1表示LCD显存首地址。

g_LcdWidth*168*2计算的是行数占用的字节数。

24*2计算的是所在行的具体地址。

乘以2是因为RGB565颜色格式的1个像素占用两个字节。

  •   第6行,输出行偏移的,由于输出区需要的长度是128,那么行偏移就是LCD的长度减去128。

6.4.5      函数_DMA2D_DrawAlphaBitmap

函数原型:

1.    /*
2.    ******************************************************************************************************
3.    *    函 数 名: _DMA2D_DrawAlphaBitmap
4.    *    功能说明: ARGB8888格式位图显示
5.    *    形    参: pDst        目标区地址
6.    *             pSrc        源数据地址,即位图首地址
7.    *             xSize       目标区域的X轴大小,即每行像素数
8.    *             ySize       目标区域的Y轴大小,即行数
9.    *             OffLineSrc  源数据行偏移
10.    *             OffLineDst  目标区行偏移
11.    *             PixelFormat 目标区颜色格式
12.    *    返 回 值: 无
13.    ******************************************************************************************************
14.    */
15.    static void _DMA2D_DrawAlphaBitmap(void  * pDst, 
16.                                       void  * pSrc, 
17.                                   uint32_t xSize, 
18.                                   uint32_t ySize, 
19.                                   uint32_t OffLineSrc, 
20.                                   uint32_t OffLineDst, 
21.                                    uint32_t PixelFormat) 
22.    {
23.    /* DMA2D采用存储器到存储器模式, 这种模式前景层和背景层作为DMA2D输入,且支持颜色格式转换和颜色混合 */  
24.        DMA2D->CR      = 0x00020000UL | (1 << 9);
25.        DMA2D->FGMAR   = (uint32_t)pSrc;
26.        DMA2D->BGMAR   = (uint32_t)pDst;
27.        DMA2D->OMAR    = (uint32_t)pDst;
28.        DMA2D->FGOR    = OffLineSrc;
29.        DMA2D->BGOR    = OffLineDst;
30.        DMA2D->OOR     = OffLineDst;
31.        
32.        /* 前景层颜色格式是LTDC_PIXEL_FORMAT_ARGB8888,即位图的颜色格式,背景层和输出区颜色格式可配置 */
33.        DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888;
34.        DMA2D->BGPFCCR = PixelFormat;
35.        DMA2D->OPFCCR  = PixelFormat;
36.        DMA2D->NLR     = (uint32_t)(xSize << 16) | (uint16_t)ySize;
37.    
38.        /* 启动传输 */
39.        DMA2D->CR   |= DMA2D_CR_START;   
40.    
41.        /* 等待DMA2D传输完成 */
42.        while (DMA2D->CR & DMA2D_CR_START) {} 
43.    }

函数描述:

此函数用于在指定位置显示ARGB8888格式位图。

  •   第24行,DMA2D采用存储器到存储器模式, 这种模式把前景层和背景层作为DMA2D输入,且支持颜色格式转换和颜色混合。
  •   第25行,设置前景层数据首地址。
  •   第26行,设置背景层数据首地址,这里是把输出区中的数据作为背景层。
  •   第27行,设置输出存储器首地址。
  •   第28行,设置前景层行偏移。
  •   第29行,设置背景层行偏移。
  •   第30行,设置输出区行偏移。
  •   第33-35行,前景层颜色格式是LTDC_PIXEL_FORMAT_ARGB8888,即位图的颜色格式。背景层和输出区颜色格式可配置。另外注意,如果是输出到LCD显存,那么输出颜色格式要与LCD颜色格式一致,否则显示不正常。
  •   第36行,高16位用于设置每行的像素数,低16位用于设置行数,合并起来决定总传输次数。
  •   第39-42行,启动传输,并等待传输完成。

注意事项:

  1. 使用此函数前务必要调用函数__HAL_RCC_DMA2D_CLK_ENABLE使能DMA2D时钟。

使用举例:

将大小128*128,颜色格式为ARGB8888的位图绘制到LCD起始坐标为(176, 20)的区域,输出颜色格式配置为RGB565。

1.    _DMA2D_DrawAlphaBitmap((void *)(SDRAM_LCD_BUF1 + g_LcdWidth*20*2 + 176*2), /* 显示起始地址(176, 20) */  
2.                           (void *)_aclufei,                                /* 位图地址 */
3.                           128,                                             /* 位图长 */
4.                           128,                                             /* 位图高 */
5.                           0,                                               /* 位图行偏移 */
6.                           g_LcdWidth-128,                                  /* 目标区行偏移 */
7.                           LTDC_PIXEL_FORMAT_RGB565);                       /* 目标区颜色格式 */
  •   第1行,根据设置的起始坐标,计算起始坐标在LCD显存中的具体位置。

SDRAM_LCD_BUF1表示LCD显存首地址。

g_LcdWidth*20*2计算的是行数占用的字节数。

176*2计算的是所在行的具体地址。

乘以2是因为RGB565颜色格式的1个像素占用两个字节

  •   第2行是位图首地址。
  •   第5行是位图的行偏移,行偏移的意思就是一行结束到下一行开始的距离,单位像素个数。由于整个位图都要绘制,所有行偏移就是0。
  •   第6行,输出行偏移的,由于输出区需要的长度是128,那么行偏移就是LCD的长度减去128。

6.5   DMA2D驱动移植和使用

DMA2D的驱动移植比较简单,用户仅需调用函数__HAL_RCC_DMA2D_CLK_ENABLE使能时钟,然后用到哪个函数直接复到工程里面调用即可。

6.6   实验例程设计框架

通过程序设计框架,让大家先对配套例程有一个全面的认识,然后再理解细节,本次实验例程的设计框架如下:

  第1阶段,上电启动阶段:

  •   这部分在V7板子BSP驱动教程的第14章进行了详细说明。

  第2阶段,进入main函数:

  •   第1步,硬件初始化,主要是MPU,Cache,HAL库,系统时钟,滴答定时器,LED ,LCD,和SDRAM。
  •   第2步,DMA2D应用程序设计部分,主要展示DMA2D刷色块,刷位图,Alpha混合和图片混合功能。

6.7   实验例程说明

配套例子:

V7-2003_DMA2D

实验目的:

  1. 学习DMA2D显示色块,位图,Alpha混合和图片混合等。

实验内容:

  1. 启动1个200ms的自动重装定时器,让LED2每200ms翻转一次。
  2. 第1个图:使用DMA2D刷色块。
  3. 第2个图:显示ARGB8888位图。
  4. 第3个图:显示RGB565位图。
  5. 第4个图:两个位图混合。
  6. 第5个图:Alpha透明度200的位图显示。
  7. 第6个图:Alpha透明度100的位图显示。

LCD界面显示效果如下:

6.8   总结

本章节涉及到的知识点非常重要,望初学者务必熟练掌握,因为后面章节用到LCD加速的地方都要用到DMA2D。

 

这篇关于【STM32H7】第6章 ThreadX GUIX上手之STM32H7 DMA2D加速的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/502654

相关文章

PyInstaller问题解决 onnxruntime-gpu 使用GPU和CUDA加速模型推理

前言 在模型推理时,需要使用GPU加速,相关的CUDA和CUDNN安装好后,通过onnxruntime-gpu实现。 直接运行python程序是正常使用GPU的,如果使用PyInstaller将.py文件打包为.exe,发现只能使用CPU推理了。 本文分析这个问题和提供解决方案,供大家参考。 问题分析——找不到ONNX Runtime GPU 动态库 首先直接运行python程序

【轻松上手postman】入门篇:如果根据接口文档写postman接口用例

在我们平时的测试工作中除了最基本的网页测试外,也会遇到没有页面但需要验证内部逻辑正确性的接口测试任务,在遇到没有网页的测试任务时,我们就要使用到接口测试工具来模拟对程序代码触发。 在接到接口测试任务时,一般都会拿到接口需求文档,没接触过接口测试的人看到接口文档正常反应一脸闷🤣不知如何下手怎么开始测试😓,下面我就来讲讲如何将接口文档上的一个个接口转换成postman用例 首先需要安装

机器人助力上下料搬运,加速仓库转运自动化

近年来,国内制造业领域掀起了一股智能化改造的浪潮,众多工厂纷纷采纳富唯智能提供的先进物流解决方案,这一举措显著优化了生产流程,实现了生产效率的飞跃式增长。得益于这些成功案例,某信息技术服务企业在工厂智能物流建设的进程中,也选择了与富唯智能合作。 为了应对日益增长的物料搬运需求,匹配成品输出节拍,该公司引入了富唯智能复合机器人AMR与搬运机器人AGV,实现了仓库成品搬运自动化,大幅减少人工

【JFinal】IDEA+maven上手JFinal之Hello World!

一、New Project 1、在 IDEA 环境下新建 Project 项目 2、选择创建 Maven 项目,并且不使用模板 3、输入 Maven 的 GroupId 和 ArtifactId 4、输入项目名称 二、将当前 Project 改为 POM 工程 将项目的 jfinal-web-demo 作为项目的 parent 工程,用于定义 maven 依赖包的版本信息、

ACM比赛中如何加速c++的输入输出?如何使cin速度与scanf速度相当?什么是最快的输入输出方法?

在竞赛中,遇到大数据时,往往读文件成了程序运行速度的瓶颈,需要更快的读取方式。相信几乎所有的C++学习者都在cin机器缓慢的速度上栽过跟头,于是从此以后发誓不用cin读数据。还有人说Pascal的read语句的速度是C/C++中scanf比不上的,C++选手只能干着急。难道C++真的低Pascal一等吗?答案是不言而喻的。一个进阶的方法是把数据一下子读进来,然后再转化字符串,这种方法传说中

P0.7全倒装COB超微小间距LED显示屏厂家已量产,加速高清显示的发展

随着P0.7全倒装COB超微小间距LED显示屏技术的成功量产,这一里程碑式的成就不仅标志着高清显示技术迈入了全新纪元,更预示着未来视觉体验将迎来前所未有的变革。各大应用场景,如指挥中心、会议中心、大型活动直播、高端影院乃至家庭娱乐,都将因这项技术而焕发新生。 市场上,消费者对于视觉质量的追求日益高涨,P0.7全倒装COB显示屏以其极致细腻的画质、超高的色彩还原度以及卓越的稳定性,迅速成为行业新宠

鸿蒙(API 12 Beta6版)图形加速【OpenGL ES平台内插模式】超帧功能开发

超帧内插模式是利用相邻两个真实渲染帧进行超帧计算生成中间的预测帧,即利用第N-1帧和第N帧真实渲染帧预测第N-0.5帧预测帧,如下图所示。由于中间预测帧的像素点通常能在前后两帧中找到对应位置,因此内插模式的预测帧效果较外插模式更优。由于第N帧真实渲染帧需要等待第N-0.5帧预测帧生成并送显后才能最终送显,因此会新增1~2帧的响应时延。 OpenGL ES平台 业务流程 基于OpenGL

低代码平台:加速企业制造业数字化转型的新引擎

近期,国家发布了中小企业数字化转型试点城市的政策,旨在通过先行先试,探索支持制造业特别是汽车制造行业数字化转型的有效模式。这一政策的出台,为汽车制造企业的数字化转型提供了强有力的政策支持和方向指引,标志着汽车制造业正迎来一场前所未有的变革。 面对复杂多变的市场需求和日益激烈的市场竞争,汽车制造企业纷纷寻求突破,而低代码平台凭借其快速、灵活、易用的特性,成为了助力这一转型的重要工具。 汽车制造行

word2vec 两个模型,两个加速方法 负采样加速Skip-gram模型 层序Softmax加速CBOW模型 item2vec 双塔模型 (DSSM双塔模型)

推荐领域(DSSM双塔模型): https://www.cnblogs.com/wilson0068/p/12881258.html   word2vec  word2vec笔记和实现 理解 Word2Vec 之 Skip-Gram 模型 上面这两个链接能让你彻底明白word2vec,不要搞什么公式,看完也是不知所云,也没说到本质. 目前用的比较多的都是Skip-gram模型 Go

免费SSL证书大全,加速普及网站实现HTTPS加密

免费SSL证书大全,加速普及网站实现HTTPS加密   SSL 证书用于加密 HTTP 协议,实现网站通过HTTPS加密协议访问。随着国内外各大网站实现全站 HTTPS 协议,以及搜索引擎对使用 HTTPS 协议网站的更加友好,加之互联网对数据和隐私安全的加强,网站添加 SSL 证书并实现 HTTPS 加密协议访问已经成为趋势和必然。 SSL证书大全​zzzjtd.com 而对于给网站添加