OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 113|回复: 0

STM32H743-DMA2D转换YUV422成RGB888数据花屏

[复制链接]

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2015-6-23
在线时间
17 小时
发表于 2025-4-2 11:24:38 | 显示全部楼层 |阅读模式
利用STM32H743-DMA2D将YUV422数据流转换成RGB888数据花屏:
原始热成像数据:192x256分辨率,颜色格式YUV422,以UYVY排列
YUV422数据已经通过SPI_DMA方式获取到,软件解码显示正常;软件解码如下:
void YUV422_RGB888(const u8* uyvy, u8* rgb, int frameSize)
{
        int cnt = 0;
        for (int i = 0; i<frameSize; i += 2)
                          {
                 // 获取UYVY数据
                 u8 U = uyvy[i * 2];       // U分量
                 u8 Y0 = uyvy[i * 2 + 1]; // Y分量0
                 u8 V = uyvy[i * 2 + 2];   // V分量
                 u8 Y1 = uyvy[i * 2 + 3]; // Y分量1

                 // 转换Y0
                 int C0 = Y0 - 16;
                 int D = U - 128;
                 int E = V - 128;

                 int R0 = (298 * C0 + 409 * E + 128) >> 8;
                 int G0 = (298 * C0 - 100 * D - 208 * E + 128) >> 8;
                 int B0 = (298 * C0 + 516 * D + 128) >> 8;

                 // 转换Y1
                 int C1 = Y1 - 16;

                 int R1 = (298 * C1 + 409 * E + 128) >> 8;
                 int G1 = (298 * C1 - 100 * D - 208 * E + 128) >> 8;
                 int B1 = (298 * C1 + 516 * D + 128) >> 8;

                 // 限制RGB值在0-255之间
                 rgb[cnt] =(u8) (R0< 0 ? 0 : (R0 > 255 ? 255 : R0));
                 cnt++;
                 rgb[cnt] = (u8)(G0< 0 ? 0 : (G0 > 255 ? 255 : G0));
                 cnt++;
                 rgb[cnt] = (u8)(B0< 0 ? 0 : (B0 > 255 ? 255 : B0));
                 cnt++;

                 rgb[cnt] = (u8)(R1< 0 ? 0 : (R1 > 255 ? 255 : R1));
                 cnt++;
                 rgb[cnt] = (u8)(G1< 0 ? 0 : (G1 > 255 ? 255 : G1));
                 cnt++;
                 rgb[cnt] = (u8)(B1< 0 ? 0 : (B1 > 255 ? 255 : B1));
                 cnt++;
        }
}
软件解码显示图像如图片一
为了加快解算速度配置DMA2D解算数据,参考原子哥JPEG硬件解码DMA2D配置代码如下:
u8 JPEG_DMA2D_YUV2RGB_Conversion(u8 *YUV422,u8 *RGB888)
{
        u32 regval=0;
        u32 timeout=0;
        RCC->AHB3ENR|=1<<4;                                //使能DMA2D时钟
        RCC->AHB3RSTR|=1<<4;                        //复位DMA2D
        RCC->AHB3RSTR&=~(1<<4);                        //结束复位
        DMA2D->CR&=~(1<<0);                                //先停止DMA2D
        DMA2D->CR=1<<16;                                //MODE[1:0]=01,存储器到存储???,带PFC模式
        DMA2D->OPFCCR=1<<0;                                //CM[2:0]=001,输出为RGB888格式

        DMA2D->IFCR|=1<<1;                                //清除传输完成标志

        regval=11<<0;                                        //CM[3:0]=1011,输入数据为YCbCr格式
        regval|=1<<18;                                        //CSS[1:0]=cm,Chroma Sub-Sampling:0,4:4:4;1,4:2:2;2,4:2:0
        DMA2D->FGPFCCR=regval;                        //设置FGPCCR寄存???
       
        DMA2D->NLR=192+(256<<16);        //设定行数寄存???

        DMA2D->OMAR=(u32)RGB888;                //输出存储器地址
        DMA2D->OOR=0;                                        //设置输出行偏移为0
        DMA2D->FGMAR=(u32)YUV422;        //输入数据源地址
        DMA2D->FGOR=0;                                        //前景层行偏移

        DMA2D->CR|=1<<0;                                //启动DMA2D
        while((DMA2D->ISR&(1<<1))==0)        //等待传输完成
        {
                timeout++;
                if(timeout>0X1FFFFF)break;        //超时??????
        }
    //YUV2RGB转码结束后,在复位一次DMA2D
    RCC->AHB3RSTR|=1<<4;    //复位DMA2D
    RCC->AHB3RSTR&=~(1<<4); //结束复位
        if(timeout>0X1FFFFF)return 1;
        return 0;
}

解算出来的数据是花,如图片二
是我哪里配置不对,还是原始YUV422数据排列的方式与DMA2D的数据为YCbCr格式不对应?



图片1软件解码

图片1软件解码

图片2DMA2D解码

图片2DMA2D解码
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-21 11:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表