文章目录
-
- 一、项目背景
- 二、系统整体架构
- [三、OV5640 数据格式说明](#三、OV5640 数据格式说明)
- [四、RGB565 转 RGB888](#四、RGB565 转 RGB888)
- [五、为什么系统中还要进行 RGB888 → RGB565 → RGB888 转换?](#五、为什么系统中还要进行 RGB888 → RGB565 → RGB888 转换?)
- [六、原因一:降低 DDR 带宽压力](#六、原因一:降低 DDR 带宽压力)
- [七、原因二:AXI VDMA 更适合 16bit 数据宽度](#七、原因二:AXI VDMA 更适合 16bit 数据宽度)
- 八、调试过程:尝试去掉格式转换模块
- 九、问题出现:系统黑屏
- 十、问题分析
- 十一、最终解决方案
- 小结
一、项目背景
在基于 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 是一种合理且常见的工程设计方案。