提问有关于STM32H7B0 的DMA2D问题

没有RGB接口的屏幕,例如中景园1.69寸ST7789这种屏幕可以用DMA2D吗?我的STM32H7B0是有DMA2D的

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇文章:【STM32H7教程】第56章 STM32H7的DMA2D应用之刷色块,位图和Alpha混合 也许有你想要的答案,你可以看看
  • 以下回答来自chatgpt:

    根据参考资料提供的代码,可以使用DMA2D功能在没有RGB接口的屏幕上进行操作。下面是具体的步骤和代码示例:

    1. 首先,需要确定你的屏幕使用的是什么颜色格式和取样方式(4:2:0、4:2:2或4:4:4)。这个信息通常可以在屏幕的数据手册或者厂商提供的文档中找到。

    2. 根据屏幕的颜色格式和取样方式,选择合适的参数来调用DMA2D_Copy_YCbCr_To_RGB_v函数。函数的参数说明如下:

    3. pSrc:数据源地址,即YCbCr数据的起始地址。

    4. pDst:数据目的地址,即RGB数据的起始地址。
    5. x:X轴首地址,即在屏幕上的起始位置。
    6. y:Y轴首地址,即在屏幕上的起始位置。
    7. xsize:目的区域的X轴大小,即每行像素数。
    8. ysize:目的区域的Y轴大小,即行数。
    9. PixelFormat:目标区颜色格式,可以是RGB565等。
    10. ChromaSampling:YCbCr Chroma采样方式,可以是DMA2D_CSS_420、DMA2D_CSS_422或DMA2D_NO_CSS。

    这些参数可以根据你的实际情况进行调整。

    1. 在函数内部,根据ChromaSampling的不同值确定cssMode和inputLineOffset的取值。根据目标格式的不同,需要调整destination的值。

    2. 设置DMA2D的相关寄存器。具体的操作如下:

    3. 设置DMA2D->CR寄存器的值为0x00010000UL | (1 << 9),表示启动DMA2D和使用后面的输出颜色格式。

    4. 设置DMA2D->OOR寄存器的值为屏幕的宽度减去目的区域的宽度,用于指定输出行之间的偏移量。
    5. 设置DMA2D->OPFCCR寄存器的值为目标颜色格式和alpha通道设置。
    6. 设置DMA2D->FGPFCCR寄存器的值为输入颜色格式和alpha通道设置,以及YCbCr的采样方式和alpha通道设置。
    7. 设置DMA2D->FGOR寄存器的值为输入行之间的偏移量。
    8. 设置DMA2D->NLR寄存器的值为目的区域的宽度和高度。
    9. 设置DMA2D->OMAR寄存器的值为输出数据的地址。
    10. 设置DMA2D->FGMAR寄存器的值为输入数据的地址。

    11. 启动DMA2D转换,等待转换完成。可以通过轮询DMA2D->CR寄存器的START位来判断转换是否完成。

    下面是一个示例代码, 假设屏幕颜色格式为RGB565, ChromaSampling为DMA2D_NO_CSS:

    void DMA2D_Copy_YCbCr_To_RGB_v(uint32_t pSrc, uint32_t *pDst, uint16_t x, uint16_t y, uint16_t xsize, uint16_t ysize, uint32_t PixelFormat, uint32_t ChromaSampling) {
        uint32_t cssMode = DMA2D_NO_CSS;
        uint32_t inputLineOffset = 0;
        uint32_t destination = 0;
    
        inputLineOffset = xsize % 8;
        if(inputLineOffset != 0) {
            inputLineOffset = 8 - inputLineOffset;
        }
    
        // 输出地址,乘以2的对RGB565,如果输出格式是ARGB8888,需要乘以4 
        destination = (uint32_t)pDst + ((y * g_LcdWidth) + x) * 2;
    
        DMA2D->CR      = 0x00010000UL | (1 << 9);
        DMA2D->OOR     = g_LcdWidth - xsize;
    
        DMA2D->OPFCCR  = PixelFormat | (DMA2D_REGULAR_ALPHA << 20) | (DMA2D_RB_REGULAR << 21);
    
        DMA2D->FGPFCCR = DMA2D_INPUT_YCBCR | (DMA2D_REPLACE_ALPHA << 16) | (DMA2D_REGULAR_ALPHA << 20) | (DMA2D_RB_REGULAR << 21) | (0xFFU << 24) | (cssMode << 18);
    
        DMA2D->FGOR    = inputLineOffset;
        DMA2D->NLR     = (uint32_t)(xsize << 16) | (uint16_t)ysize;      
        DMA2D->OMAR    = (uint32_t)destination;
        DMA2D->FGMAR   = (uint32_t)pSrc;  
    
        DMA2D->CR   |= DMA2D_CR_START;   
    
        while (DMA2D->CR & DMA2D_CR_START) {}
    }
    

    这样就完成了DMA2D在没有RGB接口屏幕上的操作。你可以根据实际情况调整参数和代码。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^