正点原子 发表于 2023-5-8 09:44:59

《ATK-DFPGL22G之FPGA开发指南_V1.0》第二十八章OV5640摄像头HDMI显示

本帖最后由 正点原子 于 2023-5-8 09:44 编辑

1)实验平台:正点原子 DFZU2EG_4EV MPSoC开发板
2)购买链接:https://item.taobao.com/item.htm?&id=692368045899
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-340252-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子FPGA交流群:994244016





第二十八章OV5640摄像头HDMI显示
在“OV5640摄像头LCD显示”实验中,我们采用以VDMA为中心的架构设计,实现了OV5640摄像头在LCD屏上的显示。本次实验进一步延伸,我们将OV5640摄像头采集的视频显示在带有HDMI接口的显示器上。
本章包括以下几个部分:
28.1简介
28.2实验任务
28.3硬件设计
28.4软件设计
28.5下载验证


28.1简介
有关HDMI的详细介绍,请参见“HDMI彩条显示”实验。
28.2实验任务
本节实验任务是使用MPSOC开发板及双目OV5640摄像头(实际只用到了其中一路)实现图像采集,并通过带有HDMI接口的显示器实时显示。
28.3硬件设计
开发板扩展接口原理图及OV5640模块说明与“OV5640摄像头LCD显示实验”完全相同,请参考“OV5640摄像头LCD显示实验”硬件设计部分。HDMI接口部分的硬件设计请参考“HDMI彩条显示”实验中的硬件设计部分。
本次实验的系统架构与“OV5640摄像头LCD显示”实验基本相似,只是把读通道最后端的显示接口部分换成了HDMI显示,当然也不需要传送LCD ID的AXI_GPIO IP核了。系统架构如下图所示:
图28.3.1 系统架构框图
我们将“HDMI彩条显示”实验中的HDMI驱动部分封装成IP核,以便直接在Block Design设计中进行调用。有关在Vivado中自定义IP核的操作步骤,请参见“自定义IP核”实验。在Block Design设计中封装后的HDMI驱动IP核如下图所示:
图28.3.2 HDMI驱动IP核
本次实验通过HDMI显示器显示图像数据,采用的分辨率是720P(1280*720),时钟IP核的配置同样是取消勾选动态重配置功能,如下图所示:
图28.3.3 取消动态重配置选项
输出时钟频率的配置,如下图所示:
图28.3.4 时钟IP核输出的时钟配置
由上图可知,时钟IP核共配置输出三路时钟,分别为75Mhz、187.5Mhz和375Mhz,但“Actual”一栏实际输出的时钟和预期偏差较大,此时我们可以通过手动调整该IP核的倍频/分频系数,来得到和预期偏差较小的时钟,修改方法如下图所示:
图28.3.5 MMCM Settings选项页
先对输入时钟进行75倍频,5分频;随后clk_out1、clk_out2和clk_out3在此基础上进行20分频、8分频和4倍频;再次切换至“Output Clocks”选项页,可以看到修改后的时钟和预期时钟偏差非常小,如下图所示:
图28.3.6 Output Clocks输出时钟
HDMI驱动IP核的Video_In输入接口连接到AXI_Stream to Video Out的输出接口,其需要三个输入时钟:“pclk”、“pixel_clk_2_5x”和“pixel_clk_5x”,均由时钟IP核生成。其复位信号由时钟IP核的锁定指示locked信号来驱动。连线如下图所示:
图28.3.7 HDMI驱动IP核的时钟和复位信号
连线后的Block Design如下图所示:
图28.3.8 整体Block Design框图
接下来验证当前设计。验证完成后弹出对话框提示没有错误或者关键警告,点击“OK”。如果验证结果报出错误或者警告,则需要重新检查设计。
为工程添加约束文件,约束文件如下:
#----------------------摄像头接口的时钟---------------------------
create_clock -period 20 -name cam_pclk
set_property CLOCK_DEDICATED_ROUTE FALSE

set_property -dict {PACKAGE_PIN C13 IOSTANDARD LVCMOS33}
set_property -dict {PACKAGE_PIN F13 IOSTANDARD LVCMOS33}
set_property -dict {PACKAGE_PIN B15 IOSTANDARD LVCMOS33}
set_property -dict {PACKAGE_PIN E15 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN D15 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN E14 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN D14 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN E13 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN B13 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN C14 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN A13 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN G14 IOSTANDARD LVCMOS33}
set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33}
set_property -dict {PACKAGE_PIN H13 IOSTANDARD LVCMOS33} }]
set_property -dict {PACKAGE_PIN F15 IOSTANDARD LVCMOS33} }]
set_property PULLUP true }]
set_property PULLUP true }]

#HDMI
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVDS} }]
set_property -dict {PACKAGE_PIN F2 IOSTANDARD LVDS} }]
set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVDS} }]
set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVDS}
最后在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“ Generate Bitstream”,对设计进行综合、实现、并生成Bitstream文件。在生成Bitstream之后,在菜单栏中选择 File > Export > Export hardware导出硬件,并在弹出的对话框中,勾选“Include bitstream”。然后在菜单栏选择Tools > Launch Vitis,启动Vitis软件。
28.4软件设计
打开Vitis后,我们创建一个Application Project,向工程中的添加的源文件与“OV5640摄像头LCD显示”实验基本相同,请读者参考“OV5640摄像头LCD显示”实验的“软件设计”部分。
不同之处在于main.c源文件,由于显示设备是带有HDMI接口的显示器,所以不需要进行ID的读取,也不需要根据ID号来设置视频参数,我们直接将视频参数设置为固定即可。
main函数的代码如下所示:
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include "xil_types.h"
5#include "xil_cache.h"
6#include "xparameters.h"
7#include "xaxivdma.h"
8#include "xaxivdma_i.h"
9#include "display_ctrl_hdmi/display_ctrl_hdmi.h"
10 #include "vdma_api/vdma_api.h"
11 #include "emio_sccb_cfg/emio_sccb_cfg.h"
12 #include "ov5640/ov5640_init.h"
13
14 //宏定义
15 #define VDMA_ID            XPAR_AXIVDMA_0_DEVICE_ID   //VDMA器件ID
16 #define DISP_VTC_ID      XPAR_VTC_0_DEVICE_ID       //VTC器件ID
17
18 //全局变量
19 XAxiVdma   vdma;
20 DisplayCtrldispCtrl;
21 VideoMode    vd_mode;
22 //frame buffer的起始地址
23 unsigned int const frame_buffer_addr = (XPAR_PSU_DDR_0_S_AXI_BASEADDR + 0x1000000);
24
25 int main(void)
26 {
27u32 status;
28u16 cmos_h_pixel;                  //ov5640 DVP 输出水平像素点数
29u16 cmos_v_pixel;                  //ov5640 DVP 输出垂直像素点数
30u16 total_h_pixel;                   //ov5640 水平总像素大小
31u16 total_v_pixel;                   //ov5640 垂直总像素大小
32
33cmos_h_pixel = 1280;               //设置OV5640输出分辨率为1280*720
34cmos_v_pixel = 720;
35total_h_pixel = 2570;
36total_v_pixel = 980;
37
38emio_init();                         //初始化EMIO
39status = ov5640_init( cmos_h_pixel,//初始化ov5640
40                        cmos_v_pixel,
41                     total_h_pixel,
42                     total_v_pixel);
43if(status == 0)
44      xil_printf("OV5640 detected successful!\r\n");
45else
46      xil_printf("OV5640 detected failed!\r\n");
47
48vd_mode = VMODE_1280x720;
49
50//配置VDMA
51run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,
52                        frame_buffer_addr,0,0,BOTH);
53
54   //初始化Display controller
55DisplayInitialize(&dispCtrl, DISP_VTC_ID);
56   //设置VideoMode
57DisplaySetMode(&dispCtrl, &vd_mode);
58DisplayStart(&dispCtrl);
59
60   return 0;
61 }
代码中的第33-36行设置OV5640的输出图像的分辨率大小为固定的1280*720,然后38-46行就是初始化EMIO和ov5640。由于我们使用HDMI显示器来显示视频画面,不需要做出像“OV5640摄像头LCD显示”实验中的根据ID来配置显示模式这样的动作,所以第48行将vd_mode结构体变量直接赋值固定值VMODE_1280x720。代码的剩下部分依次初始化VDMA和VTC IP核。
28.5下载验证
首先我们将下载器与开发板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用USB连接线将USB UART接口(PS_PORT)与电脑连接,用于串口通信。接下来将HDMI连接线将HDMI显示器连接到开发板上的HDMI接口。
接下来将双目OV5640摄像头模块插在MPSOC开发板的J19扩展口(实际只用到了一路摄像头),注意在连接时,摄像头镜头方向朝外,最后连接开发板的电源。
打开Vitis Terminal终端,设置并连接串口。然后下载本次实验的程序,下载完成后,在下方的Terminal中可以看到应用程序打印的信息,如下图所示:
图28.5.1 串口打印的信息
同时,显示器上显示出OV5640摄像头采集的图像,说明本次OV5640摄像头HDMI显示的实验在MPSOC开发板上验证成功,如下图所示:
图28.5.2 实验结果
页: [1]
查看完整版本: 《ATK-DFPGL22G之FPGA开发指南_V1.0》第二十八章OV5640摄像头HDMI显示