ZYNQ + OV5640 + HDMI 视频系统调试记录:一次 RGB888 与 RGB565 引发的黑屏问题

文章目录

一、项目背景

在基于 ZYNQ SoC FPGA 的视频处理系统中,常见的系统结构为:

bash 复制代码
摄像头采集图像
FPGA进行数据处理
DDR作为帧缓存
HDMI/LCD进行显示

本文记录了在搭建 OV5640 + ZYNQ + HDMI 视频系统过程中遇到的一次典型调试问题:

由于修改视频数据位宽导致系统黑屏。

通过这次调试,也加深了对 RGB888 / RGB565 数据格式以及 AXI VDMA 帧缓存机制 的理解。

二、系统整体架构

本系统采用 OV5640 CMOS 摄像头 + ZYNQ FPGA + HDMI 显示 的结构。

系统整体数据流如下:

bash 复制代码
OV5640 Camera
      │
      │ DVP接口 (8bit)
      ▼
OV5640_Data (自定义IP)
RGB565 → RGB888
      │
      ▼
Video In to AXI4-Stream
      │
      ▼
rgb888to565
      │
      ▼
AXI VDMA
(Frame Buffer DDR)
      │
      ▼
rgb565to888
      │
      ▼
AXI4-Stream to Video Out
      │
      ▼
rgb888to565
      │
      ▼
LCD / HDMI

系统中主要模块包括:

三、OV5640 数据格式说明

OV5640 摄像头输出的数据格式为:

cpp 复制代码
RGB565

但是摄像头接口是 8bit数据口,因此: 两个时钟周期输出一个像素

四、RGB565 转 RGB888

在本系统中,摄像头数据会被转换为 RGB888。

代码实现如下:

bash 复制代码
assign DataPixel =
{
r_DataPixel[15:11],3'd0,
r_DataPixel[10:5],2'd0,
r_DataPixel[4:0],3'd0
};

即通过 低位补0 的方式扩展为 24bit RGB888。

这样即可满足 Video In to AXI4-Stream IP核 的输入要求。

五、为什么系统中还要进行 RGB888 → RGB565 → RGB888 转换?

很多初学者在看到系统结构时都会疑惑:

bash 复制代码
RGB888
   ↓
RGB565
   ↓
RGB888

为什么要这样设计?

实际上这是 非常常见的工程优化方案。

主要原因有三个。

六、原因一:降低 DDR 带宽压力

假设系统分辨率为:

bash 复制代码
800 × 600
bash 复制代码
RGB888:800 × 600 × 3 byte ≈ 1.37 MB
bash 复制代码
RGB565:800 × 600 × 2 byte ≈ 0.92 MB

带宽减少:约 33%

在视频系统中,DDR带宽非常宝贵,因此使用 RGB565 存储是常见方案。

七、原因二:AXI VDMA 更适合 16bit 数据宽度

AXI VDMA 在处理数据时,通常使用:

bash 复制代码
8bit
16bit
32bit
64bit

而 RGB888:24bit

并不是 2的幂次宽度。

这会导致:数据打包复杂,stride计算复杂,DMA效率下降

因此很多系统会选择:VDMA 使用 16bit ,即:RGB565

八、调试过程:尝试去掉格式转换模块

在系统优化过程中,我曾尝试删除两个模块:

希望实现:RGB888 → VDMA → RGB888

也就是:VDMA 直接搬运 24bit 数据

修改后的结构:

理论上这样可以减少数据转换模块。
(在我实验中一直觉得这样是可行的,所以没有验证,直接应用在我后续的项目中,最终成为导致黑屏的一大原因。在此特别提醒:理论和实践不一样,理论可行实践未必,一定要多验证)

九、问题出现:系统黑屏

在完成修改并重新生成 bitstream 后,系统出现了问题:HDMI 输出黑屏

但程序运行正常:

bash 复制代码
VDMA启动成功
HDMI初始化正常
无报错信息

这说明:系统逻辑运行,但视频数据没有正常输出

十、问题分析

通过逐步排查,发现问题主要出在:

bash 复制代码
VDMA 数据位宽

当 VDMA 使用:24bit时:

bash 复制代码
AXI Stream 数据打包复杂
VDMA内部传输不稳定
stride计算容易出错

最终导致:视频帧无法正确读取

从而出现:黑屏

十一、最终解决方案

恢复原有结构:

bash 复制代码
RGB888 → RGB565 → VDMA → RGB888

系统恢复正常显示。

小结

提示:这里可以添加总结

在视频系统设计中:

bash 复制代码
RGB888 → RGB565 → RGB888

并不是冗余设计,而是一种 典型的工程优化方案。

通过在 FrameBuffer 前后进行格式转换,可以:

bash 复制代码
降低 DDR 带宽压力
提高 VDMA 传输稳定性
简化视频系统设计

因此,在 FPGA 视频系统中 保留 rgb888to565 和 rgb565to888 是一种合理且常见的工程设计方案。

相关推荐
搁浅小泽3 小时前
大电流焊点补焊要求
单片机·嵌入式硬件·可靠性工程师
Linux猿3 小时前
基于单片机浴室窗帘控制系统 | 附源码
单片机·嵌入式硬件·毕业设计·源码·课程设计·项目·基于单片机于是窗帘控制系统
清风6666663 小时前
基于51单片机的的智能电动车充电桩系统设计
单片机·嵌入式硬件·毕业设计·51单片机·课程设计·期末大作业
Flamingˢ4 小时前
YNQ + OV5640 视频系统开发(二):OV5640_Data IP 核源码解析
arm开发·嵌入式硬件·网络协议·tcp/ip·fpga开发·vim·音视频
Flamingˢ4 小时前
ZYNQ + OV5640 视频系统开发(三):AXI VDMA 帧缓存原理
arm开发·嵌入式硬件·fpga开发·vim·音视频
xiangw@GZ4 小时前
功耗测量:基于INA226的功耗测量原理深度解析
嵌入式硬件
Strange_Head4 小时前
快速入门 MQTT:从 Broker、发布订阅到双机通信
嵌入式硬件
Hello World . .5 小时前
Linux:Linux命令行音视频播放器
linux·音视频
LCG元5 小时前
STM32实战:基于STM32F103的MQTT协议通信(EMQ X Broker)
stm32·单片机·嵌入式硬件