打印
[应用相关]

驱动 8 位 8080 接口 LCD 时的字节序问题

[复制链接]
621|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LEDyyds|  楼主 | 2022-1-25 09:44 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
前言
在一些图形界面应用中,系统架构会时常考虑使用 FSMC 接口来驱动 8080 接口的 LCD 屏。 在 MCU 渲染完成,将
framebuffer 发送到 LCD 时,有可能会遇到存儲大小端的问题。 STM32 MCU 都采用 ARM Cortex 内核,内存使用小端
格式。而 intel 8080 接口的 LCD 在传输 RGB 数据时,使用的是大端格式。 MCU 在传输 RGB 数据时,字节序有可能
不匹配。
在图形界面应用中,像素格式一般会使用 RGB888 或 RGB565。而在使用 FSMC 接口驱动 8bit 位宽的 LCD 时,很可
能会使用 RGB565 格式。本文中会介绍两种方法来处理 8bit 8080 接口 RGB565 格式图像数据字节序问题。  

使用特权

评论回复
沙发
LEDyyds|  楼主 | 2022-1-25 09:45 | 只看该作者
图像数据字节序
8bit 8080 LCD 在接收 RGB565 数据时,会将第一个字节解析为{R4-R0,G5-G3}, 第二个字节解析为{G2-G0,B4-B0},
并按这个顺序接收所有数据,如下图:  


而在 MCU 内存中,数据按小端格式存放, RGB565 数据存放的字节序如下:

如果不做调整直接将 RGB 数据发给 LCD, MCU 会先发送 Byte 0,再发送 Byte 1,这样 LCD 显示的内容就会错乱。
对比上面两张图可以看出,只需将内存中 Byte 0 与 Byte 1 字节位置对调(Byte swap),就能满足 LCD 接口的字节序要
求。可以直接使用 CPU 进行 Byte swap,但这会消耗过多 CPU 算力,同时也会占用更多内存。这里我们将使用硬件
进行 Byte swap.


使用特权

评论回复
板凳
LEDyyds|  楼主 | 2022-1-25 09:45 | 只看该作者
DMA2D 进行 Byte swap
DMA2D 是 ST 为图形应用专门设计并优化的 2D 加速引擎,拥有丰富的功能。其字节序重排功能包含了 Red blue
swap 以及 Byte swap 特性。 Red blue swap 特性在 L4 和 L4+系列 MCU 都支持, 而 Byte swap 仅在 L4+系列有支
持。 在 L4+系列上,通过配置 DMA2D_OPFCCR 寄存器的 SB 位,即可使能 Byte swap 功能,在 DMA2D 的 output
FIFO 中完成字节序调整,如下图:  


因此在图形界面应用中, 需要 Byte swap 时,可以考虑用 DMA2D 来传输 RGB 数据给 LCD。


使用特权

评论回复
地板
LEDyyds|  楼主 | 2022-1-25 09:48 | 只看该作者
GPDMA 进行 Byte swap
在新推出的 U5 系列芯片上, 集成了 GPDMA 模块。这是新的通用 DMA 模块,能在传输数据的同时,还有丰富的数据
处理能力。在初始化 GPDMA 时,通过配置源和目的数据位宽为 DMA_SRC_DATAWIDTH_WORD,在数据处理中配
置 DataExchange 为 DMA_EXCHANGE_DEST_BYTE,如下面代码,也能实现 Byte swap 功能。
DMA_HandleTypeDef hgpdma_channel0;
DMA_DataHandlingConfTypeDef DataHandlingConfig;
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_GPDMA1_CLK_ENABLE();
hgpdma_channel0.Instance = GPDMA1_Channel0;
hgpdma_channel0.Init.Request = DMA_REQUEST_SW;
hgpdma_channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
hgpdma_channel0.Init.Direction = DMA_MEMORY_TO_MEMORY;
hgpdma_channel0.Init.SrcInc = DMA_SINC_INCREMENTED;
hgpdma_channel0.Init.DestInc = DMA_DINC_FIXED;
hgpdma_channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
hgpdma_channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
hgpdma_channel0.Init.SrcBurstLength = 1;
hgpdma_channel0.Init.DestBurstLength = 1;
hgpdma_channel0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
hgpdma_channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
hgpdma_channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1;
hgpdma_channel0.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&hgpdma_channel0) != HAL_OK)
{
Error_Handler( );
}
/* Set data handling block configuration */
//swap bytes in Half-word
DataHandlingConfig.DataExchange = DMA_EXCHANGE_DEST_BYTE;
DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
/* Data handling configuration */
if (HAL_DMAEx_ConfigDataHandling(&hgpdma_channel0, &DataHandlingConfig) != HAL_OK)
{
Error_Handler( );
}
/* DMA interrupt init */
HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);
HAL_DMA_RegisterCallback(&hgpdma_channel0, HAL_DMA_XFER_CPLT_CB_ID, DMA_Xfer_Cmplt);
}
这样,在图形应用中,既能使用 DMA2D 加速渲染过程,也能使用 GPDMA 的数据处理能力。 通过 GPDMA 直接向
FSMC 接口输出 Byte swap 后的 RGB565 格式的图形数据给 LCD。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

119

主题

841

帖子

1

粉丝