STM32 的图形加速器 DMA2D

您所在的位置:网站首页 控制器ZWK4809-CR STM32 的图形加速器 DMA2D

STM32 的图形加速器 DMA2D

2024-03-29 18:40| 来源: 网络整理| 查看: 265

STM32 的图形加速器 DMA2D 1. 背景

​ 在实际使用 LTDC 控制器控制液晶屏时,配置好的显存地址写入要显示的像素数据,LTDC 就会把这些数据从显存中搬运到液晶面板进行显示。实际上要显示的数据量非常的大,我们常常以纯软件的方式填充显存(指定那个位置要显示什么颜色),这样非常影响绘图速度,因此我们希望能用 DMA 来操作,针对这个需求,STM32 专门定制了 DMA2D 外设,它可以用于快速绘制矩形、执行、分层数据混合、数据复制以及进行图像数据格式转换,可以把它理解为图形专用的 DMA。

2. DMA2D 工作模式 寄存器到存储器(此模式通常同于清屏,将寄存器中保存的颜色值搬运到显存中的某个位置,或者整个显存)存储器到存储器(将内存中的数据搬到显存中)存储器到存储区并执行像素格式转换存储器到存储器并执行像素格式转换和混合 3. DMA2D 控制

​ 通过对 DMA2D 控制器寄存(DMA2D_CR)配置 DMA2D 控制器,用户可以执行下列操作:

选择工作模式使能/禁止 DMA2D 中断启动/挂起/中止进行中的数据传输 4. DMA2D 前景层 FIFO 和背景层 FIFO

​ DMA2D 前景层(FG) FIFO 和 背景(BG)FIFO 获取要处理的输入数据。这些 FIFO 根据相应像素格式转换器(PFC)中定义的颜色格式获取像素。通过如下一组寄存器对他们进行编程:

DMA2D 前景层存储地址寄存器(DMA2D_FGMAR 此寄存器存的是前景层数据地址)

DMA2D 前景层偏移寄存器(DMA2D_FGOR )

DMA2D 背景层存储地址寄存器(DMA2D_BGMAR )

DMA2D 背景层偏移寄存器

DMA2D 在寄存器到存储器模式下工作时,不激活任何 FIFO。

DMA2D 在存储器到存储器模式下工作时(没有像素格式转换和混合操作时),仅激活FG FIFO,并将其作用为缓冲区。

DMA2D 在存储器到存储器模式下工作时并支持像素格式转换时(无混合操作),不会激活 BG FIFO。

5. DMA2D 工作原理 5.1 register to memory

​ 说了那么多理论,我们看一下实际上 DMA2D 的优势到底在那里。当我们想要在 LCD 显示屏的中间画上几个矩形时,或者清屏时,都是使用的纯软件循环填充framnbuffer 的空间比如:

for(y = y0; y /* DMA2D配置 */ DMA2D->CR = 0x00030000UL; // 配置为寄存器到储存器模式 DMA2D->OCOLR = color; // 设置填充使用的颜色 DMA2D->OMAR = (uint32_t)fb; // 填充区域的起始内存地址 DMA2D->OOR = lineoffect; // 行偏移,即跳过的像素(像素为单位) DMA2D->OPFCCR = pixelformat; // 设置颜色格式 DMA2D->NLR = (uint32_t)(width CR & DMA2D_CR_START) {} } /* 填充颜色,此处我的 fb 是uint8类型的,由于采用 RGB565格式存储像素点,因此,一个像素占用两个字节,因此下面地址偏移乘了2 * 也可强转位 uint16 然后就不用乘 2 了 * w :待填充区域的宽度 * h :待填充区域的高度 */ void fill_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color){ void* distfb = &framebuffer[2*(y*800 + x)]; dma2d_fill(distfb, w, h, 800 - w, LTDC_PIXEL_FORMAT_RGB565, color); } int dma2d_file_rect_test(void) { fill_rect(0, 0, 800, 480, 0x0000);//清屏 fill_rect(300, 80, 20, 280, 0x001f); fill_rect(340, 100, 20, 200, 0x001f); fill_rect(380, 40, 20, 260, 0x001f); fill_rect(420, 60, 20, 240, 0x001f); fill_rect(260, 300, 240, 1, 0x0000); return 0; } MSH_CMD_EXPORT(dma2d_file_rect_test,dma2d_file_rect_test);//导出到 shell 命令

运行结果如下:

在这里插入图片描述

5.2 memory to memory

DMA2D 还可以工作在 memory to memory 模式下,此模式可用于将图片数据搬运到 fb 中指定的地址中去,因此我们做如下配置

DMA2D->CR = (0 OMAR = (uint32_t)dstaddr; // 目标地址 DMA2D->FGOR = offlinesrc; // 源数据偏移(像素) DMA2D->OOR = offlinedst; // 目标地址偏移(像素) DMA2D->FGPFCCR = pixelformat; //颜色格式 DMA2D->NLR = (uint32_t)(width } } /* * sky_animation_mask1 为原图片地址 * _lcd.front_buf 为显存 * 原图片地址不偏移 * 目的地址偏移 */ int dma2d_m2m(void) { dma2d_memcopy(LTDC_PIXEL_FORMAT_RGB565,sky_animation_mask1,_lcd.front_buf,LOGO1_W,LOGO1_H,0,800-LOGO1_W); } MSH_CMD_EXPORT(dma2d_m2m,dma2d_m2m);

执行效果如下:

请添加图片描述

如果想移动图片的位置,可以操作 fb 地址,这里给的目的地址就是 fb 的首地址,也就是左上角。

5.3 memory to mrmory 图片混合

​ 通过将两张图片混合,并且设置图片透明度,可以达到图片渐变的效果,因此需要将 DMA2D 设置在待混合的模式下

DMA2D->CR = (0x2 BGOR = offsetlineBg;// 背景偏移 DMA2D->FGMAR = (uint32_t)ggaddr;// 前景 src addr DMA2D->FGOR = offsetlinefg;// 前景偏移 DMA2D->OMAR = dstaddr;// 目的地址 DMA2D->OOR = offlinedist; // 输出偏移,行便宜将添加到行末尾,用于确认下一行的起始地址 DMA2D->NLR = (uint32_t)(width } } int dma2d_test(void) { dma2d_mixcolorsbulk(sky_animation_mask,sky_animation_mask1,&_lcd.front_buf[_lcd.lcd_info.width*200+400],0,0,800-LOGO_W,LOGO1_W,LOGO1_H,LTDC_PIXEL_FORMAT_RGB565,128); } MSH_CMD_EXPORT(dma2d_test,dma2d_test);

效果如下: 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3